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

refactor: Refactor ocm methods out of register cmd file #1807

Merged
merged 4 commits into from
Feb 20, 2023
Merged
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
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Suggesting to use variable names page and size, since that's what we use for most of the commands.

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"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Struck me while reviewing a different PR, why is the page size 100 here?
Can we use buid.defaultpagesize here? 100 might be too large.


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