From dfe68b89df053ec17dd49100c8717544ba2e74fc Mon Sep 17 00:00:00 2001 From: tithakka <tithakka@redhat.com> Date: Mon, 28 Aug 2023 16:49:53 -0700 Subject: [PATCH] Dynamically fetched capabilities from AMS instead of hard coded list --- .../capabilities/account_capability/cmd.go | 8 +- .../organization_capability/cmd.go | 8 +- .../subscription_capability/cmd.go | 8 +- .../capabilities/account_capability/cmd.go | 8 +- .../organization_capability/cmd.go | 8 +- .../subscription_capability/cmd.go | 8 +- pkg/capability/capability.go | 105 +++++------------- 7 files changed, 41 insertions(+), 112 deletions(-) diff --git a/cmd/ocm-support/create/capabilities/account_capability/cmd.go b/cmd/ocm-support/create/capabilities/account_capability/cmd.go index 054654e..e7d6422 100644 --- a/cmd/ocm-support/create/capabilities/account_capability/cmd.go +++ b/cmd/ocm-support/create/capabilities/account_capability/cmd.go @@ -34,7 +34,7 @@ var CmdCreateAccountCapability = &cobra.Command{ } //validates the capability capabilityKey := args[1] - err = capability.ValidateCapability(capabilityKey, "account") + err = capability.ValidateCapability(capabilityKey, "account", connection) if err != nil { return fmt.Errorf("%v", err) } @@ -50,11 +50,7 @@ func runCreateAccountCapability(cmd *cobra.Command, argv []string) error { if err != nil { return fmt.Errorf("failed to create OCM connection: %v", err) } - capabilityKey, err := capability.GetCapability(key, "account") - if err != nil { - return fmt.Errorf("failed to get capability: %v", err) - } - createdCapability, err := account.AddLabel(accountID, capabilityKey, "true", true, connection) + createdCapability, err := account.AddLabel(accountID, key, "true", true, connection) if err != nil { return fmt.Errorf("failed to create capability: %v", err) } diff --git a/cmd/ocm-support/create/capabilities/organization_capability/cmd.go b/cmd/ocm-support/create/capabilities/organization_capability/cmd.go index b127ef5..d53deb3 100644 --- a/cmd/ocm-support/create/capabilities/organization_capability/cmd.go +++ b/cmd/ocm-support/create/capabilities/organization_capability/cmd.go @@ -34,7 +34,7 @@ var CmdCreateOrganizationCapability = &cobra.Command{ } //validates the capability capabilityKey := args[1] - err = capability.ValidateCapability(capabilityKey, "organization") + err = capability.ValidateCapability(capabilityKey, "organization", connection) if err != nil { return fmt.Errorf("%v", err) } @@ -50,11 +50,7 @@ func runCreateOrganizationCapability(cmd *cobra.Command, argv []string) error { if err != nil { return fmt.Errorf("failed to create OCM connection: %v", err) } - capabilityKey, err := capability.GetCapability(key, "organization") - if err != nil { - return fmt.Errorf("failed to get capability: %v", err) - } - createdCapability, err := organization.AddLabel(organizationID, capabilityKey, "true", true, connection) + createdCapability, err := organization.AddLabel(organizationID, key, "true", true, connection) if err != nil { return fmt.Errorf("failed to create capability: %v", err) } diff --git a/cmd/ocm-support/create/capabilities/subscription_capability/cmd.go b/cmd/ocm-support/create/capabilities/subscription_capability/cmd.go index cd7f732..616367f 100644 --- a/cmd/ocm-support/create/capabilities/subscription_capability/cmd.go +++ b/cmd/ocm-support/create/capabilities/subscription_capability/cmd.go @@ -34,7 +34,7 @@ var CmdCreateSubscriptionCapability = &cobra.Command{ } //validates the capability capabilityKey := args[1] - err = capability.ValidateCapability(capabilityKey, "cluster") + err = capability.ValidateCapability(capabilityKey, "cluster", connection) if err != nil { return fmt.Errorf("%v", err) } @@ -50,11 +50,7 @@ func runCreateSubscriptionCapability(cmd *cobra.Command, argv []string) error { if err != nil { return fmt.Errorf("failed to create OCM connection: %v", err) } - capabilityKey, err := capability.GetCapability(key, "cluster") - if err != nil { - return fmt.Errorf("failed to get capability: %v", err) - } - createdCapability, err := subscription.AddLabel(subscriptionID, capabilityKey, "true", true, connection) + createdCapability, err := subscription.AddLabel(subscriptionID, key, "true", true, connection) if err != nil { return fmt.Errorf("failed to create capability: %v", err) } diff --git a/cmd/ocm-support/delete/capabilities/account_capability/cmd.go b/cmd/ocm-support/delete/capabilities/account_capability/cmd.go index b104473..9bd17bc 100644 --- a/cmd/ocm-support/delete/capabilities/account_capability/cmd.go +++ b/cmd/ocm-support/delete/capabilities/account_capability/cmd.go @@ -32,7 +32,7 @@ var CmdDeleteAccountCapability = &cobra.Command{ return fmt.Errorf("%v", err) } //validates the capability - err = capability.ValidateCapability(capabilityKey, "account") + err = capability.ValidateCapability(capabilityKey, "account", connection) if err != nil { return fmt.Errorf("%v", err) } @@ -48,11 +48,7 @@ func runDeleteAccountCapability(cmd *cobra.Command, argv []string) error { if err != nil { return fmt.Errorf("failed to create OCM connection: %v", err) } - capabilityKey, err := capability.GetCapability(key, "account") - if err != nil { - return fmt.Errorf("failed to get capability: %v", err) - } - err = account.DeleteLabel(accountID, capabilityKey, connection) + err = account.DeleteLabel(accountID, key, connection) if err != nil { return fmt.Errorf("failed to delete capability: %v", err) } diff --git a/cmd/ocm-support/delete/capabilities/organization_capability/cmd.go b/cmd/ocm-support/delete/capabilities/organization_capability/cmd.go index a1a67eb..f44e838 100644 --- a/cmd/ocm-support/delete/capabilities/organization_capability/cmd.go +++ b/cmd/ocm-support/delete/capabilities/organization_capability/cmd.go @@ -32,7 +32,7 @@ var CmdDeleteOrganizationCapability = &cobra.Command{ return fmt.Errorf("%v", err) } //validates the capability - err = capability.ValidateCapability(capabilityKey, "organization") + err = capability.ValidateCapability(capabilityKey, "organization", connection) if err != nil { return fmt.Errorf("%v", err) } @@ -48,11 +48,7 @@ func runDeleteOrganizationCapability(cmd *cobra.Command, argv []string) error { if err != nil { return fmt.Errorf("failed to create OCM connection: %v", err) } - capabilityKey, err := capability.GetCapability(key, "organization") - if err != nil { - return fmt.Errorf("failed to get capability: %v", err) - } - err = organization.DeleteLabel(orgID, capabilityKey, connection) + err = organization.DeleteLabel(orgID, key, connection) if err != nil { return fmt.Errorf("failed to delete capability: %v", err) } diff --git a/cmd/ocm-support/delete/capabilities/subscription_capability/cmd.go b/cmd/ocm-support/delete/capabilities/subscription_capability/cmd.go index 35e4f3b..e6013e1 100644 --- a/cmd/ocm-support/delete/capabilities/subscription_capability/cmd.go +++ b/cmd/ocm-support/delete/capabilities/subscription_capability/cmd.go @@ -32,7 +32,7 @@ var CmdDeleteSubscriptionCapability = &cobra.Command{ return fmt.Errorf("%v", err) } //validates the capability - err = capability.ValidateCapability(capabilityKey, "cluster") + err = capability.ValidateCapability(capabilityKey, "cluster", connection) if err != nil { return fmt.Errorf("%v", err) } @@ -48,11 +48,7 @@ func runDeleteSubscriptionCapability(cmd *cobra.Command, argv []string) error { if err != nil { return fmt.Errorf("failed to create OCM connection: %v", err) } - capabilityKey, err := capability.GetCapability(key, "cluster") - if err != nil { - return fmt.Errorf("failed to get capability: %v", err) - } - err = subscription.DeleteLabel(subscriptionID, capabilityKey, connection) + err = subscription.DeleteLabel(subscriptionID, key, connection) if err != nil { return fmt.Errorf("failed to delete capability: %v", err) } diff --git a/pkg/capability/capability.go b/pkg/capability/capability.go index 75053d9..58242f0 100644 --- a/pkg/capability/capability.go +++ b/pkg/capability/capability.go @@ -1,7 +1,9 @@ package capability import ( + "context" "fmt" + sdk "github.com/openshift-online/ocm-sdk-go" "strings" v1 "github.com/openshift-online/ocm-sdk-go/accountsmgmt/v1" @@ -15,64 +17,6 @@ type Capability struct { type CapabilityList []Capability -// Capabilities must contain 3 sections, separated by "." -// capability.{type}.{name} -const CapabilityAggressiveClusterSetup = "capability.account.aggressive_cluster_cleanup" -const CapabilityCreateMoaClusters = "capability.account.create_moa_clusters" -const CapabilityManageClusterAdmin = "capability.cluster.manage_cluster_admin" -const CapabilityOrganizationRegistrationsPerHour = "capability.organization.clusters_registrations_per_hour" -const CapabilityOrganizationPinClusterToShard = "capability.organization.pin_cluster_to_shard" -const CapabilityHibernateCluster = "capability.organization.hibernate_cluster" -const CapabilitySubscribedOcp = "capability.cluster.subscribed_ocp" -const CapabilitySubscribedOcpMarketplace = "capability.cluster.subscribed_ocp_marketplace" -const CapabilitySubscribedOsdMarketplace = "capability.cluster.subscribed_osd_marketplace" -const CapabilityEnableTermsEnforcement = "capability.account.enable_terms_enforcement" -const CapabilityBareMetalInstallerAdmin = "capability.account.bare_metal_installer_admin" -const CapabilityReleaseOcpClusters = "capability.cluster.release_ocp_clusters" -const CapabilityAutoscaleClustersDeprecated = "capability.organization.autoscale_clusters" -const CapabilityAutoscaleClusters = "capability.cluster.autoscale_clusters" -const CapabilityOrganizationInstallConfigOverride = "capability.organization.install_config_override" -const CapabilityOrganizationInstallConfigDefault = "capability.organization.install_config_default" -const CapabilityOrganizationOverrideOsdTrialLength = "capability.organization.override_osdtrial_length_days" -const CapabilityOrganizationCreateClusterProxy = "capability.organization.create_cluster_proxy" -const CapabilityAllowGCPNonCCSPrivateClusters = "capability.organization.create_gcp_non_ccs_cluster" -const CapabilityAllowInstallEOLVersions = "capability.organization.allow_install_eol_versions" -const CapabilityAddOnVersionSelect = "capability.organization.addon_version_select" -const CapabilityOrganizationFipsCluster = "capability.organization.fips_cluster" -const CapabilityOrganizationOvnCluster = "capability.organization.ovn_cluster" -const CapabilityOrganizationHyperShift = "capability.organization.hypershift" -const CapabilityBypassMaxExpiration = "capability.organization.bypass_max_expiration" -const CapabilityUseRosaPaidAMI = "capability.account.use_rosa_paid_ami" - -var availableCapabilities map[string]string = map[string]string{ - "AggressiveClusterSetup": CapabilityAggressiveClusterSetup, - "CreateMoaClusters": CapabilityCreateMoaClusters, - "ManageClusterAdmin": CapabilityManageClusterAdmin, - "OrganizationRegistrationsPerHour": CapabilityOrganizationRegistrationsPerHour, - "OrganizationPinClusterToShard": CapabilityOrganizationPinClusterToShard, - "HibernateCluster": CapabilityHibernateCluster, - "SubscribedOcp": CapabilitySubscribedOcp, - "SubscribedOcpMarketplace": CapabilitySubscribedOcpMarketplace, - "SubscribedOsdMarketplace": CapabilitySubscribedOsdMarketplace, - "EnableTermsEnforcement": CapabilityEnableTermsEnforcement, - "BareMetalInstallerAdmin": CapabilityBareMetalInstallerAdmin, - "ReleaseOcpClusters": CapabilityReleaseOcpClusters, - "AutoscaleClustersDeprecated": CapabilityAutoscaleClustersDeprecated, - "AutoscaleClusters": CapabilityAutoscaleClusters, - "OrganizationInstallConfigOverride": CapabilityOrganizationInstallConfigOverride, - "OrganizationInstallConfigDefault": CapabilityOrganizationInstallConfigDefault, - "OrganizationOverrideOsdTrialLength": CapabilityOrganizationOverrideOsdTrialLength, - "OrganizationCreateClusterProxy": CapabilityOrganizationCreateClusterProxy, - "AllowGCPNonCCSPrivateClusters": CapabilityAllowGCPNonCCSPrivateClusters, - "AllowInstallEOLVersions": CapabilityAllowInstallEOLVersions, - "AddOnVersionSelect": CapabilityAddOnVersionSelect, - "OrganizationFipsCluster": CapabilityOrganizationFipsCluster, - "OrganizationOvnCluster": CapabilityOrganizationOvnCluster, - "OrganizationHyperShift": CapabilityOrganizationHyperShift, - "BypassMaxExpiration": CapabilityBypassMaxExpiration, - "UseRosaPaidAMI": CapabilityUseRosaPaidAMI, -} - func PresentCapabilities(capabilities []*v1.Capability) CapabilityList { var capabilitiesList []Capability for _, capability := range capabilities { @@ -86,33 +30,42 @@ func PresentCapabilities(capabilities []*v1.Capability) CapabilityList { return capabilitiesList } -func ValidateCapability(capability string, resourceType string) error { - val, ok := availableCapabilities[capability] - if !ok { - capabilities := GetResourceTypeSpecificCapabilities(resourceType) - return fmt.Errorf("capability not available for '%s'. Available capabilities are '%v'", resourceType, capabilities) +func ValidateCapability(capability string, resourceType string, conn *sdk.Connection) error { + availableCapabilities, err := GetCapabilities(conn) + if err != nil { + return err + } + var availableCapabilityNames []string + for _, availableCapability := range availableCapabilities { + availableCapabilityNames = append(availableCapabilityNames, availableCapability.Name()) + } + for _, availableCap := range availableCapabilityNames { + if availableCap == capability { + return nil + } } - if strings.Split(val, ".")[1] != resourceType { - capabilities := GetResourceTypeSpecificCapabilities(resourceType) - return fmt.Errorf("capability not available for '%s'. Available capabilities are '%v'", resourceType, capabilities) + resourceSpecificCapabilities := GetResourceTypeSpecificCapabilities(resourceType, availableCapabilities) + if len(resourceSpecificCapabilities) == 0 { + return fmt.Errorf("capability not available for '%s'. Available capabilities are '%v'", resourceType, availableCapabilities) } - return nil + return fmt.Errorf("capability not available for '%s'. Available capabilities are '%v'", resourceType, resourceSpecificCapabilities) } -func GetResourceTypeSpecificCapabilities(resourceType string) []string { +func GetResourceTypeSpecificCapabilities(resourceType string, availableCapabilities []*v1.Capability) []string { var capabilities []string - for key, val := range availableCapabilities { - if strings.Split(val, ".")[1] == resourceType { - capabilities = append(capabilities, key) + for _, val := range availableCapabilities { + if strings.Split(val.Value(), ".")[1] == resourceType { + capabilities = append(capabilities, val.Name()) } } return capabilities } -func GetCapability(capability string, resourceType string) (string, error) { - if err := ValidateCapability(capability, resourceType); err != nil { - return "", err +func GetCapabilities(conn *sdk.Connection) ([]*v1.Capability, error) { + ctx := context.Background() + capabilities, err := conn.AccountsMgmt().V1().Capabilities().List().SendContext(ctx) + if err != nil { + return nil, err } - val := availableCapabilities[capability] - return val, nil + return capabilities.Items().Slice(), nil }