From d17a731439bbad1622c204f72c142ad80fdf7246 Mon Sep 17 00:00:00 2001 From: srinandan <13950006+srinandan@users.noreply.github.com> Date: Sat, 23 Jul 2022 15:04:04 -0700 Subject: [PATCH] remove envoy bindings #37 --- cmd/envoy/addbinding.go | 62 -------- cmd/envoy/addjwk.go | 50 ------ cmd/envoy/createbinding.go | 70 --------- cmd/envoy/envoy.go | 43 ------ cmd/envoy/generatejwk.go | 47 ------ cmd/envoy/generatejwt.go | 51 ------ cmd/envoy/jwkutils.go | 309 ------------------------------------- cmd/envoy/listbindings.go | 45 ------ cmd/envoy/removebinding.go | 87 ----------- 9 files changed, 764 deletions(-) delete mode 100644 cmd/envoy/addbinding.go delete mode 100644 cmd/envoy/addjwk.go delete mode 100644 cmd/envoy/createbinding.go delete mode 100644 cmd/envoy/envoy.go delete mode 100644 cmd/envoy/generatejwk.go delete mode 100644 cmd/envoy/generatejwt.go delete mode 100644 cmd/envoy/jwkutils.go delete mode 100644 cmd/envoy/listbindings.go delete mode 100644 cmd/envoy/removebinding.go diff --git a/cmd/envoy/addbinding.go b/cmd/envoy/addbinding.go deleted file mode 100644 index 65d0872e0..000000000 --- a/cmd/envoy/addbinding.go +++ /dev/null @@ -1,62 +0,0 @@ -// 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 envoy - -import ( - "strings" - - "github.com/apigee/apigeecli/apiclient" - "github.com/apigee/apigeecli/client/products" - "github.com/spf13/cobra" -) - -//AddBindCmd -var AddBindCmd = &cobra.Command{ - Use: "add", - Short: "Add a new Envoy binding; Binds an Envoy service to an existing API Product", - Long: "Add a new Envoy binding; Binds an Envoy service to an existing API Product", - Args: func(cmd *cobra.Command, args []string) (err error) { - return apiclient.SetApigeeOrg(org) - }, - RunE: func(cmd *cobra.Command, args []string) (err error) { - - apiclient.SetPrintOutput(false) - _, err = products.GetAttribute(productName, envoyAttributeName) - apiclient.SetPrintOutput(true) - if err != nil { - attr := make(map[string]string) - attr[string(envoyAttributeName)] = strings.Join(serviceNames, ",") - _, err = products.UpdateLegacy(productName, "", "", "", "", "", "", nil, nil, nil, attr) - return err - } else { - _, err = products.UpdateAttribute(productName, envoyAttributeName, strings.Join(serviceNames, ",")) - return err - } - - return err - }, -} - -func init() { - AddBindCmd.Flags().StringVarP(&org, "org", "o", - "", "Apigee organization name") - AddBindCmd.Flags().StringVarP(&productName, "prod", "p", - "", "Apigee API Product name") - AddBindCmd.Flags().StringArrayVarP(&serviceNames, "remote-svcs", "r", - []string{}, "Envoy Service names") - - _ = AddBindCmd.MarkFlagRequired("prod") - _ = AddBindCmd.MarkFlagRequired("remote-svcs") -} diff --git a/cmd/envoy/addjwk.go b/cmd/envoy/addjwk.go deleted file mode 100644 index 52dd49205..000000000 --- a/cmd/envoy/addjwk.go +++ /dev/null @@ -1,50 +0,0 @@ -// 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 envoy - -import ( - "fmt" - "time" - - "github.com/spf13/cobra" -) - -//AddCmd to get org details -var AddCmd = &cobra.Command{ - Use: "add-jwk", - Short: "Add a new JSON Web Key for Apigee Envoy Connector", - Long: "Add a new JSON Web Key for Apigee Envoy Connector", - Args: func(cmd *cobra.Command, args []string) (err error) { - return nil - }, - RunE: func(cmd *cobra.Command, args []string) (err error) { - if err = AddKey(kid, folder); err != nil { - return err - } - fmt.Println("Add the generated files to the Kubernetes secret:") - fmt.Println("kubectl create secret generic {org}-{env}-policy-secret -n apigee --from-file=remote-service.key --from-file=remote-service.crt --from-file=remote-service.properties") - return Generatekid(kid, folder) - }, -} - -func init() { - - AddCmd.Flags().StringVarP(&folder, "folder", "f", - "", "folder containing remote-service.* files") - AddCmd.Flags().StringVarP(&kid, "kid", "k", - time.Now().Format("2006-01-02T15:04:05"), "Key Identifier") - - _ = AddCmd.MarkFlagRequired("folder") -} diff --git a/cmd/envoy/createbinding.go b/cmd/envoy/createbinding.go deleted file mode 100644 index a32db010a..000000000 --- a/cmd/envoy/createbinding.go +++ /dev/null @@ -1,70 +0,0 @@ -// 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 envoy - -import ( - "strings" - - "github.com/apigee/apigeecli/apiclient" - "github.com/apigee/apigeecli/client/products" - "github.com/spf13/cobra" -) - -//CreateCmd -var CreateCmd = &cobra.Command{ - Use: "create", - Short: "Create a new Envoy binding; Binds an Envoy service to an API Product", - Long: "Create a new Envoy binding; Binds an Envoy service to an API Product", - Args: func(cmd *cobra.Command, args []string) (err error) { - return apiclient.SetApigeeOrg(org) - }, - RunE: func(cmd *cobra.Command, args []string) (err error) { - if attrs == nil { - attrs = make(map[string]string) - } - attrs[envoyAttributeName] = strings.Join(serviceNames, ",") - _, err = products.CreateLegacy(name, description, approval, displayName, quota, quotaInterval, quotaUnit, environments, nil, scopes, attrs) - return - }, -} - -func init() { - CreateCmd.Flags().StringVarP(&name, "name", "n", - "", "Name of the API Product") - CreateCmd.Flags().StringVarP(&displayName, "displayname", "m", - "", "Display Name of the API Product") - CreateCmd.Flags().StringVarP(&description, "desc", "d", - "", "Description for the API Product") - CreateCmd.Flags().StringArrayVarP(&environments, "envs", "e", - []string{}, "Environments to enable") - CreateCmd.Flags().StringArrayVarP(&serviceNames, "remote-svcs", "r", - []string{}, "Envoy Service names. Ex: -s service1:port1 -s service2:port2") - CreateCmd.Flags().StringArrayVarP(&scopes, "scopes", "s", - []string{}, "OAuth scopes") - CreateCmd.Flags().StringVarP("a, "quota", "q", - "", "Quota Amount") - CreateCmd.Flags().StringVarP("aInterval, "interval", "i", - "", "Quota Interval") - CreateCmd.Flags().StringVarP("aUnit, "unit", "u", - "", "Quota Unit") - CreateCmd.Flags().StringVarP(&approval, "approval", "f", - "", "Approval type") - CreateCmd.Flags().StringToStringVar(&attrs, "attrs", - nil, "Custom attributes") - - _ = CreateCmd.MarkFlagRequired("prod") - _ = CreateCmd.MarkFlagRequired("remote-svcs") - _ = CreateCmd.MarkFlagRequired("approval") -} diff --git a/cmd/envoy/envoy.go b/cmd/envoy/envoy.go deleted file mode 100644 index 35015ca27..000000000 --- a/cmd/envoy/envoy.go +++ /dev/null @@ -1,43 +0,0 @@ -// 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 envoy - -import ( - "github.com/spf13/cobra" -) - -//Cmd to manage orgs -var Cmd = &cobra.Command{ - Use: "envoy-bindings", - Short: "Manage Envoy API Product Bindings Apigee", - Long: "Manage Envoy API Product Bindings Apigee", -} - -var name, description, approval, displayName, quota, quotaInterval, quotaUnit, org, kid, productName, folder string -var environments, scopes, serviceNames []string -var attrs map[string]string -var legacy bool - -const envoyAttributeName = "apigee-remote-service-targets" - -func init() { - Cmd.AddCommand(CreateCmd) - Cmd.AddCommand(ListCmd) - Cmd.AddCommand(RemoveCmd) - Cmd.AddCommand(GenCmd) - Cmd.AddCommand(GenJwtCmd) - Cmd.AddCommand(AddCmd) - Cmd.AddCommand(AddBindCmd) -} diff --git a/cmd/envoy/generatejwk.go b/cmd/envoy/generatejwk.go deleted file mode 100644 index 3219ff037..000000000 --- a/cmd/envoy/generatejwk.go +++ /dev/null @@ -1,47 +0,0 @@ -// 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 envoy - -import ( - "fmt" - "time" - - "github.com/spf13/cobra" -) - -//GenCmd to get org details -var GenCmd = &cobra.Command{ - Use: "gen-jwk", - Short: "Generate JSON Web Keys for Apigee Envoy Connector", - Long: "Generate JSON Web Keys for Apigee Envoy Connector", - Args: func(cmd *cobra.Command, args []string) (err error) { - return nil - }, - RunE: func(cmd *cobra.Command, args []string) (err error) { - if err = Generatekeys(kid, folder); err != nil { - return err - } - fmt.Println("Add the generated files to the Kubernetes secret:") - fmt.Println("kubectl create secret generic {org}-{env}-policy-secret -n apigee --from-file=remote-service.key --from-file=remote-service.crt --from-file=remote-service.properties") - return Generatekid(kid, folder) - }, -} - -func init() { - GenCmd.Flags().StringVarP(&folder, "folder", "f", - "", "folder containing remote-service.* files") - GenCmd.Flags().StringVarP(&kid, "kid", "k", - time.Now().Format("2006-01-02T15:04:05"), "Key Identifier") -} diff --git a/cmd/envoy/generatejwt.go b/cmd/envoy/generatejwt.go deleted file mode 100644 index d8ac61039..000000000 --- a/cmd/envoy/generatejwt.go +++ /dev/null @@ -1,51 +0,0 @@ -// 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 envoy - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -//GenJwtCmd to get org details -var GenJwtCmd = &cobra.Command{ - Use: "gen-jwt", - Short: "Generate JSON Web Tokens for Apigee Envoy Connector", - Long: "Generate JSON Web Token for Apigee Envoy Connector", - Args: func(cmd *cobra.Command, args []string) (err error) { - return nil - }, - RunE: func(cmd *cobra.Command, args []string) (err error) { - var token string - if token, err = GenerateToken(folder, expiry); err != nil { - return err - } - fmt.Printf("%s", token) - return nil - }, -} - -var expiry int - -func init() { - - GenJwtCmd.Flags().StringVarP(&folder, "folder", "f", - "", "path to folder containing remote-service.* files") - GenJwtCmd.Flags().IntVarP(&expiry, "exp", "x", - 10, "expiry in minutes; default 10 mins") - - _ = GenJwtCmd.MarkFlagRequired("folder") -} diff --git a/cmd/envoy/jwkutils.go b/cmd/envoy/jwkutils.go deleted file mode 100644 index b0c86c860..000000000 --- a/cmd/envoy/jwkutils.go +++ /dev/null @@ -1,309 +0,0 @@ -// 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 envoy - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "encoding/json" - "encoding/pem" - "fmt" - "io/ioutil" - "log" - "os" - "path" - "strings" - "time" - - "github.com/lestrrat-go/jwx/v2/jwa" - "github.com/lestrrat-go/jwx/v2/jwk" - "github.com/lestrrat-go/jwx/v2/jws" - "github.com/lestrrat-go/jwx/v2/jwt" - - "github.com/apigee/apigeecli/clilog" -) - -const keyFile = "remote-service.key" -const certFile = "remote-service.crt" -const kidFile = "remote-service.properties" -const use = "sig" -const kidFormat = "kid=" - -func readFile(name string) (data []byte, err error) { - data, err = ioutil.ReadFile(name) - return -} - -func writeToFile(name string, data string) error { - - f, err := os.Create(name) - if err != nil { - log.Printf("failed to open file: %s\n", err) - return err - } - - _, err = f.WriteString(data) - if err != nil { - log.Printf("failed to open file: %s\n", err) - return err - } - - f.Close() - - return nil -} - -func getPrivateKey(privateKey string) (interface{}, error) { - pemPrivateKey := fmt.Sprintf("%v", privateKey) - block, _ := pem.Decode([]byte(pemPrivateKey)) - privKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) - if err != nil { - clilog.Error.Println("error parsing Private Key: ", err) - return nil, err - } - return privKey, nil -} - -func GenerateToken(folder string, expiry int) (string, error) { - - var jwtKidFile, jwtKeyFile, privateKey, kid string - var err error - - if jwtKidFile, jwtKeyFile, _, err = checkFiles(folder); err != nil { - return "", err - } - - const aud = "remote-service-client" - const iss = "apigee-remote-service-envoy" - const tokenType = "JWT" - - if privateKey, err = getFileContents(jwtKeyFile); err != nil { - return "", err - } - - if kid, err = getFileContents(jwtKidFile); err != nil { - return "", err - } - - privKey, err := getPrivateKey(privateKey) - - if err != nil { - return "", err - } - - now := time.Now() - hdr := jws.NewHeaders() - if err = hdr.Set(jws.AlgorithmKey, jwa.RS256); err != nil { - return "", err - } - if err = hdr.Set(jws.TypeKey, tokenType); err != nil { - return "", err - } - - if err = hdr.Set(jws.KeyIDKey, getKid(kid)); err != nil { - return "", err - } - - token := jwt.New() - - if err = token.Set(jwt.AudienceKey, aud); err != nil { - return "", err - } - if err = token.Set(jwt.IssuerKey, iss); err != nil { - return "", err - } - if err = token.Set(jwt.IssuedAtKey, now.Unix()); err != nil { - return "", err - } - if err = token.Set(jwt.ExpirationKey, now.Unix()+(int64(expiry*60))); err != nil { - return "", err - } - - buf, err := json.Marshal(token) - if err != nil { - return "", err - } - - payload, err := jws.Sign(buf, jws.WithKey(jwa.RS256, privKey), jws.WithHeaders(hdr)) - if err != nil { - clilog.Error.Println("error parsing Private Key: ", err) - return "", err - } - clilog.Info.Println("jwt token : ", string(payload)) - return string(payload), nil -} - -func Generatekeys(kid string, folder string) (err error) { - - var jwtCertFile, jwtKeyFile string - - if folder != "" { - jwtKeyFile = path.Join(folder, keyFile) - jwtCertFile = path.Join(folder, certFile) - } else { - jwtKeyFile = keyFile - jwtCertFile = certFile - } - - privkey, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - return err - } - - pemdata := pem.EncodeToMemory( - &pem.Block{ - Type: "RSA PRIVATE KEY", - Bytes: x509.MarshalPKCS1PrivateKey(privkey), - }, - ) - - if err = writeToFile(jwtKeyFile, string(pemdata)); err != nil { - return err - } - - key, err := jwk.FromRaw(&privkey.PublicKey) - if err != nil { - return err - } - if err = key.Set(jwk.KeyUsageKey, use); err != nil { - return err - } - if err = key.Set(jwk.KeyIDKey, kid); err != nil { - return err - } - - if fileExists(jwtCertFile) { - //append cert - return nil - } else { //create new cert file - jsonbuf, err := json.MarshalIndent(key, "", " ") - if err != nil { - return err - } - - set, err := jwk.Parse(jsonbuf) - if err != nil { - return err - } - jsonbuf, err = json.MarshalIndent(set, "", " ") - if err != nil { - return err - } - - return writeToFile(jwtCertFile, string(jsonbuf)) - } -} - -func Generatekid(kid string, folder string) (err error) { - var jwtKidFile string - if folder != "" { - jwtKidFile = path.Join(folder, kidFile) - } else { - jwtKidFile = kidFile - } - data := kidFormat + kid - return writeToFile(jwtKidFile, data) -} - -func AddKey(kid string, folder string) (err error) { - - var jwtCertFile string - if jwtCertFile = path.Join(folder, certFile); !fileExists(jwtCertFile) { - return fmt.Errorf("remote-service.crt not found in %s", folder) - } - - data, err := readFile(jwtCertFile) - if err != nil { - return err - } - - set, err := jwk.Parse(data) - if err != nil { - return err - } - - privkey, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - return err - } - - pemdata := pem.EncodeToMemory( - &pem.Block{ - Type: "RSA PRIVATE KEY", - Bytes: x509.MarshalPKCS1PrivateKey(privkey), - }, - ) - - if err = writeToFile(keyFile, string(pemdata)); err != nil { - return err - } - - newKey, err := jwk.FromRaw(&privkey.PublicKey) - if err != nil { - return err - } - if err = newKey.Set(jwk.KeyUsageKey, use); err != nil { - return err - } - if err = newKey.Set(jwk.KeyIDKey, kid); err != nil { - return err - } - - set.AddKey(newKey) - - jsonbuf, err := json.MarshalIndent(set, "", " ") - if err != nil { - return err - } - - return writeToFile(certFile, string(jsonbuf)) -} - -func fileExists(file string) bool { - if _, err := os.Stat(file); os.IsNotExist(err) { - return false - } - return true -} - -func getFileContents(filename string) (content string, err error) { - var contentBytes []byte - if contentBytes, err = ioutil.ReadFile(filename); err != nil { - return "", err - } - return strings.TrimSuffix(string(contentBytes), "\n"), nil -} - -func getKid(kid string) string { - return strings.ReplaceAll(kid, kidFormat, "") -} - -func checkFiles(folder string) (jwtKidFile string, jwtKeyFile string, jwtCertFile string, err error) { - - if jwtKidFile = path.Join(folder, kidFile); !fileExists(jwtKidFile) { - return "", "", "", fmt.Errorf("remote-service.properties not found in %s", folder) - } - - if jwtKeyFile = path.Join(folder, keyFile); !fileExists(jwtKeyFile) { - return "", "", "", fmt.Errorf("remote-service.key not found in %s", folder) - } - - if jwtCertFile = path.Join(folder, certFile); !fileExists(jwtCertFile) { - return "", "", "", fmt.Errorf("remote-service.crt not found in %s", folder) - } - - return jwtKidFile, jwtKeyFile, jwtCertFile, nil -} diff --git a/cmd/envoy/listbindings.go b/cmd/envoy/listbindings.go deleted file mode 100644 index 9b29668c9..000000000 --- a/cmd/envoy/listbindings.go +++ /dev/null @@ -1,45 +0,0 @@ -// 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 envoy - -import ( - "github.com/apigee/apigeecli/apiclient" - "github.com/apigee/apigeecli/client/products" - "github.com/spf13/cobra" -) - -//ListCmd bindings -var ListCmd = &cobra.Command{ - Use: "list", - Short: "List Envoy bindings to an API Product", - Long: "List Envoy bindings to an API Product", - Args: func(cmd *cobra.Command, args []string) (err error) { - return apiclient.SetApigeeOrg(org) - }, - RunE: func(cmd *cobra.Command, args []string) (err error) { - _, err = products.GetAttribute(productName, envoyAttributeName) - return err - }, -} - -func init() { - ListCmd.Flags().StringVarP(&org, "org", "o", - "", "Apigee organization name") - ListCmd.Flags().StringVarP(&productName, "prod", "p", - "", "Apigee API Product name") - - _ = ListCmd.MarkFlagRequired("org") - _ = ListCmd.MarkFlagRequired("prod") -} diff --git a/cmd/envoy/removebinding.go b/cmd/envoy/removebinding.go deleted file mode 100644 index b02499a45..000000000 --- a/cmd/envoy/removebinding.go +++ /dev/null @@ -1,87 +0,0 @@ -// 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 envoy - -import ( - "encoding/json" - "fmt" - "strings" - - "github.com/apigee/apigeecli/apiclient" - "github.com/apigee/apigeecli/client/products" - "github.com/spf13/cobra" -) - -//RemoveCmd -var RemoveCmd = &cobra.Command{ - Use: "remove", - Short: "Removes an Envoy binding from an API Product", - Long: "Removes an Envoy binding from an API Product", - Args: func(cmd *cobra.Command, args []string) (err error) { - return apiclient.SetApigeeOrg(org) - }, - RunE: func(cmd *cobra.Command, args []string) (err error) { - - fmt.Println("Current Values of Attribute: ") - respBody, err := products.GetAttribute(productName, envoyAttributeName) - if err != nil { - return err - } - - var attributeValue map[string]string - err = json.Unmarshal(respBody, &attributeValue) - if err != nil { - return err - } - - values := strings.Split(attributeValue["value"], ",") - var newValues []string - var found bool - - for _, value := range values { - if strings.TrimSpace(value) != serviceName { - newValues = append(newValues, strings.TrimSpace(value)) - } else { - found = true - fmt.Println(("Found service name, removing binding")) - } - } - - if !found { - return fmt.Errorf("did not find value matching service name") - } - - fmt.Println("New Values of Attribute: ") - newAttributeValues := strings.Join(newValues, ",") - _, err = products.UpdateAttribute(productName, envoyAttributeName, newAttributeValues) - - return - }, -} - -var serviceName string - -func init() { - RemoveCmd.Flags().StringVarP(&org, "org", "o", - "", "Apigee organization name") - RemoveCmd.Flags().StringVarP(&productName, "prod", "p", - "", "Apigee API Product name") - RemoveCmd.Flags().StringVarP(&serviceName, "svc", "s", - "", "Envoy Service name") - - _ = RemoveCmd.MarkFlagRequired("org") - _ = RemoveCmd.MarkFlagRequired("prod") - _ = RemoveCmd.MarkFlagRequired("svc") -}