Documentation
¶
Index ¶
- Constants
- Variables
- func AccessTokenToSimple(auths map[string]*amv1.AccessTokenAuth) map[string]SimpleAuth
- func CheckExistingSyncSets(ctx context.Context, hiveNamespace string, kubeCli client.Client, in io.Reader, ...) error
- func CountOwnerClusters(ocm *sdk.Connection, accountID string, logger *logrus.Logger) int
- func DeleteCredentialSecrets(ctx context.Context, managedClient client.Client, in io.Reader, out io.Writer) error
- func ExtractRegistryAuth(pullSecretData []byte, registry string) (string, error)
- func FetchOwnerAccessToken(ocm *sdk.Connection, ownerUsername string, logger *logrus.Logger) ([]byte, map[string]*amv1.AccessTokenAuth, error)
- func GetLatestCredentialUpdate(ocm *sdk.Connection, accountID string) (time.Time, error)
- func MergePullSecretAuths(existingData, newData []byte) ([]byte, error)
- func RenderCredRequestTable(report *DiagnosticReport, out io.Writer)
- func RenderReport(report *DiagnosticReport, out io.Writer)
- func RenderThreeWayComparison(result *ThreeWayComparison, sourceLabel string, hasHive bool, out io.Writer)
- func RenderVerifyResult(result *PullSecretVerifyResult, out io.Writer)
- func RestartPodsBySelector(ctx context.Context, clientset *kubernetes.Clientset, ...) error
- func RotateSecret(ctx context.Context, input *RotateSecretInput) error
- func UpdateHCPPullSecretViaManifestWork(ctx context.Context, ocm *sdk.Connection, kubeCli client.Client, ...) error
- func UpdateHivePullSecretSSS(ctx context.Context, kubeCli client.Client, clientset kubernetes.Interface, ...) error
- func ValidateRequiredAuths(auths map[string]*amv1.AccessTokenAuth) []string
- func VerifyRotationPermissions(out io.Writer, awsClient awsprovider.Client, accountID string, username string) error
- type AWSCredsInput
- type AuthCheckResult
- type ClusterSummary
- type CredRequestStatus
- type DiagnosticReport
- type Finding
- type HiveNamespaceInfo
- type InsufficientPermissionsError
- type KeyStatus
- type PermissionResult
- type PullSecretOp
- func (op *PullSecretOp) CheckCanI(ctx context.Context, clientset *kubernetes.Clientset, ...) bool
- func (op *PullSecretOp) CheckSecretExists(ctx context.Context, clientset *kubernetes.Clientset, ...) bool
- func (op *PullSecretOp) Fail(format string, args ...any)
- func (op *PullSecretOp) FetchAccessTokenOp(ocm *sdk.Connection, ownerUsername string) ([]byte, map[string]*amv1.AccessTokenAuth, bool)
- func (op *PullSecretOp) FindHiveNamespaceOp(ctx context.Context, kubeCli client.Client, clusterID, infraName string) (*HiveNamespaceInfo, bool)
- func (op *PullSecretOp) Info(format string, args ...any)
- func (op *PullSecretOp) OK(format string, args ...any)
- func (op *PullSecretOp) ResolveExistingPullSecret(ctx context.Context, infraClientSet *kubernetes.Clientset, ...) ([]byte, string)
- func (op *PullSecretOp) Section(step int, title string, lines ...string)
- func (op *PullSecretOp) Warn(format string, args ...any)
- func (op *PullSecretOp) Would(format string, args ...any)
- type PullSecretVerifyResult
- type RotateSecretInput
- type SecretStatus
- type SimpleAuth
- type ThreeWayAuthState
- type ThreeWayComparison
Constants ¶
const SyncSetName = "pull-secret-update"
SyncSetName is the name used by this tool for pull secret SyncSets. Distinct from "pull-secret-replacement" used by transfer-owner to avoid collisions.
Variables ¶
var CRSecretPollInterval = 5 * time.Second
CRSecretPollInterval is the delay between CR health checks after deleting a secret.
var CRSecretPollTimeout = 60 * time.Second
CRSecretPollTimeout is the maximum time to wait for CCO to recreate a secret.
var RequiredPullSecretAuths = []string{
"cloud.openshift.com",
"quay.io",
"registry.redhat.io",
"registry.connect.redhat.com",
}
RequiredPullSecretAuths lists the registry auth entries that must be present in a cluster's pull secret for the cluster to function.
var RotationRequiredActions = []string{
"iam:CreateAccessKey",
"iam:CreateUser",
"iam:DeleteAccessKey",
"iam:DeleteUser",
"iam:DeleteUserPolicy",
"iam:GetUser",
"iam:GetUserPolicy",
"iam:ListAccessKeys",
"iam:PutUserPolicy",
"iam:TagUser",
}
RotationRequiredActions are the IAM actions needed by the rotation tooling to create/delete access keys and manage IAM users.
var SyncMaxRetries = 6
SyncMaxRetries is the maximum number of ClusterSync poll attempts.
var SyncPollInterval = 5 * time.Second
SyncPollInterval is the delay between ClusterSync status checks.
Functions ¶
func AccessTokenToSimple ¶ added in v0.63.0
func AccessTokenToSimple(auths map[string]*amv1.AccessTokenAuth) map[string]SimpleAuth
AccessTokenToSimple converts access token auths to SimpleAuth map.
func CheckExistingSyncSets ¶ added in v0.63.0
func CheckExistingSyncSets(ctx context.Context, hiveNamespace string, kubeCli client.Client, in io.Reader, out io.Writer) error
CheckExistingSyncSets checks for existing SyncSets that could interfere with a new pull secret sync. Must be called BEFORE updating the hive secret so that aborting leaves no mutations.
func CountOwnerClusters ¶ added in v0.63.0
CountOwnerClusters returns the number of active clusters owned by the given account ID.
func DeleteCredentialSecrets ¶ added in v0.62.0
func DeleteCredentialSecrets(ctx context.Context, managedClient client.Client, in io.Reader, out io.Writer) error
DeleteCredentialSecrets sequentially deletes each credential secret and waits for CCO to recreate it before proceeding to the next one.
func ExtractRegistryAuth ¶ added in v0.63.0
ExtractRegistryAuth extracts the "auth" field for a given registry from raw pull secret JSON bytes.
func FetchOwnerAccessToken ¶ added in v0.63.0
func FetchOwnerAccessToken(ocm *sdk.Connection, ownerUsername string, logger *logrus.Logger) ([]byte, map[string]*amv1.AccessTokenAuth, error)
FetchOwnerAccessToken retrieves the cluster owner's pull secret from OCM, using impersonation if the current OCM user is not the cluster owner. Returns the marshaled pull secret bytes and the raw auth map for verification.
func GetLatestCredentialUpdate ¶ added in v0.63.0
GetLatestCredentialUpdate returns the most recent UpdatedAt time across all registry credentials for the given account.
func MergePullSecretAuths ¶ added in v0.63.0
MergePullSecretAuths merges new auths into existing pull secret data. Existing auths not present in newData are preserved. This never removes auths.
func RenderCredRequestTable ¶ added in v0.62.0
func RenderCredRequestTable(report *DiagnosticReport, out io.Writer)
RenderCredRequestTable outputs the CredentialRequest secrets table.
func RenderReport ¶ added in v0.62.0
func RenderReport(report *DiagnosticReport, out io.Writer)
RenderReport formats the diagnostic report as a human-readable table.
func RenderThreeWayComparison ¶ added in v0.63.0
func RenderThreeWayComparison(result *ThreeWayComparison, sourceLabel string, hasHive bool, out io.Writer)
RenderThreeWayComparison prints the three-way comparison in a readable format. sourceLabel identifies the OCM source (e.g. "ACCESS TOKEN AUTHS", "REGISTRY CREDENTIAL AUTHS"). When hasHive is false (HCP clusters), the hive columns are omitted.
func RenderVerifyResult ¶ added in v0.63.0
func RenderVerifyResult(result *PullSecretVerifyResult, out io.Writer)
RenderVerifyResult writes the verification result in human-readable format.
func RestartPodsBySelector ¶ added in v0.63.0
func RestartPodsBySelector(ctx context.Context, clientset *kubernetes.Clientset, namespace, selector string, out io.Writer) error
RestartPodsBySelector deletes pods matching the selector in the namespace to trigger a rollout.
func RotateSecret ¶
func RotateSecret(ctx context.Context, input *RotateSecretInput) error
RotateSecret performs the IAM credential rotation workflow:
- Validates the Account CR (not STS, has iamUserId label)
- Resolves the osdManagedAdmin username
- Verifies rotation permissions via SimulatePrincipalPolicy
- Creates a new IAM access key
- Updates k8s secrets on hive
- Creates a SyncSet to push credentials to the cluster
- Polls ClusterSync for completion and cleans up the SyncSet
- Optionally rotates osdCcsAdmin credentials
func UpdateHCPPullSecretViaManifestWork ¶ added in v0.63.0
func UpdateHCPPullSecretViaManifestWork(ctx context.Context, ocm *sdk.Connection, kubeCli client.Client, clusterID, mgmtClusterName string, pullsecret []byte, in io.Reader, out io.Writer) error
UpdateHCPPullSecretViaManifestWork updates the pull secret within a ManifestWork on the service cluster for HCP clusters.
HCP pull secret architecture:
- This operates at level 1 (HostedCluster.spec.pullSecret)
- HCCO reconciles changes to kube-system/original-pull-secret on the hosted cluster
- Customer-added registries in kube-system/additional-pull-secret are not affected
- Ref: https://access.redhat.com/solutions/7118834
- Ref: https://hypershift.pages.dev/how-to/powervs/global-pull-secret/
func UpdateHivePullSecretSSS ¶ added in v0.63.0
func UpdateHivePullSecretSSS(ctx context.Context, kubeCli client.Client, clientset kubernetes.Interface, hiveNamespace string, cdName string, pullsecret []byte, in io.Reader, out io.Writer) error
UpdateHivePullSecretSSS updates the pull secret in the given hive namespace using update-in-place (never deletes). If the secret doesn't exist, it creates it. When the secret exists, new auths are merged into the existing secret via MergePullSecretAuths, preserving any auths not present in the new data.
func ValidateRequiredAuths ¶ added in v0.63.0
func ValidateRequiredAuths(auths map[string]*amv1.AccessTokenAuth) []string
ValidateRequiredAuths checks that the OCM access token includes all required registry auth entries. Returns the list of missing registries.
func VerifyRotationPermissions ¶
func VerifyRotationPermissions(out io.Writer, awsClient awsprovider.Client, accountID string, username string) error
VerifyRotationPermissions checks if the assumed role has the necessary IAM permissions to perform secret rotation by simulating the required actions. Uses simulateActions internally for consistency with the diagnostic path.
Types ¶
type AWSCredsInput ¶ added in v0.62.0
type AWSCredsInput struct {
ClusterID string
ClusterName string
ClusterExternalID string
IsCCS bool
AWSAccountID string
AccountCRName string
Account *awsv1alpha1.Account
AdminUsername string
AwsClient awsprovider.Client
HiveKubeClient client.Client
ManagedClient client.Client
Log *logrus.Logger
Out io.Writer
}
AWSCredsInput holds all resolved dependencies needed for both diagnostics and rotation. The CLI layer resolves AWS and k8s clients before calling DiagnoseCredentials or RotateCredentials.
type AuthCheckResult ¶ added in v0.63.0
type AuthCheckResult struct {
Registry string
Source string // "access_token" or "registry_credential"
OK bool
TokenMatch bool
EmailMatch bool
Email string
Detail string
}
AuthCheckResult holds the outcome of a single registry auth comparison.
type ClusterSummary ¶ added in v0.63.0
ClusterSummary holds subscription-level data for a cluster owned by an account.
func ListOwnerSubscriptions ¶ added in v0.63.0
func ListOwnerSubscriptions(ocm *sdk.Connection, accountID string) ([]ClusterSummary, error)
ListOwnerSubscriptions returns all active subscriptions for the given account ID.
type CredRequestStatus ¶ added in v0.62.0
type DiagnosticReport ¶ added in v0.62.0
type DiagnosticReport struct {
ClusterID string
ClusterName string
ClusterExternalID string
IsCCS bool
AWSAccountID string
AccountCRName string
ManagedAdminUser string
CcsAdminUser string
CallerARN string
CallerAccount string
Keys []KeyStatus
Secrets []SecretStatus
CredRequests []CredRequestStatus
Permissions []PermissionResult
Findings []Finding
AllPermissionsOK bool
AllSecretsInSync bool
RootKeyInSync bool
ClusterRootKeyID string
HiveAccountKeyID string
}
func DiagnoseCRSecrets ¶ added in v0.62.0
func DiagnoseCRSecrets(ctx context.Context, hiveClient client.Client, managedClient client.Client, accountCRName string, account *awsv1alpha1.Account, out io.Writer) (*DiagnosticReport, error)
DiagnoseCRSecrets produces a lightweight report of just the CredentialRequest secrets, comparing the cluster's root credential (kube-system/aws-creds) against the Hive account secret to detect staleness.
func DiagnoseCredentials ¶ added in v0.62.0
func DiagnoseCredentials(ctx context.Context, input *AWSCredsInput) (*DiagnosticReport, error)
DiagnoseCredentials runs a full read-only diagnostic of IAM keys, Hive secrets, CredentialRequests, and IAM permissions, returning a structured report.
type HiveNamespaceInfo ¶ added in v0.63.0
HiveNamespaceInfo holds the resolved Hive namespace and ClusterDeployment name for a given cluster.
func FindHiveNamespace ¶ added in v0.63.0
func FindHiveNamespace(ctx context.Context, kubeCli client.Client, clusterID string) (*HiveNamespaceInfo, error)
FindHiveNamespace discovers the Hive namespace for a cluster by listing ClusterDeployments filtered by the api.openshift.com/id label. This avoids the fragile uhc-{env}-{clusterID} namespace construction.
type InsufficientPermissionsError ¶
type InsufficientPermissionsError struct {
DeniedActions []string
}
InsufficientPermissionsError is returned when SimulatePrincipalPolicy reports that one or more required IAM actions are denied.
func (*InsufficientPermissionsError) Error ¶
func (e *InsufficientPermissionsError) Error() string
Error returns a human-readable message listing the denied IAM actions.
type PermissionResult ¶ added in v0.62.0
type PullSecretOp ¶ added in v0.63.0
type PullSecretOp struct {
DryRun bool
Logger *logrus.Logger
Out io.Writer
AllOK bool
PullSecretUpToDate bool
PullSecretUpdated bool
AuthDiffCount int
Failures []string
}
PullSecretOp carries context for pull secret operations. Each method checks DryRun and either performs the operation or reports what it would do.
func NewPullSecretOp ¶ added in v0.63.0
NewPullSecretOp creates a new operation context.
func (*PullSecretOp) CheckCanI ¶ added in v0.63.0
func (op *PullSecretOp) CheckCanI(ctx context.Context, clientset *kubernetes.Clientset, systemLabel, verb, resource, group, namespace string) bool
CheckCanI verifies RBAC permission. In dry-run mode it reports the result. In live mode it just logs the check. Returns whether the permission is allowed.
func (*PullSecretOp) CheckSecretExists ¶ added in v0.63.0
func (op *PullSecretOp) CheckSecretExists(ctx context.Context, clientset *kubernetes.Clientset, namespace, name, systemLabel string) bool
CheckSecretExists checks if a secret exists. Returns true if found.
func (*PullSecretOp) Fail ¶ added in v0.63.0
func (op *PullSecretOp) Fail(format string, args ...any)
Fail prints a failure result and marks the operation as not-all-OK.
func (*PullSecretOp) FetchAccessTokenOp ¶ added in v0.63.0
func (op *PullSecretOp) FetchAccessTokenOp(ocm *sdk.Connection, ownerUsername string) ([]byte, map[string]*amv1.AccessTokenAuth, bool)
FetchAccessTokenOp wraps FetchOwnerAccessToken with operational output.
func (*PullSecretOp) FindHiveNamespaceOp ¶ added in v0.63.0
func (op *PullSecretOp) FindHiveNamespaceOp(ctx context.Context, kubeCli client.Client, clusterID, infraName string) (*HiveNamespaceInfo, bool)
FindHiveNamespaceOp wraps FindHiveNamespace with operational output.
func (*PullSecretOp) Info ¶ added in v0.63.0
func (op *PullSecretOp) Info(format string, args ...any)
Info prints an informational message.
func (*PullSecretOp) OK ¶ added in v0.63.0
func (op *PullSecretOp) OK(format string, args ...any)
OK prints a success result.
func (*PullSecretOp) ResolveExistingPullSecret ¶ added in v0.63.0
func (op *PullSecretOp) ResolveExistingPullSecret(ctx context.Context, infraClientSet *kubernetes.Clientset, targetClientSet *kubernetes.Clientset, hiveNS string, infraName string, targetName string) ([]byte, string)
ResolveExistingPullSecret finds the best available base pull secret data. Tries the hive secret first, then falls back to the target cluster's secret. Returns the secret data bytes and the source description.
func (*PullSecretOp) Section ¶ added in v0.63.0
func (op *PullSecretOp) Section(step int, title string, lines ...string)
Section prints a step header with educational description.
func (*PullSecretOp) Warn ¶ added in v0.63.0
func (op *PullSecretOp) Warn(format string, args ...any)
Warn prints a warning.
func (*PullSecretOp) Would ¶ added in v0.63.0
func (op *PullSecretOp) Would(format string, args ...any)
Would prints what the operation would do (dry-run only).
type PullSecretVerifyResult ¶ added in v0.63.0
type PullSecretVerifyResult struct {
Matched int
Total int
Mismatches []string
AuthResults []AuthCheckResult
MissingRequired []string
}
PullSecretVerifyResult holds the outcome of a per-registry auth comparison.
func CompareAccessTokenAuthsToCluster ¶ added in v0.63.0
func CompareAccessTokenAuthsToCluster(ctx context.Context, clientset *kubernetes.Clientset, expectedAuths map[string]*amv1.AccessTokenAuth, out io.Writer) (*PullSecretVerifyResult, error)
CompareAccessTokenAuthsToCluster compares OCM access token auths against the pull secret on the target cluster. Writes per-registry results to out. Returns a PullSecretVerifyResult with match counts and any mismatches.
func CompareRegistryCredentialAuthsToCluster ¶ added in v0.63.0
func CompareRegistryCredentialAuthsToCluster(ctx context.Context, ocm *sdk.Connection, clientset *kubernetes.Clientset, accountID string, accountEmail string, out io.Writer) (*PullSecretVerifyResult, error)
CompareRegistryCredentialAuthsToCluster compares OCM registry credentials against the pull secret on the target cluster. Registry credentials use a different token format (base64-encoded "username:token") than access token auths.
type RotateSecretInput ¶
type RotateSecretInput struct {
// AccountCRName is the name of the Account CR.
AccountCRName string
// Account is the pre-fetched Account CR.
Account *awsv1alpha1.Account
// OsdManagedAdminUsername is an explicit admin username override.
// If empty, it is derived from the Account CR's iamUserId label.
OsdManagedAdminUsername string
// UpdateManagedAdminCreds controls whether osdManagedAdmin credentials are rotated.
UpdateManagedAdminCreds bool
// UpdateCcsCreds controls whether osdCcsAdmin credentials are also rotated.
UpdateCcsCreds bool
// AwsClient is the fully-authenticated AWS client with permissions in the
// target AWS account (after all role chaining has been completed).
AwsClient awsprovider.Client
// HiveKubeClient is the k8s client connected to the hive cluster.
HiveKubeClient client.Client
// ManagedClusterClient is the k8s client connected to the managed cluster
// (via backplane using the target OCM environment). Used to delete
// CredentialRequests so CCO recreates them with the new credentials.
ManagedClusterClient client.Client
// DryRun, when true, prints what actions would be taken without performing
// any mutating operations (no AWS key creation/deletion, no k8s resource
// creation/deletion/updates).
DryRun bool
// Report is the pre-computed diagnostic report from the snapshot phase.
// Used to display key/secret context during interactive key deletion.
Report *DiagnosticReport
// Log is the logger for operational messages (writes to stderr).
Log *logrus.Logger
// SkipPermissionCheck skips the managed-admin permission verification when
// the caller has already run diagnostics and the user confirmed despite failures.
SkipPermissionCheck bool
// In is the reader for interactive prompts (defaults to os.Stdin).
In io.Reader
// Out is the writer for structured report output (writes to stdout).
Out io.Writer
}
RotateSecretInput holds all resolved dependencies for secret rotation. The CLI layer is responsible for resolving AWS and k8s clients before calling RotateSecret.
type SecretStatus ¶ added in v0.62.0
type SimpleAuth ¶ added in v0.63.0
SimpleAuth holds a registry auth's token and email for generic comparison.
type ThreeWayAuthState ¶ added in v0.63.0
type ThreeWayAuthState struct {
Registry string
InOCM bool
InHive bool
InTarget bool
OCMMatchesHive bool
OCMMatchesTarget bool
HiveMatchesTarget bool
}
ThreeWayAuthState describes the sync state of a single auth entry across OCM, hive, and target.
type ThreeWayComparison ¶ added in v0.63.0
type ThreeWayComparison struct {
Auths []ThreeWayAuthState
HiveNeedsUpdate bool
TargetNeedsSync bool
AllInSync bool
}
ThreeWayComparison holds the full comparison result across OCM, hive, and target.
func CompareThreeWay ¶ added in v0.63.0
func CompareThreeWay(ocmAuths map[string]SimpleAuth, hiveData []byte, targetData []byte) (*ThreeWayComparison, error)
CompareThreeWay compares pull secret auths across OCM, hive secret, and target cluster secret. ocmAuths maps registry name → SimpleAuth with the expected auth/email values. hiveData and targetData are the raw .dockerconfigjson bytes from each secret.