Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSD-23312: Refactor GetRestConfig() to allow passing an ocm connection programatically #421

Merged
merged 1 commit into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions cmd/ocm-backplane/login/login.go
typeid marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

BackplaneApi "github.com/openshift/backplane-api/pkg/client"

ocmsdk "github.com/openshift-online/ocm-sdk-go"
"github.com/openshift/backplane-cli/pkg/backplaneapi"
"github.com/openshift/backplane-cli/pkg/cli/config"
"github.com/openshift/backplane-cli/pkg/cli/globalflags"
Expand Down Expand Up @@ -388,6 +389,38 @@ func GetRestConfig(bp config.BackplaneConfiguration, clusterID string) (*rest.Co
return cfg, nil
}

// GetRestConfig returns a client-go *rest.Config which can be used to programmatically interact with the
// Kubernetes API of a provided clusterID
func GetRestConfigWithConn(bp config.BackplaneConfiguration, ocmConnection *ocmsdk.Connection, clusterID string) (*rest.Config, error) {
cluster, err := ocm.DefaultOCMInterface.GetClusterInfoByIDWithConn(ocmConnection, clusterID)
if err != nil {
return nil, err
}

accessToken, err := ocm.DefaultOCMInterface.GetOCMAccessTokenWithConn(ocmConnection)
if err != nil {
return nil, err
}

bpAPIClusterURL, err := doLogin(bp.URL, clusterID, *accessToken)
if err != nil {
return nil, fmt.Errorf("failed to backplane login to cluster %s: %v", cluster.Name(), err)
}

cfg := &rest.Config{
Host: bpAPIClusterURL,
BearerToken: *accessToken,
}

if bp.ProxyURL != nil {
cfg.Proxy = func(*http.Request) (*url.URL, error) {
return url.Parse(*bp.ProxyURL)
}
}

return cfg, nil
}

// GetRestConfigAsUser returns a client-go *rest.Config like GetRestConfig, but supports configuring an
// impersonation username. Commonly, this is "backplane-cluster-admin"
// best practice would be to add at least one elevationReason in order to justity the impersonation
Expand Down
1 change: 0 additions & 1 deletion cmd/ocm-backplane/login/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,6 @@ var _ = Describe("Login command", func() {
})

Context("check GetRestConfigAsUser", func() {

It("check config creation with username and without elevationReasons", func() {
mockOcmInterface.EXPECT().GetClusterInfoByID(testClusterID).Return(mockCluster, nil)
mockOcmInterface.EXPECT().GetOCMAccessToken().Return(&testToken, nil)
Expand Down
30 changes: 30 additions & 0 deletions pkg/ocm/mocks/ocmWrapperMock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 27 additions & 13 deletions pkg/ocm/ocmWrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type OCMInterface interface {
GetPullSecret() (string, error)
GetStsSupportJumpRoleARN(ocmConnection *ocmsdk.Connection, clusterID string) (string, error)
GetOCMEnvironment() (*cmv1.Environment, error)
GetOCMAccessTokenWithConn(ocmConnection *ocmsdk.Connection) (*string, error)
GetClusterInfoByIDWithConn(ocmConnection *ocmsdk.Connection, clusterID string) (*cmv1.Cluster, error)
}

const (
Expand All @@ -38,7 +40,7 @@ type DefaultOCMInterfaceImpl struct{}
var DefaultOCMInterface OCMInterface = &DefaultOCMInterfaceImpl{}

// IsClusterHibernating returns a boolean to indicate whether the cluster is hibernating
func (*DefaultOCMInterfaceImpl) IsClusterHibernating(clusterID string) (bool, error) {
func (o *DefaultOCMInterfaceImpl) IsClusterHibernating(clusterID string) (bool, error) {
connection, err := ocm.NewConnection().Build()
if err != nil {
return false, fmt.Errorf("failed to create OCM connection: %v", err)
Expand All @@ -54,7 +56,7 @@ func (*DefaultOCMInterfaceImpl) IsClusterHibernating(clusterID string) (bool, er
}

// GetTargetCluster returns one single cluster based on the search key and survery.
func (*DefaultOCMInterfaceImpl) GetTargetCluster(clusterKey string) (clusterID, clusterName string, err error) {
func (o *DefaultOCMInterfaceImpl) GetTargetCluster(clusterKey string) (clusterID, clusterName string, err error) {
// Create the client for the OCM API:
connection, err := ocm.NewConnection().Build()
if err != nil {
Expand Down Expand Up @@ -143,7 +145,7 @@ func (o *DefaultOCMInterfaceImpl) GetManagingCluster(targetClusterID string) (cl
}

// GetServiceCluster gets the service cluster for a given hpyershift hosted cluster
func (*DefaultOCMInterfaceImpl) GetServiceCluster(targetClusterID string) (clusterID, clusterName string, err error) {
func (o *DefaultOCMInterfaceImpl) GetServiceCluster(targetClusterID string) (clusterID, clusterName string, err error) {
// Create the client for the OCM API
connection, err := ocm.NewConnection().Build()
if err != nil {
Expand Down Expand Up @@ -197,15 +199,22 @@ func (*DefaultOCMInterfaceImpl) GetServiceCluster(targetClusterID string) (clust
}

// GetOCMAccessToken initiates the OCM connection and returns the access token
func (*DefaultOCMInterfaceImpl) GetOCMAccessToken() (*string, error) {
func (o *DefaultOCMInterfaceImpl) GetOCMAccessToken() (*string, error) {
// Get ocm access token
logger.Debugln("Finding ocm token")
connection, err := ocm.NewConnection().Build()
if err != nil {
return nil, fmt.Errorf("failed to create OCM connection: %v", err)
}
defer connection.Close()
accessToken, _, err := connection.Tokens()

return o.GetOCMAccessTokenWithConn(connection)
}

// GetOCMAccessTokenWithConn returns the access token of an ocmConnection
func (o *DefaultOCMInterfaceImpl) GetOCMAccessTokenWithConn(ocmConnection *ocmsdk.Connection) (*string, error) {
// Get ocm access token
logger.Debugln("Finding ocm token")
accessToken, _, err := ocmConnection.Tokens()
if err != nil {
return nil, err
}
Expand All @@ -217,7 +226,7 @@ func (*DefaultOCMInterfaceImpl) GetOCMAccessToken() (*string, error) {
}

// GetPullSecret returns pull secret from OCM
func (*DefaultOCMInterfaceImpl) GetPullSecret() (string, error) {
func (o *DefaultOCMInterfaceImpl) GetPullSecret() (string, error) {

// Get ocm access token
logger.Debugln("Finding ocm token")
Expand All @@ -239,16 +248,21 @@ func (*DefaultOCMInterfaceImpl) GetPullSecret() (string, error) {

// GetClusterInfoByID calls the OCM to retrieve the cluster info
// for a given internal cluster id.
func (*DefaultOCMInterfaceImpl) GetClusterInfoByID(clusterID string) (*cmv1.Cluster, error) {
func (o *DefaultOCMInterfaceImpl) GetClusterInfoByID(clusterID string) (*cmv1.Cluster, error) {
// Create the client for the OCM API:
connection, err := ocm.NewConnection().Build()
if err != nil {
return nil, fmt.Errorf("failed to create OCM connection: %v", err)
}
defer connection.Close()

// Get the cluster info based on the cluster id
response, err := connection.ClustersMgmt().V1().Clusters().Cluster(clusterID).Get().Send()
return o.GetClusterInfoByIDWithConn(connection, clusterID)
}

// GetClusterInfoByIDWithConn calls the OCM to retrieve the cluster info
// for a given internal cluster id.
func (o *DefaultOCMInterfaceImpl) GetClusterInfoByIDWithConn(ocmConnection *ocmsdk.Connection, clusterID string) (*cmv1.Cluster, error) {
response, err := ocmConnection.ClustersMgmt().V1().Clusters().Cluster(clusterID).Get().Send()
if err != nil {
return nil, fmt.Errorf("can't retrieve cluster for id '%s': %v", clusterID, err)
}
Expand All @@ -260,7 +274,7 @@ func (*DefaultOCMInterfaceImpl) GetClusterInfoByID(clusterID string) (*cmv1.Clus
}

// IsProduction checks if OCM is currently in production env
func (*DefaultOCMInterfaceImpl) IsProduction() (bool, error) {
func (o *DefaultOCMInterfaceImpl) IsProduction() (bool, error) {
// Create the client for the OCM API:
connection, err := ocm.NewConnection().Build()
if err != nil {
Expand All @@ -271,7 +285,7 @@ func (*DefaultOCMInterfaceImpl) IsProduction() (bool, error) {
return connection.URL() == "https://api.openshift.com", nil
}

func (*DefaultOCMInterfaceImpl) GetStsSupportJumpRoleARN(ocmConnection *ocmsdk.Connection, clusterID string) (string, error) {
func (o *DefaultOCMInterfaceImpl) GetStsSupportJumpRoleARN(ocmConnection *ocmsdk.Connection, clusterID string) (string, error) {
response, err := ocmConnection.ClustersMgmt().V1().Clusters().Cluster(clusterID).StsSupportJumpRole().Get().Send()
if err != nil {
return "", fmt.Errorf("failed to get STS Support Jump Role for cluster %v, %w", clusterID, err)
Expand All @@ -280,7 +294,7 @@ func (*DefaultOCMInterfaceImpl) GetStsSupportJumpRoleARN(ocmConnection *ocmsdk.C
}

// GetBackplaneURL returns the Backplane API URL based on the OCM env
func (*DefaultOCMInterfaceImpl) GetOCMEnvironment() (*cmv1.Environment, error) {
func (o *DefaultOCMInterfaceImpl) GetOCMEnvironment() (*cmv1.Environment, error) {
// Create the client for the OCM API
connection, err := ocm.NewConnection().Build()
if err != nil {
Expand Down