From c539eb2210da4e9eb50e399611a8a597cd7cc39d Mon Sep 17 00:00:00 2001 From: Daniel Sy Date: Thu, 18 Sep 2025 13:51:09 +0200 Subject: [PATCH] =?UTF-8?q?feat(cli):=20=E2=9C=A8=20Implement=20Edge=20Con?= =?UTF-8?q?nect=20CLI=20tool?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Creates a new command-line interface for managing Edge Connect applications and instances with the following features: - Configuration management via YAML files and environment variables - Application lifecycle commands (create, show, list, delete) - Instance management with cloudlet support - Improved error handling and authentication flow - Comprehensive documentation with usage examples The CLI provides a user-friendly interface for managing Edge Connect resources while following best practices for command-line tool development using Cobra and Viper. --- .gitignore | 1 + README.md | 108 ++++++++++++++++++++++++++++++ client/client.go | 20 ++++-- cmd/app.go | 145 ++++++++++++++++++++++++++++++++++++++++ cmd/instance.go | 159 ++++++++++++++++++++++++++++++++++++++++++++ cmd/root.go | 72 ++++++++++++++++++++ config.yaml.example | 3 + go.mod | 24 +++++++ go.sum | 54 +++++++++++++++ main.go | 7 ++ 10 files changed, 589 insertions(+), 4 deletions(-) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 cmd/app.go create mode 100644 cmd/instance.go create mode 100644 cmd/root.go create mode 100644 config.yaml.example create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5a87e4e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +edge-connect \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1c9f5a9 --- /dev/null +++ b/README.md @@ -0,0 +1,108 @@ +# Edge Connect CLI + +A command-line interface for managing Edge Connect applications and their instances. + +## Installation + +```bash +go install +``` + +## Configuration + +The CLI can be configured using a configuration file or environment variables. The default configuration file location is `$HOME/.edge-connect.yaml`. + +You can also specify a different configuration file using the `--config` flag. + +### Configuration File Format + +Create a YAML file with the following structure: + +```yaml +base_url: "https://api.edge-connect.example.com" +username: "your-username" +password: "your-password" +``` + +### Environment Variables + +You can also use environment variables to configure the CLI: + +- `EDGE_CONNECT_BASE_URL`: Base URL for the Edge Connect API +- `EDGE_CONNECT_USERNAME`: Username for authentication +- `EDGE_CONNECT_PASSWORD`: Password for authentication + +## Usage + +### Managing Applications + +Create a new application: +```bash +edge-connect app create --org myorg --name myapp --version 1.0.0 --region us-west +``` + +Show application details: +```bash +edge-connect app show --org myorg --name myapp --version 1.0.0 --region us-west +``` + +List applications: +```bash +edge-connect app list --org myorg --region us-west +``` + +Delete an application: +```bash +edge-connect app delete --org myorg --name myapp --version 1.0.0 --region us-west +``` + +### Managing Application Instances + +Create a new application instance: +```bash +edge-connect instance create \ + --org myorg \ + --name myinstance \ + --cloudlet mycloudlet \ + --cloudlet-org cloudletorg \ + --region us-west \ + --app myapp \ + --version 1.0.0 \ + --flavor myflavor +``` + +Show instance details: +```bash +edge-connect instance show \ + --org myorg \ + --name myinstance \ + --cloudlet mycloudlet \ + --cloudlet-org cloudletorg \ + --region us-west +``` + +List instances: +```bash +edge-connect instance list \ + --org myorg \ + --cloudlet mycloudlet \ + --cloudlet-org cloudletorg \ + --region us-west +``` + +Delete an instance: +```bash +edge-connect instance delete \ + --org myorg \ + --name myinstance \ + --cloudlet mycloudlet \ + --cloudlet-org cloudletorg \ + --region us-west +``` + +## Global Flags + +- `--config`: Config file (default is $HOME/.edge-connect.yaml) +- `--base-url`: Base URL for the Edge Connect API +- `--username`: Username for authentication +- `--password`: Password for authentication \ No newline at end of file diff --git a/client/client.go b/client/client.go index 88eb965..e4a34df 100644 --- a/client/client.go +++ b/client/client.go @@ -5,9 +5,10 @@ import ( "context" "encoding/json" "fmt" - + "io" "log" "net/http" + "strings" ) var ErrResourceNotFound = fmt.Errorf("resource not found") @@ -32,7 +33,8 @@ func (e *EdgeConnect) RetrieveToken(ctx context.Context) (string, error) { return "", err } - request, err := http.NewRequestWithContext(ctx, "POST", e.BaseURL+"/api/v1/login", bytes.NewBuffer(json_data)) + baseURL := strings.TrimRight(e.BaseURL, "/") + request, err := http.NewRequestWithContext(ctx, "POST", baseURL+"/api/v1/login", bytes.NewBuffer(json_data)) if err != nil { return "", err } @@ -45,12 +47,22 @@ func (e *EdgeConnect) RetrieveToken(ctx context.Context) (string, error) { defer resp.Body.Close() + // Read the entire response body + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", fmt.Errorf("error reading response body: %v", err) + } + + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("login failed with status %d: %s", resp.StatusCode, string(body)) + } + var respData struct { Token string `json:"token"` } - err = json.NewDecoder(resp.Body).Decode(&respData) + err = json.Unmarshal(body, &respData) if err != nil { - return "", err + return "", fmt.Errorf("error parsing JSON (status %d): %v", resp.StatusCode, err) } return respData.Token, nil diff --git a/cmd/app.go b/cmd/app.go new file mode 100644 index 0000000..ab0b702 --- /dev/null +++ b/cmd/app.go @@ -0,0 +1,145 @@ +package cmd + +import ( + "context" + "fmt" + "net/http" + "os" + + "edp.buildth.ing/DevFW-CICD/edge-connect-client/client" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var ( + organization string + appName string + appVersion string + region string +) + +func newClient() *client.EdgeConnect { + return &client.EdgeConnect{ + BaseURL: viper.GetString("base_url"), + HttpClient: &http.Client{}, + Credentials: client.Credentials{ + Username: viper.GetString("username"), + Password: viper.GetString("password"), + }, + } +} + +var appCmd = &cobra.Command{ + Use: "app", + Short: "Manage Edge Connect applications", + Long: `Create, show, list, and delete Edge Connect applications.`, +} + +var createAppCmd = &cobra.Command{ + Use: "create", + Short: "Create a new Edge Connect application", + Run: func(cmd *cobra.Command, args []string) { + c := newClient() + input := client.NewAppInput{ + Region: region, + App: client.App{ + Key: client.AppKey{ + Organization: organization, + Name: appName, + Version: appVersion, + }, + }, + } + + err := c.CreateApp(context.Background(), input) + if err != nil { + fmt.Printf("Error creating app: %v\n", err) + os.Exit(1) + } + fmt.Println("Application created successfully") + }, +} + +var showAppCmd = &cobra.Command{ + Use: "show", + Short: "Show details of an Edge Connect application", + Run: func(cmd *cobra.Command, args []string) { + c := newClient() + appKey := client.AppKey{ + Organization: organization, + Name: appName, + Version: appVersion, + } + + app, err := c.ShowApp(context.Background(), appKey, region) + if err != nil { + fmt.Printf("Error showing app: %v\n", err) + os.Exit(1) + } + fmt.Printf("Application details:\n%+v\n", app) + }, +} + +var listAppsCmd = &cobra.Command{ + Use: "list", + Short: "List Edge Connect applications", + Run: func(cmd *cobra.Command, args []string) { + c := newClient() + appKey := client.AppKey{ + Organization: organization, + Name: appName, + Version: appVersion, + } + + apps, err := c.ShowApps(context.Background(), appKey, region) + if err != nil { + fmt.Printf("Error listing apps: %v\n", err) + os.Exit(1) + } + fmt.Println("Applications:") + for _, app := range apps { + fmt.Printf("%+v\n", app) + } + }, +} + +var deleteAppCmd = &cobra.Command{ + Use: "delete", + Short: "Delete an Edge Connect application", + Run: func(cmd *cobra.Command, args []string) { + c := newClient() + appKey := client.AppKey{ + Organization: organization, + Name: appName, + Version: appVersion, + } + + err := c.DeleteApp(context.Background(), appKey, region) + if err != nil { + fmt.Printf("Error deleting app: %v\n", err) + os.Exit(1) + } + fmt.Println("Application deleted successfully") + }, +} + +func init() { + rootCmd.AddCommand(appCmd) + appCmd.AddCommand(createAppCmd, showAppCmd, listAppsCmd, deleteAppCmd) + + // Add common flags to all app commands + appCmds := []*cobra.Command{createAppCmd, showAppCmd, listAppsCmd, deleteAppCmd} + for _, cmd := range appCmds { + cmd.Flags().StringVarP(&organization, "org", "o", "", "organization name (required)") + cmd.Flags().StringVarP(&appName, "name", "n", "", "application name") + cmd.Flags().StringVarP(&appVersion, "version", "v", "", "application version") + cmd.Flags().StringVarP(®ion, "region", "r", "", "region (required)") + cmd.MarkFlagRequired("org") + cmd.MarkFlagRequired("region") + } + + // Add required name flag for specific commands + for _, cmd := range []*cobra.Command{createAppCmd, showAppCmd, deleteAppCmd} { + cmd.MarkFlagRequired("name") + } +} diff --git a/cmd/instance.go b/cmd/instance.go new file mode 100644 index 0000000..dfdb80e --- /dev/null +++ b/cmd/instance.go @@ -0,0 +1,159 @@ +package cmd + +import ( + "context" + "fmt" + "os" + + "edp.buildth.ing/DevFW-CICD/edge-connect-client/client" + "github.com/spf13/cobra" +) + +var ( + cloudletName string + cloudletOrg string + instanceName string + flavorName string +) + +var appInstanceCmd = &cobra.Command{ + Use: "instance", + Short: "Manage Edge Connect application instances", + Long: `Create, show, list, and delete Edge Connect application instances.`, +} + +var createInstanceCmd = &cobra.Command{ + Use: "create", + Short: "Create a new Edge Connect application instance", + Run: func(cmd *cobra.Command, args []string) { + c := newClient() + input := client.NewAppInstanceInput{ + Region: region, + AppInst: client.AppInstance{ + Key: client.AppInstanceKey{ + Organization: organization, + Name: instanceName, + CloudletKey: client.CloudletKey{ + Organization: cloudletOrg, + Name: cloudletName, + }, + }, + AppKey: client.AppKey{ + Organization: organization, + Name: appName, + Version: appVersion, + }, + Flavor: client.Flavor{ + Name: flavorName, + }, + }, + } + + err := c.CreateAppInstance(context.Background(), input) + if err != nil { + fmt.Printf("Error creating app instance: %v\n", err) + os.Exit(1) + } + fmt.Println("Application instance created successfully") + }, +} + +var showInstanceCmd = &cobra.Command{ + Use: "show", + Short: "Show details of an Edge Connect application instance", + Run: func(cmd *cobra.Command, args []string) { + c := newClient() + instanceKey := client.AppInstanceKey{ + Organization: organization, + Name: instanceName, + CloudletKey: client.CloudletKey{ + Organization: cloudletOrg, + Name: cloudletName, + }, + } + + instance, err := c.ShowAppInstance(context.Background(), instanceKey, region) + if err != nil { + fmt.Printf("Error showing app instance: %v\n", err) + os.Exit(1) + } + fmt.Printf("Application instance details:\n%+v\n", instance) + }, +} + +var listInstancesCmd = &cobra.Command{ + Use: "list", + Short: "List Edge Connect application instances", + Run: func(cmd *cobra.Command, args []string) { + c := newClient() + instanceKey := client.AppInstanceKey{ + Organization: organization, + Name: instanceName, + CloudletKey: client.CloudletKey{ + Organization: cloudletOrg, + Name: cloudletName, + }, + } + + instances, err := c.ShowAppInstances(context.Background(), instanceKey, region) + if err != nil { + fmt.Printf("Error listing app instances: %v\n", err) + os.Exit(1) + } + fmt.Println("Application instances:") + for _, instance := range instances { + fmt.Printf("%+v\n", instance) + } + }, +} + +var deleteInstanceCmd = &cobra.Command{ + Use: "delete", + Short: "Delete an Edge Connect application instance", + Run: func(cmd *cobra.Command, args []string) { + c := newClient() + instanceKey := client.AppInstanceKey{ + Organization: organization, + Name: instanceName, + CloudletKey: client.CloudletKey{ + Organization: cloudletOrg, + Name: cloudletName, + }, + } + + err := c.DeleteAppInstance(context.Background(), instanceKey, region) + if err != nil { + fmt.Printf("Error deleting app instance: %v\n", err) + os.Exit(1) + } + fmt.Println("Application instance deleted successfully") + }, +} + +func init() { + rootCmd.AddCommand(appInstanceCmd) + appInstanceCmd.AddCommand(createInstanceCmd, showInstanceCmd, listInstancesCmd, deleteInstanceCmd) + + // Add flags to all instance commands + instanceCmds := []*cobra.Command{createInstanceCmd, showInstanceCmd, listInstancesCmd, deleteInstanceCmd} + for _, cmd := range instanceCmds { + cmd.Flags().StringVarP(&organization, "org", "o", "", "organization name (required)") + cmd.Flags().StringVarP(&instanceName, "name", "n", "", "instance name (required)") + cmd.Flags().StringVarP(&cloudletName, "cloudlet", "c", "", "cloudlet name (required)") + cmd.Flags().StringVarP(&cloudletOrg, "cloudlet-org", "", "", "cloudlet organization (required)") + cmd.Flags().StringVarP(®ion, "region", "r", "", "region (required)") + + cmd.MarkFlagRequired("org") + cmd.MarkFlagRequired("name") + cmd.MarkFlagRequired("cloudlet") + cmd.MarkFlagRequired("cloudlet-org") + cmd.MarkFlagRequired("region") + } + + // Add additional flags for create command + createInstanceCmd.Flags().StringVarP(&appName, "app", "a", "", "application name (required)") + createInstanceCmd.Flags().StringVarP(&appVersion, "version", "v", "", "application version") + createInstanceCmd.Flags().StringVarP(&flavorName, "flavor", "f", "", "flavor name (required)") + createInstanceCmd.MarkFlagRequired("app") + createInstanceCmd.MarkFlagRequired("flavor") +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..480d8f5 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,72 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var ( + cfgFile string + baseURL string + username string + password string +) + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "edge-connect", + Short: "A CLI tool for managing Edge Connect applications", + Long: `edge-connect is a command line interface for managing Edge Connect applications +and their instances. It provides functionality to create, show, list, and delete +applications and application instances.`, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func init() { + cobra.OnInitialize(initConfig) + + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.edge-connect.yaml)") + rootCmd.PersistentFlags().StringVar(&baseURL, "base-url", "", "base URL for the Edge Connect API") + rootCmd.PersistentFlags().StringVar(&username, "username", "", "username for authentication") + rootCmd.PersistentFlags().StringVar(&password, "password", "", "password for authentication") + + viper.BindPFlag("base_url", rootCmd.PersistentFlags().Lookup("base-url")) + viper.BindPFlag("username", rootCmd.PersistentFlags().Lookup("username")) + viper.BindPFlag("password", rootCmd.PersistentFlags().Lookup("password")) +} + +func initConfig() { + viper.AutomaticEnv() + viper.SetEnvPrefix("EDGE_CONNECT") + viper.BindEnv("base_url", "EDGE_CONNECT_BASE_URL") + viper.BindEnv("username", "EDGE_CONNECT_USERNAME") + viper.BindEnv("password", "EDGE_CONNECT_PASSWORD") + + if cfgFile != "" { + viper.SetConfigFile(cfgFile) + } else { + home, err := os.UserHomeDir() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + viper.AddConfigPath(home) + viper.SetConfigType("yaml") + viper.SetConfigName(".edge-connect") + } + + if err := viper.ReadInConfig(); err == nil { + fmt.Println("Using config file:", viper.ConfigFileUsed()) + } +} diff --git a/config.yaml.example b/config.yaml.example new file mode 100644 index 0000000..2c1bbad --- /dev/null +++ b/config.yaml.example @@ -0,0 +1,3 @@ +base_url: "https://api.edge-connect.example.com" +username: "your-username" +password: "your-password" \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a54303b --- /dev/null +++ b/go.mod @@ -0,0 +1,24 @@ +module edp.buildth.ing/DevFW-CICD/edge-connect-client + +go 1.25.1 + +require ( + github.com/spf13/cobra v1.10.1 + github.com/spf13/viper v1.21.0 +) + +require ( + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/sagikazarmark/locafero v0.11.0 // indirect + github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.28.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..450a91f --- /dev/null +++ b/go.sum @@ -0,0 +1,54 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= +github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= +github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..9bc902d --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main + +import "edp.buildth.ing/DevFW-CICD/edge-connect-client/cmd" + +func main() { + cmd.Execute() +}