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

Dynamically fetched capabilities from AMS instead of hard coded list #47

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
8 changes: 2 additions & 6 deletions cmd/ocm-support/create/capabilities/account_capability/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down
8 changes: 2 additions & 6 deletions cmd/ocm-support/delete/capabilities/account_capability/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down
105 changes: 29 additions & 76 deletions pkg/capability/capability.go
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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 {
Expand All @@ -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
}