Author: Paolo Lulli <paolo@lulli.net>
Add cli
client/.gitignore | 3 + client/.idea/.gitignore | 8 +++ client/.idea/client.iml | 10 ++++ client/.idea/misc.xml | 6 ++ client/.idea/modules.xml | 8 +++ client/.idea/vcs.xml | 6 ++ client/apiclient.go | 85 ++++++++++++++++++++++++++++++++++++++ client/config/cli-config.go | 33 ++++++++++++++ client/event-client-rest.go | 20 ++++++++ client/go.mod | 13 +++++ client/go.sum | 10 ++++ client/main.go | 52 +++++++++++++++++++++++ client/metric-client-rest.go | 29 ++++++++++++
diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5add2221c9996f92e9334fbeb298cecce7f69742 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,3 @@ +yats +.dqt +.idea diff --git a/client/.idea/.gitignore b/client/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4 --- /dev/null +++ b/client/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/client/.idea/client.iml b/client/.idea/client.iml new file mode 100644 index 0000000000000000000000000000000000000000..25ed3f6e7b6e344b6ca91ebcc5d005f35357f9cf --- /dev/null +++ b/client/.idea/client.iml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="Go" enabled="true" /> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$" /> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> \ No newline at end of file diff --git a/client/.idea/misc.xml b/client/.idea/misc.xml new file mode 100644 index 0000000000000000000000000000000000000000..6f29fee2f2b3b412625a792b92bcd1263e5b765a --- /dev/null +++ b/client/.idea/misc.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK"> + <output url="file://$PROJECT_DIR$/out" /> + </component> +</project> \ No newline at end of file diff --git a/client/.idea/modules.xml b/client/.idea/modules.xml new file mode 100644 index 0000000000000000000000000000000000000000..0742ebc3adff31ae2584d375adada6d0fdf83f93 --- /dev/null +++ b/client/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/client.iml" filepath="$PROJECT_DIR$/.idea/client.iml" /> + </modules> + </component> +</project> \ No newline at end of file diff --git a/client/.idea/vcs.xml b/client/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53 --- /dev/null +++ b/client/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="" vcs="Git" /> + </component> +</project> \ No newline at end of file diff --git a/client/apiclient.go b/client/apiclient.go new file mode 100644 index 0000000000000000000000000000000000000000..f43b1a16b9dbf31ad87139aa2370e08c932ce434 --- /dev/null +++ b/client/apiclient.go @@ -0,0 +1,85 @@ +/** + * Yats - yats + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Paolo Lulli <kevwe.com> + * @copyright Paolo Lulli 2024 + */ +package main + +import ( + "bytes" + "crypto/tls" + "fmt" + "io" + "net/http" + "os" +) + +func (c *YatsClient) httpClient(key string, cert string) (client *http.Client) { + x509cert, err := tls.LoadX509KeyPair(cert, key) + + if err != nil { + fmt.Printf("Error loading X509 certificate: %s and/or key: %s", cert, key) + panic(err.Error()) + } + certs := []tls.Certificate{x509cert} + if len(certs) == 0 { + client = &http.Client{} + return + } + insecureSkipVerify := false + if c.config.TlsVerifyServer == "false" { + insecureSkipVerify = true + } + + tr := &http.Transport{ + TLSClientConfig: &tls.Config{Certificates: certs, + InsecureSkipVerify: insecureSkipVerify}, + } + client = &http.Client{Transport: tr} + return +} + +func (c *YatsClient) ApiGet(endpoint string) string { + cert, certKey := c.config.TlsCertificate, c.config.TlsKeyFile + client := c.httpClient(certKey, cert) + + req, err := http.NewRequest("GET", endpoint, nil) + if err != nil { + fmt.Println("Unable to make GET request", err) + os.Exit(1) + } + req.Header.Add("Accept", "*/*") + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer resp.Body.Close() + data, _ := io.ReadAll(resp.Body) + return string(data) +} + +func (c *YatsClient) ApiPost(endpoint string, body string) string { + cert, certKey := c.config.TlsCertificate, c.config.TlsKeyFile + client := c.httpClient(certKey, cert) + + req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer([]byte(body))) + req.Header.Set("Content-Type", "application/json; charset=UTF-8") + if err != nil { + fmt.Println("Unable to make POST request", err) + os.Exit(1) + } + req.Header.Add("Accept", "*/*") + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer resp.Body.Close() + data, _ := io.ReadAll(resp.Body) + return string(data) +} diff --git a/client/config/cli-config.go b/client/config/cli-config.go new file mode 100644 index 0000000000000000000000000000000000000000..8b37c6d1b4a6e749581aae2949009243d434ec4a --- /dev/null +++ b/client/config/cli-config.go @@ -0,0 +1,33 @@ +/** + * Yats - yats + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Paolo Lulli <kevwe.com> + * @copyright Paolo Lulli 2024 + */ + +package config + +import ( + "github.com/tkanos/gonfig" +) + +type ClientConfiguration struct { + Endpoint string `json:"endpoint"` + /* + Service string `json:"service"` + Client string `json:"client"` + */ + TlsKeyFile string `json:"tlsKeyFile"` + TlsCertificate string `json:"tlsCertificate"` + TlsVerifyServer string `json:"tlsVerifyServer"` +} + +func GetClientConfig(fileName string) ClientConfiguration { + configuration := ClientConfiguration{} + gonfig.GetConf(fileName, &configuration) + + return configuration +} diff --git a/client/event-client-rest.go b/client/event-client-rest.go new file mode 100644 index 0000000000000000000000000000000000000000..b71556506e492caa76486763eb4c650617aed376 --- /dev/null +++ b/client/event-client-rest.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "strconv" +) + +func (c *YatsClient) EventList(from int64, to int64) string { + if from == 0 { + panic("From is empty") + } + var body string + if to == 0 { + body = "{ \"from\":" + strconv.FormatInt(from, 10) + " }" + } else { + body = "{ \"from\":" + strconv.FormatInt(from, 10) + ",\"to\":" + strconv.FormatInt(to, 10) + " }" + } + fmt.Printf("request: [%s]\n", body) + return c.ApiPost(c.config.Endpoint+"/event/search", body) +} diff --git a/client/go.mod b/client/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..5fe6ef50af519f98a1e07ecae31b532227fda6e4 --- /dev/null +++ b/client/go.mod @@ -0,0 +1,13 @@ +module yats + +go 1.22.0 + +require ( + github.com/spf13/pflag v1.0.5 + github.com/tkanos/gonfig v0.0.0-20210106201359-53e13348de2f +) + +require ( + github.com/ghodss/yaml v1.0.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/client/go.sum b/client/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..41bb7c41fe3f16b6c7a6de385e8d335ec991368e --- /dev/null +++ b/client/go.sum @@ -0,0 +1,10 @@ +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/tkanos/gonfig v0.0.0-20210106201359-53e13348de2f h1:xDFq4NVQD34ekH5UsedBSgfxsBuPU2aZf7v4t0tH2jY= +github.com/tkanos/gonfig v0.0.0-20210106201359-53e13348de2f/go.mod h1:DaZPBuToMc2eezA9R9nDAnmS2RMwL7yEa5YD36ESQdI= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/client/main.go b/client/main.go new file mode 100644 index 0000000000000000000000000000000000000000..d96905b7c9dacab2a015244c7c86ab71d8755614 --- /dev/null +++ b/client/main.go @@ -0,0 +1,52 @@ +/** + * Yats - yats + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Paolo Lulli <kevwe.com> + * @copyright Paolo Lulli 2024 + */ +package main + +import ( + "fmt" + "os" + "yats/config" + + flag "github.com/spf13/pflag" +) + +type YatsClient struct { + config config.ClientConfiguration +} + +func main() { + var configPath string + + if len(os.Args) == 1 { + fmt.Printf("For usage: %s --help\n", os.Args[0]) + os.Exit(1) + } + fmt.Println("Loading default config") + configPath = os.Getenv("HOME") + "/.yats-client.json" + + cfg := config.GetClientConfig(configPath) + var yatsClient = YatsClient{config: cfg} + + isMetricOption := flag.BoolP("isMetric", "m", false, "Select Metric") + fromOption := flag.Int64("from", 0, "From tstamp") + toOption := flag.Int64("to", 0, "To tstamp") + metricNameOption := flag.StringP("metricName", "n", "", "Metric name") + + flag.Parse() + + if *isMetricOption { + listResponse := yatsClient.MetricList(*metricNameOption, *fromOption, *toOption) + fmt.Printf("Metric list: %s", listResponse) + } else { + listEvents := yatsClient.EventList(*fromOption, *toOption) + fmt.Printf("Event list: %s", listEvents) + } + +} diff --git a/client/metric-client-rest.go b/client/metric-client-rest.go new file mode 100644 index 0000000000000000000000000000000000000000..d3a4c3e086f5e9cd768ffc3308dc14883a4be7d1 --- /dev/null +++ b/client/metric-client-rest.go @@ -0,0 +1,29 @@ +/** + * Yats - yats + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Paolo Lulli <kevwe.com> + * @copyright Paolo Lulli 2024 + */ +package main + +import ( + "fmt" + "strconv" +) + +func (c *YatsClient) MetricList(metricName string, from int64, to int64) string { + if metricName == "" { + panic("Metric Name is empty") + } + var body string + if to == 0 { + body = "{\"name\":\"" + metricName + "\", \"from\":" + strconv.FormatInt(from, 10) + " }" + } else { + body = "{\"name\":\"" + metricName + "\", \"from\":" + strconv.FormatInt(from, 10) + ",\"to\":" + strconv.FormatInt(to, 10) + " }" + } + fmt.Printf("request: [%s]\n", body) + return c.ApiPost(c.config.Endpoint+"/metric/search", body) +}