Skip to content

Commit

Permalink
ROSA: Support for OCM service account credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
mzazrivec committed Dec 3, 2024
1 parent 9b65314 commit 6c7f244
Showing 1 changed file with 54 additions and 27 deletions.
81 changes: 54 additions & 27 deletions pkg/rosa/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package rosa
import (
"context"
"fmt"
"os"

sdk "github.com/openshift-online/ocm-sdk-go"
ocmcfg "github.com/openshift/rosa/pkg/config"
Expand All @@ -16,68 +15,96 @@ import (
)

const (
ocmTokenKey = "ocmToken"
ocmAPIURLKey = "ocmApiUrl"
ocmTokenKey = "ocmToken"
ocmAPIURLKey = "ocmApiUrl"
ocmClientIdKey = "ocmClientId"
ocmClientSecretKey = "ocmClientSecret"
)

// NewOCMClient creates a new OCM client.
func NewOCMClient(ctx context.Context, rosaScope *scope.ROSAControlPlaneScope) (*ocm.Client, error) {
token, url, err := ocmCredentials(ctx, rosaScope)
token, url, clientId, clientSecret, err := ocmCredentials(ctx, rosaScope)
if err != nil {
return nil, err
}
return ocm.NewClient().Logger(logrus.New()).Config(&ocmcfg.Config{
AccessToken: token,
URL: url,
}).Build()

ocmConfig := ocmcfg.Config{
URL: url,
}

if clientId != "" && clientSecret != "" {
ocmConfig.ClientID = clientId
ocmConfig.ClientSecret = clientSecret
} else if token != "" {
rosaScope.Info(fmt.Sprintf("Using SSO offline token (%s) is deprecated, use service account credentials instead (%s and %s)",
ocmTokenKey, ocmClientIdKey, ocmClientSecretKey))

ocmConfig.AccessToken = token
}

return ocm.NewClient().Logger(logrus.New()).Config(&ocmConfig).Build()
}

func newOCMRawConnection(ctx context.Context, rosaScope *scope.ROSAControlPlaneScope) (*sdk.Connection, error) {
logger, err := sdk.NewGoLoggerBuilder().
ocmSdkLogger, err := sdk.NewGoLoggerBuilder().
Debug(false).
Build()
if err != nil {
return nil, fmt.Errorf("failed to build logger: %w", err)
}
token, url, err := ocmCredentials(ctx, rosaScope)

token, url, clientId, clientSecret, err := ocmCredentials(ctx, rosaScope)
if err != nil {
return nil, err
}

connection, err := sdk.NewConnectionBuilder().
Logger(logger).
Tokens(token).
URL(url).
Build()
connBuilder := sdk.NewConnectionBuilder().
Logger(ocmSdkLogger).
URL(url)

if clientId != "" && clientSecret != "" {
connBuilder.Client(clientId, clientSecret)
} else if token != "" {
rosaScope.Info(fmt.Sprintf("Using SSO offline token (%s) is deprecated, use service account credentials instead (%s and %s)",
ocmTokenKey, ocmClientIdKey, ocmClientSecretKey))

connBuilder.Tokens(token)
}

connection, err := connBuilder.Build()
if err != nil {
return nil, fmt.Errorf("failed to create ocm connection: %w", err)
}

return connection, nil
}

func ocmCredentials(ctx context.Context, rosaScope *scope.ROSAControlPlaneScope) (string, string, error) {
func ocmCredentials(ctx context.Context, rosaScope *scope.ROSAControlPlaneScope) (string, string, string, string, error) {
var token string
var ocmAPIUrl string
var ocmClientId string
var ocmClientSecret string

ocmAPIUrl := "https://api.openshift.com" // Defaults to production URL

secret := rosaScope.CredentialsSecret()
if secret != nil {
if err := rosaScope.Client.Get(ctx, client.ObjectKeyFromObject(secret), secret); err != nil {
return "", "", fmt.Errorf("failed to get credentials secret: %w", err)
return "", "", "", "", fmt.Errorf("failed to get credentials secret: %w", err)
}

token = string(secret.Data[ocmTokenKey])
ocmAPIUrl = string(secret.Data[ocmAPIURLKey])
} else {
// fallback to env variables if secrert is not set
token = os.Getenv("OCM_TOKEN")
if ocmAPIUrl = os.Getenv("OCM_API_URL"); ocmAPIUrl == "" {
ocmAPIUrl = "https://api.openshift.com"
}
ocmClientId = string(secret.Data[ocmClientIdKey])
ocmClientSecret = string(secret.Data[ocmClientSecretKey])
}

if token == "" {
return "", "", fmt.Errorf("token is not provided, be sure to set OCM_TOKEN env variable or reference a credentials secret with key %s", ocmTokenKey)
// FIXME: deployment level ocm credentials

if token == "" && (ocmClientId == "" || ocmClientSecret == "") {
return "", "", "", "",
fmt.Errorf("OCM credentials have not been provided. Make sure to set the service account credentials (%s and %s) or the offline token (%s)",
ocmClientIdKey, ocmClientSecretKey, ocmTokenKey)
}
return token, ocmAPIUrl, nil

return token, ocmAPIUrl, ocmClientId, ocmClientSecret, nil
}

0 comments on commit 6c7f244

Please sign in to comment.