From 8d46816fbb4d749900f5421466d524650ba4b4b9 Mon Sep 17 00:00:00 2001 From: srinandan <13950006+srinandan@users.noreply.github.com> Date: Thu, 20 Jul 2023 10:46:51 -0700 Subject: [PATCH 1/3] feat: allow updates to app developers #226 --- cmd/developers/developers.go | 1 + cmd/developers/upddev.go | 56 ++++++++++++++++++++++++ internal/client/developers/developers.go | 46 +++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 cmd/developers/upddev.go diff --git a/cmd/developers/developers.go b/cmd/developers/developers.go index 8838ba3a1..f02f6a41e 100644 --- a/cmd/developers/developers.go +++ b/cmd/developers/developers.go @@ -38,6 +38,7 @@ func init() { Cmd.AddCommand(ListCmd) Cmd.AddCommand(GetCmd) Cmd.AddCommand(DelCmd) + Cmd.AddCommand(UpdateCmd) Cmd.AddCommand(CreateCmd) Cmd.AddCommand(ImpCmd) Cmd.AddCommand(ExpCmd) diff --git a/cmd/developers/upddev.go b/cmd/developers/upddev.go new file mode 100644 index 000000000..659987a8e --- /dev/null +++ b/cmd/developers/upddev.go @@ -0,0 +1,56 @@ +// Copyright 2020 Google LLC +// +// 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 developers + +import ( + "internal/apiclient" + + "internal/client/developers" + + "github.com/spf13/cobra" +) + +// UpdateCmd to update developer +var UpdateCmd = &cobra.Command{ + Use: "update", + Short: "Update an Apigee developer configuration", + Long: "Update an Apigee developer configuration", + Args: func(cmd *cobra.Command, args []string) (err error) { + return apiclient.SetApigeeOrg(org) + }, + RunE: func(cmd *cobra.Command, args []string) (err error) { + _, err = developers.Update(email, firstName, lastName, userName, status, attrs) + return + }, +} + +var status bool + +func init() { + UpdateCmd.Flags().StringVarP(&email, "email", "n", + "", "The developer's email") + UpdateCmd.Flags().StringVarP(&firstName, "first", "f", + "", "The first name of the developer") + UpdateCmd.Flags().StringVarP(&lastName, "last", "s", + "", "The last name of the developer") + UpdateCmd.Flags().StringVarP(&userName, "user", "u", + "", "The username of the developer") + UpdateCmd.Flags().BoolVarP(&status, "status", "", + true, "The status of the developer") + UpdateCmd.Flags().StringToStringVar(&attrs, "attrs", + nil, "Custom attributes") + + _ = UpdateCmd.MarkFlagRequired("email") +} diff --git a/internal/client/developers/developers.go b/internal/client/developers/developers.go index add2369b0..166d13cd9 100644 --- a/internal/client/developers/developers.go +++ b/internal/client/developers/developers.go @@ -39,6 +39,7 @@ type Appdeveloper struct { Attributes []Attribute `json:"attributes,omitempty"` Username string `json:"userName,omitempty"` DeveloperId string `json:"developerId,omitempty"` + Status *string `json:"status,omitempty"` } // Appdevelopers hold an array of developers @@ -94,6 +95,51 @@ func Get(email string) (respBody []byte, err error) { return respBody, err } +// Update +func Update(email string, firstName string, lastName string, username string, status bool, attrs map[string]string) (respBody []byte, err error) { + apiclient.ClientPrintHttpResponse.Set(false) + devRespBody, err := Get(email) + if err != nil { + return nil, err + } + apiclient.ClientPrintHttpResponse.Set(apiclient.GetCmdPrintHttpResponseSetting()) + + d := Appdeveloper{} + if err = json.Unmarshal(devRespBody, &d); err != nil { + return nil, err + } + + if firstName != "" { + d.FirstName = firstName + } + + if lastName != "" { + d.LastName = lastName + } + + if username != "" { + d.Username = username + } + + d.Status = new(string) + + if status { + *d.Status = "active" + } else { + *d.Status = "inactive" + } + + reqBody, err := json.Marshal(d) + if err != nil { + return nil, err + } + + u, _ := url.Parse(apiclient.BaseURL) + u.Path = path.Join(u.Path, apiclient.GetApigeeOrg(), "developers", url.QueryEscape(email)) + respBody, err = apiclient.HttpClient(u.String(), string(reqBody), "PUT") + return respBody, err +} + // GetDeveloperId func GetDeveloperId(email string) (developerId string, err error) { apiclient.ClientPrintHttpResponse.Set(false) From d43e349d34ba1b4e79657eb959c88fbcf0e44738 Mon Sep 17 00:00:00 2001 From: srinandan <13950006+srinandan@users.noreply.github.com> Date: Mon, 24 Jul 2023 10:08:49 -0700 Subject: [PATCH 2/3] feat: fix status update #226 --- cmd/developers/upddev.go | 34 +++++++++++++++++++++--- internal/client/developers/developers.go | 26 +++++++++++++----- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/cmd/developers/upddev.go b/cmd/developers/upddev.go index 659987a8e..8a80097d4 100644 --- a/cmd/developers/upddev.go +++ b/cmd/developers/upddev.go @@ -15,6 +15,7 @@ package developers import ( + "fmt" "internal/apiclient" "internal/client/developers" @@ -31,12 +32,37 @@ var UpdateCmd = &cobra.Command{ return apiclient.SetApigeeOrg(org) }, RunE: func(cmd *cobra.Command, args []string) (err error) { - _, err = developers.Update(email, firstName, lastName, userName, status, attrs) + _, err = developers.Update(email, firstName, lastName, userName, cmd.Flag("status").Value.String(), attrs) return }, } -var status bool +type developerStatus string + +var status developerStatus + +const ( + active developerStatus = "active" + inactive developerStatus = "inactive" +) + +func (s *developerStatus) String() string { + return string(*s) +} + +func (s *developerStatus) Set(r string) error { + switch r { + case "active", "inactive": + *s = developerStatus(r) + return nil + default: + return fmt.Errorf("must be %s or %s", active, inactive) + } +} + +func (s *developerStatus) Type() string { + return "developerStatus" +} func init() { UpdateCmd.Flags().StringVarP(&email, "email", "n", @@ -47,8 +73,8 @@ func init() { "", "The last name of the developer") UpdateCmd.Flags().StringVarP(&userName, "user", "u", "", "The username of the developer") - UpdateCmd.Flags().BoolVarP(&status, "status", "", - true, "The status of the developer") + UpdateCmd.Flags().Var(&status, "status", + fmt.Sprintf("must be %s or %s", active, inactive)) UpdateCmd.Flags().StringToStringVar(&attrs, "attrs", nil, "Custom attributes") diff --git a/internal/client/developers/developers.go b/internal/client/developers/developers.go index 166d13cd9..e952bdada 100644 --- a/internal/client/developers/developers.go +++ b/internal/client/developers/developers.go @@ -96,7 +96,7 @@ func Get(email string) (respBody []byte, err error) { } // Update -func Update(email string, firstName string, lastName string, username string, status bool, attrs map[string]string) (respBody []byte, err error) { +func Update(email string, firstName string, lastName string, username string, status string, attrs map[string]string) (respBody []byte, err error) { apiclient.ClientPrintHttpResponse.Set(false) devRespBody, err := Get(email) if err != nil { @@ -121,12 +121,13 @@ func Update(email string, firstName string, lastName string, username string, st d.Username = username } - d.Status = new(string) - - if status { - *d.Status = "active" - } else { - *d.Status = "inactive" + if status != "" { + apiclient.ClientPrintHttpResponse.Set(false) + err = setDeveloperStatus(email, status) + apiclient.ClientPrintHttpResponse.Set(apiclient.GetCmdPrintHttpResponseSetting()) + if err != nil { + return nil, err + } } reqBody, err := json.Marshal(d) @@ -140,6 +141,17 @@ func Update(email string, firstName string, lastName string, username string, st return respBody, err } +func setDeveloperStatus(email string, action string) (err error) { + u, _ := url.Parse(apiclient.BaseURL) + u.Path = path.Join(u.Path, apiclient.GetApigeeOrg(), "developers", url.QueryEscape(email)) + q := u.Query() + q.Set("action", action) + u.RawQuery = q.Encode() + + _, err = apiclient.HttpClient(u.String(), "", "POST", "application/octet-stream") + return err +} + // GetDeveloperId func GetDeveloperId(email string) (developerId string, err error) { apiclient.ClientPrintHttpResponse.Set(false) From c59346acd770bd624ed487ce14b1df8ccf1fadd0 Mon Sep 17 00:00:00 2001 From: srinandan <13950006+srinandan@users.noreply.github.com> Date: Mon, 24 Jul 2023 10:10:00 -0700 Subject: [PATCH 3/3] chore: fix linting issues #226 --- cmd/developers/upddev.go | 1 + internal/client/apis/apis.go | 4 +--- internal/client/developers/developers.go | 1 - internal/client/sharedflows/sharedflows.go | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cmd/developers/upddev.go b/cmd/developers/upddev.go index 8a80097d4..8e3cfefb6 100644 --- a/cmd/developers/upddev.go +++ b/cmd/developers/upddev.go @@ -16,6 +16,7 @@ package developers import ( "fmt" + "internal/apiclient" "internal/client/developers" diff --git a/internal/client/apis/apis.go b/internal/client/apis/apis.go index 2e3c7adce..9c83f3a00 100644 --- a/internal/client/apis/apis.go +++ b/internal/client/apis/apis.go @@ -65,8 +65,7 @@ type violation struct { Description string `json:"description,omitempty"` } -type routingchanges struct { -} +type routingchanges struct{} type routingconflicts struct { EnvironmentGroup string `json:"environmentGroup,omitempty"` @@ -112,7 +111,6 @@ func DeleteProxyRevision(name string, revision int) (respBody []byte, err error) // DeployProxy func DeployProxy(name string, revision int, overrides bool, sequencedRollout bool, safeDeploy bool, serviceAccountName string) (respBody []byte, err error) { - if safeDeploy { var safeResp []byte d := deploychangereport{} diff --git a/internal/client/developers/developers.go b/internal/client/developers/developers.go index e952bdada..d168ddf25 100644 --- a/internal/client/developers/developers.go +++ b/internal/client/developers/developers.go @@ -226,7 +226,6 @@ func Export() (respBody []byte, err error) { // Import func Import(conn int, filePath string) error { - entities, err := ReadDevelopersFile(filePath) if err != nil { clilog.Error.Println("Error reading file: ", err) diff --git a/internal/client/sharedflows/sharedflows.go b/internal/client/sharedflows/sharedflows.go index fe097f1a1..ce77b1528 100644 --- a/internal/client/sharedflows/sharedflows.go +++ b/internal/client/sharedflows/sharedflows.go @@ -345,7 +345,6 @@ func Export(conn int, folder string, allRevisions bool) (err error) { lastRevision := maxRevision(proxy.Revision) jobChan <- revision{name: proxy.Name, rev: lastRevision} } - } close(jobChan) fanOutWg.Wait()