From 2dec648e8924573aeffc3cd2f10359f45c9d19b3 Mon Sep 17 00:00:00 2001 From: Javier Canizalez Date: Sat, 11 Sep 2021 18:20:46 -0600 Subject: [PATCH] Including path and scheme (#19) --- client/client/client.go | 10 ++++----- client/client/environment.go | 8 +++---- client/client/job.go | 8 +++---- client/client/module.go | 8 +++---- client/client/organization.go | 8 +++---- client/client/secret.go | 8 +++---- client/client/variable.go | 8 +++---- client/client/workspace.go | 8 +++---- client/models/job.go | 6 +++++ cmd/environment_create.go | 10 +-------- cmd/job_create.go | 16 +++++--------- cmd/job_list.go | 9 +------- cmd/login.go | 37 +++++++++++++++---------------- cmd/module.go | 2 ++ cmd/organization.go | 16 -------------- cmd/root.go | 41 +++++++++++++++++++++++++++++------ go.mod | 1 + 17 files changed, 100 insertions(+), 104 deletions(-) diff --git a/client/client/client.go b/client/client/client.go index 1ebcda2..286fced 100644 --- a/client/client/client.go +++ b/client/client/client.go @@ -3,7 +3,6 @@ package client import ( "bytes" "encoding/json" - "fmt" "io" "net/http" "net/url" @@ -22,12 +21,13 @@ type Client struct { Job *JobClient Environment *EnvironmentClient HttpClient *http.Client + BasePath string } -const basePath = "/api/v1/" +var defaultPath string = "/api/v1/" func (c *Client) newRequest(method, path string, body interface{}) (*http.Request, error) { - rel := &url.URL{Path: path} + rel := &url.URL{Path: c.BasePath + path} u := c.BaseURL.ResolveReference(rel) var buf io.ReadWriter if body != nil { @@ -58,8 +58,6 @@ func (c *Client) do(req *http.Request, v interface{}) (*http.Response, error) { err = json.NewDecoder(resp.Body).Decode(v) } - fmt.Println(resp.StatusCode) - return resp, err } @@ -67,6 +65,7 @@ func NewClient(httpClient *http.Client, token string, baseUrl *url.URL) *Client if httpClient == nil { httpClient = http.DefaultClient } + c := &Client{HttpClient: httpClient} c.BaseURL = baseUrl c.Token = token @@ -77,5 +76,6 @@ func NewClient(httpClient *http.Client, token string, baseUrl *url.URL) *Client c.Environment = &EnvironmentClient{Client: c} c.Secret = &SecretClient{Client: c} c.Job = &JobClient{Client: c} + c.BasePath = baseUrl.Path + defaultPath return c } diff --git a/client/client/environment.go b/client/client/environment.go index c6f383e..e5a6026 100644 --- a/client/client/environment.go +++ b/client/client/environment.go @@ -11,7 +11,7 @@ type EnvironmentClient struct { } func (c *EnvironmentClient) List(organizationId string, workspaceId string, filter string) ([]*models.Environment, error) { - req, err := c.Client.newRequest(http.MethodGet, basePath+fmt.Sprintf("organization/%v/workspace/%v/environment", organizationId, workspaceId), nil) + req, err := c.Client.newRequest(http.MethodGet, fmt.Sprintf("organization/%v/workspace/%v/environment", organizationId, workspaceId), nil) if err != nil { return nil, err } @@ -25,7 +25,7 @@ func (c *EnvironmentClient) Create(organizationId string, workspaceId string, en Data: &environment, } - req, err := c.Client.newRequest(http.MethodPost, basePath+fmt.Sprintf("organization/%v/workspace/%v/environment", organizationId, workspaceId), reqBody) + req, err := c.Client.newRequest(http.MethodPost, fmt.Sprintf("organization/%v/workspace/%v/environment", organizationId, workspaceId), reqBody) if err != nil { return nil, err } @@ -35,7 +35,7 @@ func (c *EnvironmentClient) Create(organizationId string, workspaceId string, en } func (c *EnvironmentClient) Delete(organizationId string, workspaceId string, environmentId string) error { - req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf(basePath+"organization/%v/workspace/%v/environment/%v", organizationId, workspaceId, environmentId), nil) + req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf("organization/%v/workspace/%v/environment/%v", organizationId, workspaceId, environmentId), nil) if err != nil { return err } @@ -49,7 +49,7 @@ func (c *EnvironmentClient) Update(organizationId string, workspaceId string, en Data: &environment, } - req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf(basePath+"organization/%v/workspace/%v/environment/%v", organizationId, workspaceId, environment.ID), reqBody) + req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf("organization/%v/workspace/%v/environment/%v", organizationId, workspaceId, environment.ID), reqBody) if err != nil { return err } diff --git a/client/client/job.go b/client/client/job.go index c89e9f9..a2db1f2 100644 --- a/client/client/job.go +++ b/client/client/job.go @@ -11,7 +11,7 @@ type JobClient struct { } func (c *JobClient) List(organizationId string, filter string) ([]*models.Job, error) { - req, err := c.Client.newRequest(http.MethodGet, basePath+fmt.Sprintf("organization/%v/job", organizationId), nil) + req, err := c.Client.newRequest(http.MethodGet, fmt.Sprintf("organization/%v/job", organizationId), nil) if err != nil { return nil, err } @@ -25,7 +25,7 @@ func (c *JobClient) Create(organizationId string, job models.Job) (*models.Job, Data: &job, } - req, err := c.Client.newRequest(http.MethodPost, basePath+fmt.Sprintf("organization/%v/job", organizationId), reqBody) + req, err := c.Client.newRequest(http.MethodPost, fmt.Sprintf("organization/%v/job", organizationId), reqBody) if err != nil { return nil, err } @@ -35,7 +35,7 @@ func (c *JobClient) Create(organizationId string, job models.Job) (*models.Job, } func (c *JobClient) Delete(organizationID string, moduleId string) error { - req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf(basePath+"organization/%v/module/%v", organizationID, moduleId), nil) + req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf("organization/%v/module/%v", organizationID, moduleId), nil) if err != nil { return err } @@ -49,7 +49,7 @@ func (c *JobClient) Update(organizationId string, module models.Module) error { Data: &module, } - req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf(basePath+"organization/%v/module/%v", organizationId, module.ID), reqBody) + req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf("organization/%v/module/%v", organizationId, module.ID), reqBody) if err != nil { return err } diff --git a/client/client/module.go b/client/client/module.go index 3f95527..0ef7c48 100644 --- a/client/client/module.go +++ b/client/client/module.go @@ -11,7 +11,7 @@ type ModuleClient struct { } func (c *ModuleClient) List(organizationId string, filter string) ([]*models.Module, error) { - req, err := c.Client.newRequest(http.MethodGet, basePath+fmt.Sprintf("organization/%v/module", organizationId), nil) + req, err := c.Client.newRequest(http.MethodGet, fmt.Sprintf("organization/%v/module", organizationId), nil) if err != nil { return nil, err } @@ -25,7 +25,7 @@ func (c *ModuleClient) Create(organizationId string, module models.Module) (*mod Data: &module, } - req, err := c.Client.newRequest(http.MethodPost, basePath+fmt.Sprintf("organization/%v/module", organizationId), reqBody) + req, err := c.Client.newRequest(http.MethodPost, fmt.Sprintf("organization/%v/module", organizationId), reqBody) if err != nil { return nil, err } @@ -35,7 +35,7 @@ func (c *ModuleClient) Create(organizationId string, module models.Module) (*mod } func (c *ModuleClient) Delete(organizationID string, moduleId string) error { - req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf(basePath+"organization/%v/module/%v", organizationID, moduleId), nil) + req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf("organization/%v/module/%v", organizationID, moduleId), nil) if err != nil { return err } @@ -49,7 +49,7 @@ func (c *ModuleClient) Update(organizationId string, module models.Module) error Data: &module, } - req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf(basePath+"organization/%v/module/%v", organizationId, module.ID), reqBody) + req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf("organization/%v/module/%v", organizationId, module.ID), reqBody) if err != nil { return err } diff --git a/client/client/organization.go b/client/client/organization.go index 550a718..171c9ad 100644 --- a/client/client/organization.go +++ b/client/client/organization.go @@ -11,7 +11,7 @@ type OrganizationClient struct { } func (c *OrganizationClient) List(filter string) ([]*models.Organization, error) { - req, err := c.Client.newRequest(http.MethodGet, basePath+"organization", nil) + req, err := c.Client.newRequest(http.MethodGet, "organization", nil) if err != nil { return nil, err } @@ -25,7 +25,7 @@ func (c *OrganizationClient) Create(organization models.Organization) (*models.O Data: &organization, } - req, err := c.Client.newRequest(http.MethodPost, basePath+"organization", reqBody) + req, err := c.Client.newRequest(http.MethodPost, "organization", reqBody) if err != nil { return nil, err } @@ -35,7 +35,7 @@ func (c *OrganizationClient) Create(organization models.Organization) (*models.O } func (c *OrganizationClient) Delete(organizationID string) error { - req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf(basePath+"organization/%v", organizationID), nil) + req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf("organization/%v", organizationID), nil) if err != nil { return err } @@ -49,7 +49,7 @@ func (c *OrganizationClient) Update(organization models.Organization) error { Data: &organization, } - req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf(basePath+"organization/%v", organization.ID), reqBody) + req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf("organization/%v", organization.ID), reqBody) if err != nil { return err } diff --git a/client/client/secret.go b/client/client/secret.go index 5107d7c..cc6e05d 100644 --- a/client/client/secret.go +++ b/client/client/secret.go @@ -11,7 +11,7 @@ type SecretClient struct { } func (c *SecretClient) List(organizationId string, workspaceId string, filter string) ([]*models.Secret, error) { - req, err := c.Client.newRequest(http.MethodGet, basePath+fmt.Sprintf("organization/%v/workspace/%v/secret", organizationId, workspaceId), nil) + req, err := c.Client.newRequest(http.MethodGet, fmt.Sprintf("organization/%v/workspace/%v/secret", organizationId, workspaceId), nil) if err != nil { return nil, err } @@ -25,7 +25,7 @@ func (c *SecretClient) Create(organizationId string, workspaceId string, secret Data: &secret, } - req, err := c.Client.newRequest(http.MethodPost, basePath+fmt.Sprintf("organization/%v/workspace/%v/secret", organizationId, workspaceId), reqBody) + req, err := c.Client.newRequest(http.MethodPost, fmt.Sprintf("organization/%v/workspace/%v/secret", organizationId, workspaceId), reqBody) if err != nil { return nil, err } @@ -35,7 +35,7 @@ func (c *SecretClient) Create(organizationId string, workspaceId string, secret } func (c *SecretClient) Delete(organizationId string, workspaceId string, secretId string) error { - req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf(basePath+"organization/%v/workspace/%v/secret/%v", organizationId, workspaceId, secretId), nil) + req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf("organization/%v/workspace/%v/secret/%v", organizationId, workspaceId, secretId), nil) if err != nil { return err } @@ -49,7 +49,7 @@ func (c *SecretClient) Update(organizationId string, workspaceId string, secret Data: &secret, } - req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf(basePath+"organization/%v/workspace/%v/secret/%v", organizationId, workspaceId, secret.ID), reqBody) + req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf("organization/%v/workspace/%v/secret/%v", organizationId, workspaceId, secret.ID), reqBody) if err != nil { return err } diff --git a/client/client/variable.go b/client/client/variable.go index 773071c..6e359e4 100644 --- a/client/client/variable.go +++ b/client/client/variable.go @@ -11,7 +11,7 @@ type VariableClient struct { } func (c *VariableClient) List(organizationId string, workspaceId string, filter string) ([]*models.Variable, error) { - req, err := c.Client.newRequest(http.MethodGet, basePath+fmt.Sprintf("organization/%v/workspace/%v/variable", organizationId, workspaceId), nil) + req, err := c.Client.newRequest(http.MethodGet, fmt.Sprintf("organization/%v/workspace/%v/variable", organizationId, workspaceId), nil) if err != nil { return nil, err } @@ -25,7 +25,7 @@ func (c *VariableClient) Create(organizationId string, workspaceId string, varia Data: &variable, } - req, err := c.Client.newRequest(http.MethodPost, basePath+fmt.Sprintf("organization/%v/workspace/%v/variable", organizationId, workspaceId), reqBody) + req, err := c.Client.newRequest(http.MethodPost, fmt.Sprintf("organization/%v/workspace/%v/variable", organizationId, workspaceId), reqBody) if err != nil { return nil, err } @@ -35,7 +35,7 @@ func (c *VariableClient) Create(organizationId string, workspaceId string, varia } func (c *VariableClient) Delete(organizationId string, workspaceId string, variableId string) error { - req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf(basePath+"organization/%v/workspace/%v/variable/%v", organizationId, workspaceId, variableId), nil) + req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf("organization/%v/workspace/%v/variable/%v", organizationId, workspaceId, variableId), nil) if err != nil { return err } @@ -49,7 +49,7 @@ func (c *VariableClient) Update(organizationId string, workspaceId string, varia Data: &variable, } - req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf(basePath+"organization/%v/workspace/%v/variable/%v", organizationId, workspaceId, variable.ID), reqBody) + req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf("organization/%v/workspace/%v/variable/%v", organizationId, workspaceId, variable.ID), reqBody) if err != nil { return err } diff --git a/client/client/workspace.go b/client/client/workspace.go index 475b195..92844ca 100644 --- a/client/client/workspace.go +++ b/client/client/workspace.go @@ -11,7 +11,7 @@ type WorkspaceClient struct { } func (c *WorkspaceClient) List(organizationId string, filter string) ([]*models.Workspace, error) { - req, err := c.Client.newRequest(http.MethodGet, basePath+fmt.Sprintf("organization/%v/workspace", organizationId), nil) + req, err := c.Client.newRequest(http.MethodGet, fmt.Sprintf("organization/%v/workspace", organizationId), nil) if err != nil { return nil, err } @@ -25,7 +25,7 @@ func (c *WorkspaceClient) Create(organizationId string, workspace models.Workspa Data: &workspace, } - req, err := c.Client.newRequest(http.MethodPost, basePath+fmt.Sprintf("organization/%v/workspace", organizationId), reqBody) + req, err := c.Client.newRequest(http.MethodPost, fmt.Sprintf("organization/%v/workspace", organizationId), reqBody) if err != nil { return nil, err } @@ -35,7 +35,7 @@ func (c *WorkspaceClient) Create(organizationId string, workspace models.Workspa } func (c *WorkspaceClient) Delete(organizationID string, workspaceId string) error { - req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf(basePath+"organization/%v/workspace/%v", organizationID, workspaceId), nil) + req, err := c.Client.newRequest(http.MethodDelete, fmt.Sprintf("organization/%v/workspace/%v", organizationID, workspaceId), nil) if err != nil { return err } @@ -49,7 +49,7 @@ func (c *WorkspaceClient) Update(organizationId string, workspace models.Workspa Data: &workspace, } - req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf(basePath+"organization/%v/workspace/%v", organizationId, workspace.ID), reqBody) + req, err := c.Client.newRequest(http.MethodPatch, fmt.Sprintf("organization/%v/workspace/%v", organizationId, workspace.ID), reqBody) if err != nil { return err } diff --git a/client/models/job.go b/client/models/job.go index a9c4973..07aa448 100644 --- a/client/models/job.go +++ b/client/models/job.go @@ -62,6 +62,12 @@ type JobRelationshipsOrganization struct { type JobRelationshipsWorkspace struct { + // data + Data *JobRelationshipsWorkspaceData `json:"data"` +} + +type JobRelationshipsWorkspaceData struct { + // id ID string `json:"id,omitempty"` diff --git a/cmd/environment_create.go b/cmd/environment_create.go index 9aa318d..3aeaa5d 100644 --- a/cmd/environment_create.go +++ b/cmd/environment_create.go @@ -2,9 +2,7 @@ package cmd import ( "azb/client/models" - "encoding/json" "fmt" - "log" "github.com/spf13/cobra" ) @@ -56,11 +54,5 @@ func createEnvironment() { return } - prettyJSON, err := json.MarshalIndent(resp, "", " ") - if err != nil { - log.Fatal("Failed to generate json", err) - } - - fmt.Printf("%s\n", string(prettyJSON)) - + renderOutput(resp, output) } diff --git a/cmd/job_create.go b/cmd/job_create.go index 205985c..0790b2f 100644 --- a/cmd/job_create.go +++ b/cmd/job_create.go @@ -2,9 +2,7 @@ package cmd import ( "azb/client/models" - "encoding/json" "fmt" - "log" "github.com/spf13/cobra" ) @@ -45,8 +43,10 @@ func createJob() { Type: "job", Relationships: &models.JobRelationships{ Workspace: &models.JobRelationshipsWorkspace{ - Type: "workspace", - ID: JobCreateWorkspaceId, + Data: &models.JobRelationshipsWorkspaceData{ + Type: "workspace", + ID: JobCreateWorkspaceId, + }, }, }, } @@ -58,11 +58,5 @@ func createJob() { return } - prettyJSON, err := json.MarshalIndent(resp, "", " ") - if err != nil { - log.Fatal("Failed to generate json", err) - } - - fmt.Printf("%s\n", string(prettyJSON)) - + renderOutput(resp, output) } diff --git a/cmd/job_list.go b/cmd/job_list.go index 277d13f..354d75a 100644 --- a/cmd/job_list.go +++ b/cmd/job_list.go @@ -1,9 +1,7 @@ package cmd import ( - "encoding/json" "fmt" - "log" "github.com/spf13/cobra" ) @@ -40,10 +38,5 @@ func listJobs() { return } - prettyJSON, err := json.MarshalIndent(resp, "", " ") - if err != nil { - log.Fatal("Failed to generate json", err) - } - - fmt.Printf("%s\n", string(prettyJSON)) + renderOutput(resp, output) } diff --git a/cmd/login.go b/cmd/login.go index cf4594b..41eb28a 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -1,18 +1,3 @@ -/* -Copyright © 2021 NAME HERE - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ package cmd import ( @@ -20,6 +5,8 @@ import ( "fmt" "time" + "github.com/fatih/color" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/public" homedir "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" @@ -38,13 +25,15 @@ Login to a local azb server var Server string var ClientID string var TenantID string +var Path string +var Scheme string var loginCmd = &cobra.Command{ Use: "login", Short: "login to azb server", Long: loginLong, Run: func(cmd *cobra.Command, args []string) { - acquireAccessToken(ClientID, TenantID, Server) + acquireAccessToken(ClientID, TenantID, Server, Scheme, Path) }, Example: fmt.Sprintf(loginExamples, rootCmd.Use), } @@ -53,13 +42,20 @@ func init() { rootCmd.AddCommand(loginCmd) loginCmd.Flags().StringVarP(&Server, "server", "s", "", "AZB Server url (required)") _ = loginCmd.MarkFlagRequired("server") + _ = viper.BindEnv("server") loginCmd.Flags().StringVarP(&ClientID, "client-id", "c", "", "Azure application Client id (required)") _ = loginCmd.MarkFlagRequired("client-id") + _ = viper.BindEnv("client-id", "AZB_CLIENT_ID") loginCmd.Flags().StringVarP(&TenantID, "tenant-id", "t", "", "Azure tenant Id (required)") _ = loginCmd.MarkFlagRequired("tenant-id") + _ = viper.BindEnv("tenant-id", "AZB_TENANT_ID") + loginCmd.Flags().StringVarP(&Path, "path", "p", "", "AZB Server path") + _ = viper.BindEnv("path") + loginCmd.Flags().StringVarP(&Scheme, "scheme", "", "http", "AZB Server scheme: http or https") + _ = viper.BindEnv("scheme") } -func acquireAccessToken(clientID string, tenantID string, url string) { +func acquireAccessToken(clientID string, tenantID string, url string, scheme string, path string) { app, err := public.New(clientID, public.WithAuthority(fmt.Sprintf("https://login.microsoftonline.com/%v", tenantID))) if err != nil { @@ -72,7 +68,7 @@ func acquireAccessToken(clientID string, tenantID string, url string) { if err != nil { panic(err) } - fmt.Printf(devCode.Result.Message) + color.Yellow(devCode.Result.Message) result, err := devCode.AuthenticationResult(ctx) if err != nil { panic(fmt.Sprintf("got error while waiting for user to input the device code: %s", err)) @@ -82,8 +78,9 @@ func acquireAccessToken(clientID string, tenantID string, url string) { cobra.CheckErr(err) viper.SetConfigFile(home + "/" + "azb.yml") viper.SetConfigType("yaml") - viper.Set("Token", result.AccessToken) - viper.Set("Server", url) + viper.Set("token", result.AccessToken) + viper.Set("server", url) + viper.Set("scheme", url) if err := viper.WriteConfig(); err != nil { fmt.Println(err) diff --git a/cmd/module.go b/cmd/module.go index fb55fc4..2ce9081 100644 --- a/cmd/module.go +++ b/cmd/module.go @@ -17,6 +17,7 @@ package cmd import ( "github.com/spf13/cobra" + "github.com/spf13/viper" ) var moduleLong = ` @@ -32,4 +33,5 @@ var moduleCmd = &cobra.Command{ func init() { rootCmd.AddCommand(moduleCmd) + _ = viper.BindEnv("organization-id", "AZB_ORGANIZATION_ID") } diff --git a/cmd/organization.go b/cmd/organization.go index 395b84a..ede31e1 100644 --- a/cmd/organization.go +++ b/cmd/organization.go @@ -1,18 +1,3 @@ -/* -Copyright © 2021 NAME HERE - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ package cmd import ( @@ -33,5 +18,4 @@ var organizationCmd = &cobra.Command{ func init() { rootCmd.AddCommand(organizationCmd) - } diff --git a/cmd/root.go b/cmd/root.go index 2359ada..6ffcba3 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -12,6 +12,7 @@ import ( "github.com/fatih/color" "github.com/kataras/tablewriter" "github.com/spf13/cobra" + "github.com/spf13/pflag" homedir "github.com/mitchellh/go-homedir" "github.com/spf13/viper" @@ -23,6 +24,7 @@ import ( var cfgFile string var output string +var envPrefix string = "AZB" // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ @@ -44,8 +46,8 @@ func init() { rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.azb-cli.yaml)") rootCmd.PersistentFlags().StringVar(&output, "output", "json", "Use json, table, tsv or none to format CLI output") - - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + _ = viper.BindPFlag("output", rootCmd.Flags().Lookup("output")) + _ = rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") cobra.AddTemplateFunc("StyleHeading", color.New(color.FgCyan).SprintFunc()) usageTemplate := rootCmd.UsageTemplate() @@ -71,17 +73,21 @@ func initConfig() { home, err := homedir.Dir() cobra.CheckErr(err) - // Search config in home directory with name ".azb-cli" (without extension). viper.AddConfigPath(home) - viper.SetConfigName(".azb-cli") + viper.SetConfigName(".azbcli") } + viper.SetEnvPrefix(envPrefix) + _ = viper.BindEnv("workspace-id", "AZB_WORKSPACE_ID") viper.AutomaticEnv() // read in environment variables that match // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) } + + postInitCommands(rootCmd.Commands()) + } func newClient() apiclient.Client { @@ -94,11 +100,14 @@ func newClient() apiclient.Client { if err != nil { panic(fmt.Errorf("Fatal error config file: %w \n", err)) } - url := viper.Get("Server").(string) - token := viper.Get("Token").(string) + url := viper.Get("server").(string) + scheme := viper.Get("scheme").(string) + path := viper.Get("path").(string) + token := viper.Get("token").(string) baseUrl := &neturl.URL{ - Scheme: "http", + Scheme: scheme, Host: url, + Path: path, } client := apiclient.NewClient(&http.Client{}, token, baseUrl) return *client @@ -172,3 +181,21 @@ func splitInterface(input interface{}) ([][]string, []string) { } return result, headers } + +func postInitCommands(commands []*cobra.Command) { + for _, cmd := range commands { + presetRequiredFlags(cmd) + if cmd.HasSubCommands() { + postInitCommands(cmd.Commands()) + } + } +} + +func presetRequiredFlags(cmd *cobra.Command) { + _ = viper.BindPFlags(cmd.Flags()) + cmd.Flags().VisitAll(func(f *pflag.Flag) { + if viper.IsSet(f.Name) && viper.GetString(f.Name) != "" { + _ = cmd.Flags().Set(f.Name, viper.GetString(f.Name)) + } + }) +} diff --git a/go.mod b/go.mod index 5f38527..ddb8f39 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/spf13/cobra v1.1.3 + github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.8.0 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect golang.org/x/text v0.3.6 // indirect