diff --git a/cmd/cluster/network/endpoint/create_endpoint.go b/cmd/cluster/network/endpoint/create_endpoint.go index dedfd668..82fd6c46 100644 --- a/cmd/cluster/network/endpoint/create_endpoint.go +++ b/cmd/cluster/network/endpoint/create_endpoint.go @@ -34,11 +34,16 @@ var createEndpointCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { authApi, err := ybmAuthClient.NewAuthApiClient() if err != nil { - logrus.Fatalf("Could not initiate api client: %s", err.Error()) + logrus.Fatalf("Could not initiate api client: %s", ybmAuthClient.GetApiErrorDetails(err)) } authApi.GetInfo("", "") - clusterData := getCluster(cmd, authApi) + clusterName, _ := cmd.Flags().GetString("cluster-name") + clusterData, err := authApi.GetClusterByName(clusterName) + if err != nil { + logrus.Fatalf("Could not get cluster data: %s", ybmAuthClient.GetApiErrorDetails(err)) + } + accessibilityType, _ := cmd.Flags().GetString("accessibility-type") reg, _ := cmd.Flags().GetString("region") @@ -75,7 +80,7 @@ var createEndpointCmd = &cobra.Command{ createResp, r, err := authApi.CreatePrivateServiceEndpoint(clusterData.Info.Id).PrivateServiceEndpointSpec(createPseSpec[0]).Execute() if err != nil { logrus.Debugf("Full HTTP response: %v", r) - logrus.Fatalf("Could not create private service endpoint: %s", err.Error()) + logrus.Fatalf("Could not create private service endpoint: %s", ybmAuthClient.GetApiErrorDetails(err)) } psEps := util.Filter(createResp.GetData(), func(ep ybmclient.PrivateServiceEndpointRegionData) bool { @@ -99,9 +104,9 @@ var createEndpointCmd = &cobra.Command{ func init() { EndpointCmd.AddCommand(createEndpointCmd) - createEndpointCmd.Flags().String("accessibility-type", "", "[REQUIRED] The accessibility of the endpoint.") + createEndpointCmd.Flags().String("accessibility-type", "", "[REQUIRED] The accessibility of the endpoint. Valid options are PUBLIC, PRIVATE and PRIVATE_SERVICE_ENDPOINT.") createEndpointCmd.MarkFlagRequired("accessibility-type") createEndpointCmd.Flags().String("region", "", "[REQUIRED] The region of the endpoint.") createEndpointCmd.MarkFlagRequired("region") - createEndpointCmd.Flags().String("security-principals", "", "[OPTIONAL] The security principals of the endpoint.") + createEndpointCmd.Flags().String("security-principals", "", "[OPTIONAL] The list of security principals that have access to this endpoint. Required for private service endpoints. Accepts a comma separated list. E.g.: `arn:aws:iam::account_id1:root,arn:aws:iam::account_id2:root`") } diff --git a/cmd/cluster/network/endpoint/delete_endpoint.go b/cmd/cluster/network/endpoint/delete_endpoint.go index 1f25a9f8..6c00590c 100644 --- a/cmd/cluster/network/endpoint/delete_endpoint.go +++ b/cmd/cluster/network/endpoint/delete_endpoint.go @@ -31,14 +31,19 @@ var deleteEndpointCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { authApi, err := ybmAuthClient.NewAuthApiClient() if err != nil { - logrus.Fatalf("Could not initiate api client: %s\n", err.Error()) + logrus.Fatalf("Could not initiate api client: %s\n", ybmAuthClient.GetApiErrorDetails(err)) } authApi.GetInfo("", "") - clusterEndpoints, clusterId, endpointId := getEndpointById(cmd, authApi) + clusterName, _ := cmd.Flags().GetString("cluster-name") + endpointId, _ := cmd.Flags().GetString("endpoint-id") + clusterEndpoint, clusterId, err := authApi.GetEndpointByIdForClusterByName(clusterName, endpointId) + if err != nil { + logrus.Fatalf("Error when calling `ClusterApi.GetEndpointByIdForClusterByName`: %s\n", ybmAuthClient.GetApiErrorDetails(err)) + } // We currently support fetching just Private Service Endpoints - switch clusterEndpoints[0].GetAccessibilityType() { + switch clusterEndpoint.GetAccessibilityType() { case ybmclient.ACCESSIBILITYTYPE_PRIVATE_SERVICE_ENDPOINT: logrus.Debugln("Endpoint is a private service endpoint, attempting to delete") diff --git a/cmd/cluster/network/endpoint/describe_endpoint.go b/cmd/cluster/network/endpoint/describe_endpoint.go index 16956060..e1b1c116 100644 --- a/cmd/cluster/network/endpoint/describe_endpoint.go +++ b/cmd/cluster/network/endpoint/describe_endpoint.go @@ -33,14 +33,19 @@ var describeEndpointCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { authApi, err := ybmAuthClient.NewAuthApiClient() if err != nil { - logrus.Fatalf("Could not initiate api client: %s\n", err.Error()) + logrus.Fatalf("Could not initiate api client: %s\n", ybmAuthClient.GetApiErrorDetails(err)) } authApi.GetInfo("", "") - clusterEndpoints, clusterId, endpointId := getEndpointById(cmd, authApi) + clusterName, _ := cmd.Flags().GetString("cluster-name") + endpointId, _ := cmd.Flags().GetString("endpoint-id") + clusterEndpoint, clusterId, err := authApi.GetEndpointByIdForClusterByName(clusterName, endpointId) + if err != nil { + logrus.Fatalf("Error when calling `ClusterApi.GetEndpointByIdForClusterByName`: %s\n", ybmAuthClient.GetApiErrorDetails(err)) + } // We currently support fetching just Private Service Endpoints - switch clusterEndpoints[0].GetAccessibilityType() { + switch clusterEndpoint.GetAccessibilityType() { case ybmclient.ACCESSIBILITYTYPE_PRIVATE_SERVICE_ENDPOINT: logrus.Debugln("Endpoint is a private service endpoint, getting more data") @@ -53,7 +58,7 @@ var describeEndpointCmd = &cobra.Command{ psEndpointContext := *formatter.NewPSEndpointContext() psEndpointContext.Output = os.Stdout psEndpointContext.Format = formatter.NewPSEndpointFormat(viper.GetString("output")) - psEndpointContext.SetFullPSEndpoint(*authApi, pseGetResponse.GetData(), clusterEndpoints[0]) + psEndpointContext.SetFullPSEndpoint(*authApi, pseGetResponse.GetData(), clusterEndpoint) psEndpointContext.Write() return } @@ -62,7 +67,7 @@ var describeEndpointCmd = &cobra.Command{ Output: os.Stdout, Format: formatter.NewPSEndpointFormat(viper.GetString("output")), } - formatter.PSEndpointWrite(psEndpointContext, pseGetResponse.GetData(), clusterEndpoints[0]) + formatter.PSEndpointWrite(psEndpointContext, pseGetResponse.GetData(), clusterEndpoint) default: logrus.Fatalf("Endpoint is not a private service endpoint. Only private service endpoints are currently supported.\n") diff --git a/cmd/cluster/network/endpoint/list_endpoint.go b/cmd/cluster/network/endpoint/list_endpoint.go index 5f9e8925..62d96e0a 100644 --- a/cmd/cluster/network/endpoint/list_endpoint.go +++ b/cmd/cluster/network/endpoint/list_endpoint.go @@ -35,11 +35,15 @@ var listEndpointCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { authApi, err := ybmAuthClient.NewAuthApiClient() if err != nil { - logrus.Fatalf("Could not initiate api client: %s\n", err.Error()) + logrus.Fatalf("Could not initiate api client: %s\n", ybmAuthClient.GetApiErrorDetails(err)) } authApi.GetInfo("", "") - clusterEndpoints, _ := getEndpoints(cmd, authApi) + clusterName, _ := cmd.Flags().GetString("cluster-name") + clusterEndpoints, _, err := authApi.GetEndpointsForClusterByName(clusterName) + if err != nil { + logrus.Fatalf("Could not get cluster data: %s\n", ybmAuthClient.GetApiErrorDetails(err)) + } region, _ := cmd.Flags().GetString("region") if region != "" { @@ -69,6 +73,6 @@ var listEndpointCmd = &cobra.Command{ func init() { EndpointCmd.AddCommand(listEndpointCmd) - listEndpointCmd.Flags().String("accessibility", "", "[OPTIONAL] Accessibility of the endpoint") - listEndpointCmd.Flags().String("region", "", "[OPTIONAL] Region of the endpoint") + listEndpointCmd.Flags().String("accessibility-type", "", "[OPTIONAL] Accessibility of the endpoint. Valid options are PUBLIC, PRIVATE and PRIVATE_SERVICE_ENDPOINT.") + listEndpointCmd.Flags().String("region", "", "[OPTIONAL] The region of the endpoint.") } diff --git a/cmd/cluster/network/endpoint/update_endpoint.go b/cmd/cluster/network/endpoint/update_endpoint.go index 7053fe25..1403bcec 100644 --- a/cmd/cluster/network/endpoint/update_endpoint.go +++ b/cmd/cluster/network/endpoint/update_endpoint.go @@ -32,14 +32,19 @@ var updateEndpointCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { authApi, err := ybmAuthClient.NewAuthApiClient() if err != nil { - logrus.Fatalf("Could not initiate api client: %s\n", err.Error()) + logrus.Fatalf("Could not initiate api client: %s\n", ybmAuthClient.GetApiErrorDetails(err)) } authApi.GetInfo("", "") - clusterEndpoints, clusterId, endpointId := getEndpointById(cmd, authApi) + clusterName, _ := cmd.Flags().GetString("cluster-name") + endpointId, _ := cmd.Flags().GetString("endpoint-id") + clusterEndpoint, clusterId, err := authApi.GetEndpointByIdForClusterByName(clusterName, endpointId) + if err != nil { + logrus.Fatalf("Error when calling `ClusterApi.GetEndpointByIdForClusterByName`: %s\n", ybmAuthClient.GetApiErrorDetails(err)) + } // We currently support fetching just Private Service Endpoints - switch clusterEndpoints[0].GetAccessibilityType() { + switch clusterEndpoint.GetAccessibilityType() { case ybmclient.ACCESSIBILITYTYPE_PRIVATE_SERVICE_ENDPOINT: if !cmd.Flags().Changed("security-principals") { @@ -82,5 +87,5 @@ func init() { EndpointCmd.AddCommand(updateEndpointCmd) updateEndpointCmd.Flags().String("endpoint-id", "", "[REQUIRED] The ID of the endpoint") updateEndpointCmd.MarkFlagRequired("endpoint-id") - updateEndpointCmd.Flags().String("security-principals", "", "[OPTIONAL] The list of security principals that have access to this endpoint (comma separated). Required for private service endpoints") + updateEndpointCmd.Flags().String("security-principals", "", "[OPTIONAL] The list of security principals that have access to this endpoint. Required for private service endpoints. Accepts a comma separated list. E.g.: `arn:aws:iam::account_id1:root,arn:aws:iam::account_id2:root`") } diff --git a/cmd/cluster/network/endpoint/util_endpoint.go b/cmd/cluster/network/endpoint/util_endpoint.go deleted file mode 100644 index d72031c6..00000000 --- a/cmd/cluster/network/endpoint/util_endpoint.go +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to Yugabyte, Inc. under one or more contributor license -// agreements. See the NOTICE file distributed with this work for -// additional information regarding copyright ownership. Yugabyte -// licenses this file to you 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 endpoint - -import ( - "encoding/json" - - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - "github.com/yugabyte/ybm-cli/cmd/util" - ybmAuthClient "github.com/yugabyte/ybm-cli/internal/client" - ybmclient "github.com/yugabyte/yugabytedb-managed-go-client-internal" -) - -func getCluster(cmd *cobra.Command, authApi *ybmAuthClient.AuthApiClient) ybmclient.ClusterData { - clusterName, _ := cmd.Flags().GetString("cluster-name") - clusterListRequest := authApi.ListClusters() - // user filters by name, add it to the request - clusterListRequest = clusterListRequest.Name(clusterName) - - resp, r, err := clusterListRequest.Execute() - if err != nil { - logrus.Debugf("Full HTTP response: %v", r) - logrus.Fatalf("Error when calling `ClusterApi.ListClusters`: %s\n", ybmAuthClient.GetApiErrorDetails(err)) - } - - if len(resp.GetData()) == 0 { - logrus.Fatalf("Cluster not found\n") - } - - return resp.GetData()[0] -} - -func getEndpoints(cmd *cobra.Command, authApi *ybmAuthClient.AuthApiClient) ([]ybmclient.Endpoint, string) { - clusterData := getCluster(cmd, authApi) - - clusterId := clusterData.Info.Id - clusterEndpoints := clusterData.Info.ClusterEndpoints - jsonEndpoints, _ := json.Marshal(clusterEndpoints) - logrus.Debugf("Found endpoints: %v", string(jsonEndpoints)) - - return clusterEndpoints, clusterId -} - -func getEndpointById(cmd *cobra.Command, authApi *ybmAuthClient.AuthApiClient) ([]ybmclient.Endpoint, string, string) { - clusterEndpoints, clusterId := getEndpoints(cmd, authApi) - endpointId, _ := cmd.Flags().GetString("endpoint-id") - clusterEndpoints = util.Filter(clusterEndpoints, func(endpoint ybmclient.Endpoint) bool { - return endpoint.Id == endpointId || endpoint.GetPseId() == endpointId - }) - - if len(clusterEndpoints) == 0 { - logrus.Fatalf("Endpoint not found\n") - } - - return clusterEndpoints, clusterId, endpointId -} diff --git a/internal/client/client.go b/internal/client/client.go index 922a4b4b..cb6c0455 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -312,17 +312,60 @@ func (a *AuthApiClient) GetInfo(providedAccountID string, providedProjectID stri } } -func (a *AuthApiClient) GetClusterIdByName(clusterName string) (string, error) { +func (a *AuthApiClient) GetClusterByName(clusterName string) (ybmclient.ClusterData, error) { clusterResp, resp, err := a.ListClusters().Name(clusterName).Execute() if err != nil { b, _ := httputil.DumpResponse(resp, true) logrus.Debug(string(b)) - return "", err + return ybmclient.ClusterData{}, err } clusterData := clusterResp.GetData() if len(clusterData) != 0 { - return clusterData[0].Info.GetId(), nil + return clusterData[0], nil + } + + return ybmclient.ClusterData{}, fmt.Errorf("could not get cluster data for cluster name: %s", clusterName) +} + +func (a *AuthApiClient) GetEndpointsForClusterByName(clusterName string) ([]ybmclient.Endpoint, string, error) { + clusterData, err := a.GetClusterByName(clusterName) + if err != nil { + return nil, "", err + } + clusterId := clusterData.Info.GetId() + clusterEndpoints := clusterData.Info.GetClusterEndpoints() + jsonEndpoints, _ := json.Marshal(clusterEndpoints) + logrus.Debugf("Found endpoints: %v\n", string(jsonEndpoints)) + + return clusterEndpoints, clusterId, nil +} + +func (a *AuthApiClient) GetEndpointByIdForClusterByName(clusterName string, endpointId string) (ybmclient.Endpoint, string, error) { + endpoints, clusterId, err := a.GetEndpointsForClusterByName(clusterName) + if err != nil { + // return the error + return ybmclient.Endpoint{}, "", err + } + + endpoints = util.Filter(endpoints, func(endpoint ybmclient.Endpoint) bool { + return endpoint.GetId() == endpointId || endpoint.GetPseId() == endpointId + }) + + if len(endpoints) == 0 { + logrus.Fatalf("Endpoint not found\n") + } + if len(endpoints) > 1 { + logrus.Fatalf("Multiple endpoints found\n") + } + + return endpoints[0], clusterId, nil +} + +func (a *AuthApiClient) GetClusterIdByName(clusterName string) (string, error) { + clusterData, err := a.GetClusterByName(clusterName) + if err == nil { + return clusterData.Info.GetId(), nil } return "", fmt.Errorf("could not get cluster data for cluster name: %s", clusterName)