From 3f30c44b83d02225b72a23ed401d7e421678195c Mon Sep 17 00:00:00 2001 From: srinandan Date: Sun, 25 May 2025 03:57:33 +0000 Subject: [PATCH 1/2] feat: adds support to update attributes --- internal/cmd/apihub/attributes/attributes.go | 1 + internal/cmd/apihub/attributes/update.go | 73 ++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 internal/cmd/apihub/attributes/update.go diff --git a/internal/cmd/apihub/attributes/attributes.go b/internal/cmd/apihub/attributes/attributes.go index 7aec798c1..a7e4980bc 100644 --- a/internal/cmd/apihub/attributes/attributes.go +++ b/internal/cmd/apihub/attributes/attributes.go @@ -37,6 +37,7 @@ func init() { AttributeCmd.AddCommand(GetCmd) AttributeCmd.AddCommand(DelCmd) AttributeCmd.AddCommand(ListCmd) + AttributeCmd.AddCommand(UpdateCmd) _ = AttributeCmd.MarkFlagRequired("org") _ = AttributeCmd.MarkFlagRequired("region") diff --git a/internal/cmd/apihub/attributes/update.go b/internal/cmd/apihub/attributes/update.go new file mode 100644 index 000000000..2c08b06b8 --- /dev/null +++ b/internal/cmd/apihub/attributes/update.go @@ -0,0 +1,73 @@ +// Copyright 2025 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 attributes + +import ( + "internal/apiclient" + "internal/client/hub" + "os" + + "github.com/spf13/cobra" +) + +// UpdateCmd to update a catalog items +var UpdateCmd = &cobra.Command{ + Use: "update", + Short: "Update an Attribute", + Long: "Update an Attribute", + Args: func(cmd *cobra.Command, args []string) (err error) { + apiclient.SetRegion(region) + return apiclient.SetApigeeOrg(org) + }, + RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.SilenceUsage = true + var aValues []byte + + if aValuesPath != "" { + if aValues, err = os.ReadFile(aValuesPath); err != nil { + return err + } + } + _, err = hub.UpdateAttribute(attributeID, updateMask, displayName, description, scope, dataType, aValues, cardinality) + return + }, +} + +var updateMask string + +func init() { + UpdateCmd.Flags().StringVarP(&attributeID, "id", "i", + "", "Attribute ID") + UpdateCmd.Flags().StringVarP(&updateMask, "mask", "m", + "", "Update Mask") + UpdateCmd.Flags().StringVarP(&displayName, "display-name", "d", + "", "Attribute Display Name") + UpdateCmd.Flags().StringVarP(&description, "description", "", + "", "Attribute Description") + UpdateCmd.Flags().StringVarP(&scope, "scope", "s", + "", "Attribute scope") + UpdateCmd.Flags().StringVarP(&dataType, "data-type", "", + "", "Attribute data type") + UpdateCmd.Flags().IntVarP(&cardinality, "cardinality", "c", + 1, "Attribute cardinality") + UpdateCmd.Flags().StringVarP(&aValuesPath, "allowed-values", "", + "", "Path to a file containing allowed values") + + _ = UpdateCmd.MarkFlagRequired("id") + _ = UpdateCmd.MarkFlagRequired("display-name") + _ = UpdateCmd.MarkFlagRequired("scope") + _ = UpdateCmd.MarkFlagRequired("data-type") + _ = UpdateCmd.MarkFlagRequired("mask") +} From b887f39691809e3db74dfd31ca794128aa75b702 Mon Sep 17 00:00:00 2001 From: srinandan Date: Sun, 25 May 2025 03:57:47 +0000 Subject: [PATCH 2/2] chore: gofumpt --- internal/client/hub/hub.go | 81 ++++++++++++++++++++++++++++++++ internal/client/spaces/spaces.go | 2 +- internal/cmd/apihub/apis/get.go | 6 ++- internal/cmd/spaces/seteditor.go | 1 - internal/cmd/spaces/setviewer.go | 63 ++++++++++++------------- internal/cmd/spaces/testiam.go | 1 - 6 files changed, 117 insertions(+), 37 deletions(-) diff --git a/internal/client/hub/hub.go b/internal/client/hub/hub.go index 504ac70a8..dfaf75b8c 100644 --- a/internal/client/hub/hub.go +++ b/internal/client/hub/hub.go @@ -1007,6 +1007,87 @@ func DeleteAttribute(attributeID string) (respBody []byte, err error) { return respBody, err } +func UpdateAttribute(attributeID string, updateMask string, displayName string, description string, scope string, + dataType string, aValues []byte, cardinality int, +) (respBody []byte, err error) { + type attributeScope string + const ( + API attributeScope = "API" + VERSION attributeScope = "VERSION" + SPEC attributeScope = "SPEC" + API_OPERATION attributeScope = "API_OPERATION" + DEPLOYMENT attributeScope = "DEPLOYMENT" + DEPENDENCY attributeScope = "DEPENDENCY" + DEFINITION attributeScope = "DEFINITION" + EXTERNAL_API attributeScope = "EXTERNAL_API" + PLUGIN attributeScope = "PLUGIN" + ) + + type attributeDataType string + const ( + ENUM attributeDataType = "ENUM" + JSON attributeDataType = "JSON" + STRING attributeDataType = "STRING" + ) + + type attribute struct { + DisplayName *string `json:"displayName,omitempty"` + Description *string `json:"description,omitempty"` + Scope *attributeScope `json:"scope,omitempty"` + DataType *attributeDataType `json:"dataType,omitempty"` + AllowedValues []allowedValue `json:"allowedValues,omitempty"` + Cardinality *int `json:"cardinality,omitempty"` + } + + u, _ := url.Parse(apiclient.GetApigeeRegistryURL()) + u.Path = path.Join(u.Path, "attributes", attributeID) + q := u.Query() + q.Set("updateMask", updateMask) + u.RawQuery = q.Encode() + + a := attribute{} + if displayName != "" { + a.DisplayName = new(string) + *a.DisplayName = displayName + } + if description != "" { + a.Description = new(string) + *a.Description = description + } + + if scope != "" { + a.Scope = new(attributeScope) + *a.Scope = attributeScope(scope) + } + + if dataType != "" { + a.DataType = new(attributeDataType) + *a.DataType = attributeDataType(dataType) + } + + if cardinality != 1 { + a.Cardinality = new(int) + *a.Cardinality = cardinality + } + + if aValues != nil { + var av []allowedValue + err = json.Unmarshal(aValues, &av) + if err != nil { + return nil, err + } + a.AllowedValues = av + } + + payload, err := json.Marshal(&a) + if err != nil { + return nil, err + } + + respBody, err = apiclient.HttpClient(u.String(), string(payload), "PATCH") + return respBody, err +} + func ListAttributes(filter string, pageSize int, pageToken string) (respBody []byte, err error) { return list("attributes", filter, pageSize, pageToken) } diff --git a/internal/client/spaces/spaces.go b/internal/client/spaces/spaces.go index a26f1319d..0662ab699 100644 --- a/internal/client/spaces/spaces.go +++ b/internal/client/spaces/spaces.go @@ -81,4 +81,4 @@ func List() (respBody []byte, err error) { return respBody, err } -//TODO: Import, Export +// TODO: Import, Export diff --git a/internal/cmd/apihub/apis/get.go b/internal/cmd/apihub/apis/get.go index 4500cc327..836c77d7f 100644 --- a/internal/cmd/apihub/apis/get.go +++ b/internal/cmd/apihub/apis/get.go @@ -37,8 +37,10 @@ var GetCmd = &cobra.Command{ }, } -var apiID string -var force bool +var ( + apiID string + force bool +) func init() { GetCmd.Flags().StringVarP(&apiID, "id", "i", diff --git a/internal/cmd/spaces/seteditor.go b/internal/cmd/spaces/seteditor.go index 1885024fd..af55310e3 100644 --- a/internal/cmd/spaces/seteditor.go +++ b/internal/cmd/spaces/seteditor.go @@ -55,4 +55,3 @@ func init() { _ = SetEditorCmd.MarkFlagRequired("space") _ = SetEditorCmd.MarkFlagRequired("name") } - diff --git a/internal/cmd/spaces/setviewer.go b/internal/cmd/spaces/setviewer.go index 2e1325994..50db1adaa 100644 --- a/internal/cmd/spaces/setviewer.go +++ b/internal/cmd/spaces/setviewer.go @@ -15,44 +15,43 @@ package spaces import ( - "internal/apiclient" - "internal/client/spaces" - "internal/clilog" + "internal/apiclient" + "internal/client/spaces" + "internal/clilog" - "github.com/spf13/cobra" + "github.com/spf13/cobra" ) // SetViewerCmd to set role on env var SetViewerCmd = &cobra.Command{ - Use: "setviewer", - Short: "Set Space Content Viewer role for a member on a Space", - Long: "Set Space Content Viewer role for a member on a Space", - Args: func(cmd *cobra.Command, args []string) (err error) { - apiclient.SetRegion(region) - return apiclient.SetApigeeOrg(org) - }, - RunE: func(cmd *cobra.Command, args []string) (err error) { - cmd.SilenceUsage = true - - err = spaces.SetIAM(space, memberName, "viewer", memberType) - if err != nil { - return err - } - clilog.Info.Printf("Member \"%s\" granted access to \"roles/apigee.spaceContentViewer\" role in space \"%s\"\n", memberName, space) - return nil - }, - Example: `Set Space Viewer role for user in a space: ` + GetExample(3), + Use: "setviewer", + Short: "Set Space Content Viewer role for a member on a Space", + Long: "Set Space Content Viewer role for a member on a Space", + Args: func(cmd *cobra.Command, args []string) (err error) { + apiclient.SetRegion(region) + return apiclient.SetApigeeOrg(org) + }, + RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.SilenceUsage = true + + err = spaces.SetIAM(space, memberName, "viewer", memberType) + if err != nil { + return err + } + clilog.Info.Printf("Member \"%s\" granted access to \"roles/apigee.spaceContentViewer\" role in space \"%s\"\n", memberName, space) + return nil + }, + Example: `Set Space Viewer role for user in a space: ` + GetExample(3), } func init() { - SetViewerCmd.Flags().StringVarP(&space, "space", "", - "", "Space name.") - SetViewerCmd.Flags().StringVarP(&memberName, "name", "n", - "", "Member Name, example Service Account Name") - SetViewerCmd.Flags().StringVarP(&memberType, "member-type", "m", - "serviceAccount", "memberType must be serviceAccount, user or group") - - _ = SetViewerCmd.MarkFlagRequired("space") - _ = SetViewerCmd.MarkFlagRequired("name") + SetViewerCmd.Flags().StringVarP(&space, "space", "", + "", "Space name.") + SetViewerCmd.Flags().StringVarP(&memberName, "name", "n", + "", "Member Name, example Service Account Name") + SetViewerCmd.Flags().StringVarP(&memberType, "member-type", "m", + "serviceAccount", "memberType must be serviceAccount, user or group") + + _ = SetViewerCmd.MarkFlagRequired("space") + _ = SetViewerCmd.MarkFlagRequired("name") } - diff --git a/internal/cmd/spaces/testiam.go b/internal/cmd/spaces/testiam.go index 9ce75d514..3eb10c19a 100644 --- a/internal/cmd/spaces/testiam.go +++ b/internal/cmd/spaces/testiam.go @@ -52,5 +52,4 @@ func init() { "proxies", "resource") _ = TestIamCmd.MarkFlagRequired("space") - }