Skip to content

Commit

Permalink
refactor: Refactor ocm methods out of register cmd file (#1807)
Browse files Browse the repository at this point in the history
* feat: addition of descriptions and examples to dedicated

* feat: Allows the CLI to install stage env addons when terraforming customer-cloud dataplane clusters

* refactor: extraction of clustermgmt funcs from register to own dir

* refactor: addresses cluster pagination and refactor of ocm functions
  • Loading branch information
dimakis authored Feb 20, 2023
1 parent 87f171d commit 57f89b8
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 135 deletions.
2 changes: 2 additions & 0 deletions docs/commands/rhoas_dedicated_register-cluster.md

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

2 changes: 1 addition & 1 deletion docs/commands/rhoas_kafka_create.md

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

158 changes: 26 additions & 132 deletions pkg/cmd/dedicated/register/registercluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package register
import (
"context"
"fmt"
"strings"

"github.com/redhat-developer/app-services-cli/internal/build"
"github.com/redhat-developer/app-services-cli/pkg/core/cmdutil"
"github.com/redhat-developer/app-services-cli/pkg/core/config"
"github.com/redhat-developer/app-services-cli/pkg/shared/connection/api/clustermgmt"
"strings"

"github.com/AlecAivazis/survey/v2"
clustersmgmtv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
Expand All @@ -27,7 +28,8 @@ type options struct {
selectedClusterMachinePool clustersmgmtv1.MachinePool
requestedMachinePoolNodeCount int
accessKafkasViaPrivateNetwork bool
// newMachinePool clustersmgmtv1.MachinePool
pageNumber int
pageSize int

f *factory.Factory
}
Expand Down Expand Up @@ -68,20 +70,22 @@ func NewRegisterClusterCommand(f *factory.Factory) *cobra.Command {
flags.StringVar(&opts.clusterManagementApiUrl, "cluster-mgmt-api-url", "", f.Localizer.MustLocalize("dedicated.registerCluster.flag.clusterMgmtApiUrl.description"))
flags.StringVar(&opts.accessToken, "access-token", "", f.Localizer.MustLocalize("dedicated.registercluster.flag.accessToken.description"))
flags.StringVar(&opts.selectedClusterId, "cluster-id", "", f.Localizer.MustLocalize("dedicated.registerCluster.flag.clusterId.description"))
flags.IntVar(&opts.pageNumber, "page-number", int(cmdutil.ConvertPageValueToInt32(build.DefaultPageNumber)), f.Localizer.MustLocalize("dedicated.registerCluster.flag.pageNumber.description"))
flags.IntVar(&opts.pageSize, "page-size", 100, f.Localizer.MustLocalize("dedicated.registerCluster.flag.pageSize.description"))

return cmd
}

func runRegisterClusterCmd(opts *options) (err error) {
// Set the base URL for the cluster management API
err = setListClusters(opts)
opts.pageNumber = int(cmdutil.ConvertPageValueToInt32(build.DefaultPageNumber))
err = getPaginatedClusterList(opts)
if err != nil {
return err
}
if len(opts.clusterList) == 0 {
return opts.f.Localizer.MustLocalizeError("dedicated.registerCluster.run.noClusterFound")
}
// TO-DO if client has supplied a cluster id, validate it and set it as the selected cluster without listing getting all clusters

if opts.selectedClusterId == "" {
err = runClusterSelectionInteractivePrompt(opts)
if err != nil {
Expand Down Expand Up @@ -112,37 +116,15 @@ func runRegisterClusterCmd(opts *options) (err error) {

}

func getClusterList(opts *options) (*clustersmgmtv1.ClusterList, error) {
conn, err := opts.f.Connection()
if err != nil {
return nil, err
}
client, cc, err := conn.API().OCMClustermgmt(opts.clusterManagementApiUrl, opts.accessToken)
if err != nil {
return nil, err
}
defer cc()
// TO-DO deal with pagination, validate clusters -- must be multi AZ and ready.
resource := client.Clusters().List()
response, err := resource.Send()
if err != nil {
return nil, err
}
clusters := response.Items()
return clusters, nil
}

func setListClusters(opts *options) error {
clusters, err := getClusterList(opts)
func getPaginatedClusterList(opts *options) error {
cl, err := clustermgmt.GetClusterList(opts.f, opts.accessToken, opts.clusterManagementApiUrl, opts.pageNumber, opts.pageSize)
if err != nil {
opts.f.Localizer.MustLocalizeError("dedicated.registerCluster.run.errorGettingClusterList")
return err
}
var cls = []clustersmgmtv1.Cluster{}
cls = validateClusters(clusters, cls)
opts.clusterList = cls
opts.clusterList = validateClusters(cl, opts.clusterList)
return nil
}

func validateClusters(clusters *clustersmgmtv1.ClusterList, cls []clustersmgmtv1.Cluster) []clustersmgmtv1.Cluster {
for _, cluster := range clusters.Slice() {
if cluster.State() == clusterReadyState && cluster.MultiAZ() == true {
Expand All @@ -153,14 +135,15 @@ func validateClusters(clusters *clustersmgmtv1.ClusterList, cls []clustersmgmtv1
}

func runClusterSelectionInteractivePrompt(opts *options) error {
// TO-DO handle in case of empty cluster list, must be cleared up with UX etc.
if len(opts.clusterList) == 0 {
return opts.f.Localizer.MustLocalizeError("dedicated.registerCluster.run.noClusterFound")
}
clusterStringList := make([]string, 0)
for i := range opts.clusterList {
cluster := opts.clusterList[i]
clusterStringList = append(clusterStringList, cluster.Name())
}

// TO-DO add page size
prompt := &survey.Select{
Message: opts.f.Localizer.MustLocalize("dedicated.registerCluster.prompt.selectCluster.message"),
Options: clusterStringList,
Expand Down Expand Up @@ -199,7 +182,7 @@ func parseDNSURL(opts *options) (string, error) {

func getOrCreateMachinePoolList(opts *options) error {
// ocm client connection
response, err := getMachinePoolList(opts)
response, err := clustermgmt.GetMachinePoolList(opts.f, opts.clusterManagementApiUrl, opts.accessToken, opts.selectedCluster.ID())
if err != nil {
return err
}
Expand All @@ -220,24 +203,6 @@ func getOrCreateMachinePoolList(opts *options) error {
return nil
}

func getMachinePoolList(opts *options) (*clustersmgmtv1.MachinePoolsListResponse, error) {
conn, err := opts.f.Connection()
if err != nil {
return nil, err
}
client, cc, err := conn.API().OCMClustermgmt(opts.clusterManagementApiUrl, opts.accessToken)
if err != nil {
return nil, err
}
defer cc()
resource := client.Clusters().Cluster(opts.selectedCluster.ID()).MachinePools().List()
response, err := resource.Send()
if err != nil {
return nil, err
}
return response, nil
}

func checkForValidMachinePoolLabels(machinePool *clustersmgmtv1.MachinePool) bool {
labels := machinePool.Labels()
for key, value := range labels {
Expand Down Expand Up @@ -295,30 +260,12 @@ func createMachinePoolRequestForDedicated(machinePoolNodeCount int) (*clustersmg
return machinePool, nil
}

// TO-DO this function should be moved to an ocm client / provider area
func createMachinePool(opts *options, mprequest *clustersmgmtv1.MachinePool) error {
conn, err := opts.f.Connection()
if err != nil {
return err
}
client, cc, err := conn.API().OCMClustermgmt(opts.clusterManagementApiUrl, opts.accessToken)
if err != nil {
return err
}
defer cc()
response, err := client.Clusters().Cluster(opts.selectedCluster.ID()).MachinePools().Add().Body(mprequest).Send()
if err != nil {
return err
}
opts.selectedClusterMachinePool = *response.Body()
return nil
}

func createMachinePoolInteractivePrompt(opts *options) error {
validator := &dedicatedcmdutil.Validator{
Localizer: opts.f.Localizer,
Connection: opts.f.Connection,
}

// TO-DO add page size and better help message
promptNodeCount := &survey.Input{
Message: opts.f.Localizer.MustLocalize("dedicated.registerCluster.prompt.createMachinePoolNodeCount.message"),
Expand All @@ -334,10 +281,12 @@ func createMachinePoolInteractivePrompt(opts *options) error {
if err != nil {
return err
}
err = createMachinePool(opts, dedicatedMachinePool)
mp := &clustersmgmtv1.MachinePool{}
mp, err = clustermgmt.CreateMachinePool(opts.f, opts.clusterManagementApiUrl, opts.accessToken, dedicatedMachinePool, opts.selectedCluster.ID())
if err != nil {
return err
}
opts.selectedClusterMachinePool = *mp
return nil
}

Expand All @@ -347,7 +296,7 @@ func validateMachinePoolNodes(opts *options) error {

machinePool := opts.existingMachinePoolList[i]

nodeCount := getMachinePoolNodeCount(&machinePool)
nodeCount := clustermgmt.GetMachinePoolNodeCount(&machinePool)

if validateMachinePoolNodeCount(nodeCount) &&
checkForValidMachinePoolLabels(&machinePool) &&
Expand All @@ -365,20 +314,6 @@ func validateMachinePoolNodes(opts *options) error {
return nil
}

func getMachinePoolNodeCount(machinePool *clustersmgmtv1.MachinePool) int {
var nodeCount int
replicas, ok := machinePool.GetReplicas()
if ok {
nodeCount = replicas
} else {
autoscaledReplicas, ok := machinePool.GetAutoscaling()
if ok {
nodeCount = autoscaledReplicas.MaxReplicas()
}
}
return nodeCount
}

func selectAccessPrivateNetworkInteractivePrompt(opts *options) error {
prompt := &survey.Confirm{
Message: opts.f.Localizer.MustLocalize("dedicated.registerCluster.prompt.selectPublicNetworkAccess.message"),
Expand All @@ -394,47 +329,6 @@ func selectAccessPrivateNetworkInteractivePrompt(opts *options) error {
return nil
}

func newAddonParameterListBuilder(params *[]kafkamgmtclient.FleetshardParameter) *clustersmgmtv1.AddOnInstallationParameterListBuilder {
if params == nil {
return nil
}
var items []*clustersmgmtv1.AddOnInstallationParameterBuilder
for _, p := range *params {
pb := clustersmgmtv1.NewAddOnInstallationParameter().ID(*p.Id).Value(*p.Value)
items = append(items, pb)
}
return clustersmgmtv1.NewAddOnInstallationParameterList().Items(items...)
}

func createAddonWithParams(opts *options, addonId string, params *[]kafkamgmtclient.FleetshardParameter) error {
// create a new addon via ocm
conn, err := opts.f.Connection()
if err != nil {
return err
}
client, cc, err := conn.API().OCMClustermgmt(opts.clusterManagementApiUrl, opts.accessToken)
if err != nil {
return err
}
defer cc()
addon := clustersmgmtv1.NewAddOn().ID(addonId)
addonParameters := newAddonParameterListBuilder(params)
addonInstallationBuilder := clustersmgmtv1.NewAddOnInstallation().Addon(addon)
if addonParameters != nil {
addonInstallationBuilder = addonInstallationBuilder.Parameters(addonParameters)
}
addonInstallation, err := addonInstallationBuilder.Build()
if err != nil {
return err
}
_, err = client.Clusters().Cluster(opts.selectedCluster.ID()).Addons().Add().Body(addonInstallation).Send()
if err != nil {
return err
}

return nil
}

func getStrimziAddonIdByEnv(con *config.Config) string {
if con.APIUrl == build.ProductionAPIURL {
return strimziAddonId
Expand All @@ -456,7 +350,7 @@ func registerClusterWithKasFleetManager(opts *options) error {
return err
}

nodeCount := getMachinePoolNodeCount(&opts.selectedClusterMachinePool)
nodeCount := clustermgmt.GetMachinePoolNodeCount(&opts.selectedClusterMachinePool)
kfmPayload := kafkamgmtclient.EnterpriseOsdClusterPayload{
AccessKafkasViaPrivateNetwork: opts.accessKafkasViaPrivateNetwork,
ClusterId: opts.selectedCluster.ID(),
Expand All @@ -479,11 +373,11 @@ func registerClusterWithKasFleetManager(opts *options) error {
if err != nil {
return err
}
err = createAddonWithParams(opts, getStrimziAddonIdByEnv(con), nil)
err = clustermgmt.CreateAddonWithParams(opts.f, opts.clusterManagementApiUrl, opts.accessToken, getStrimziAddonIdByEnv(con), response.FleetshardParameters, opts.selectedCluster.ID())
if err != nil {
return err
}
err = createAddonWithParams(opts, getKafkaFleetShardAddonIdByEnv(con), response.FleetshardParameters)
err = clustermgmt.CreateAddonWithParams(opts.f, opts.clusterManagementApiUrl, opts.accessToken, getKafkaFleetShardAddonIdByEnv(con), response.FleetshardParameters, opts.selectedCluster.ID())
if err != nil {
return err
}
Expand Down
10 changes: 8 additions & 2 deletions pkg/core/localize/locales/en/cmd/dedicated.en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ one = 'The ID of the OpenShift cluster to register:'
one = 'Select the ready cluster to register'

[dedicated.registerCluster.prompt.selectPublicNetworkAccess.message]
one = 'Would you like your Kafkas to be accessible via a public network?'
one = 'Would you like your Kafka instances to be accessible via a public network?'

[dedicated.registerCluster.prompt.selectPublicNetworkAccess.help]
one = 'If you select yes, your Kafka will be accessible via a public network'
Expand Down Expand Up @@ -72,4 +72,10 @@ one = 'The cluster has already been registered with Red Hat OpenShift Streams fo
one = 'The API URL of the OpenShift Cluster Management API.'

[dedicated.registercluster.flag.accessToken.description]
one = 'The access token to use to authenticate with the OpenShift Cluster Management API.'
one = 'The access token to use to authenticate with the OpenShift Cluster Management API.'

[dedicated.registerCluster.flag.pageNumber.description]
one = 'The page number to use when listing clusters.'

[dedicated.registerCluster.flag.pageSize.description]
one = 'The page size to use when listing clusters.'
Loading

0 comments on commit 57f89b8

Please sign in to comment.