From dba48c1f0c16f6b1f684467be5a697d9718a5179 Mon Sep 17 00:00:00 2001 From: Goutham Muguluvalli Niranjan <31833540+gouthamMN@users.noreply.github.com> Date: Tue, 5 Sep 2023 13:56:27 -0500 Subject: [PATCH] Add worker profile status (#3053) * add workerProfilesStatus field to hold the enriched worker profile data * update swagger * swagger examples * update clients * resolve golint * update defaults * validate worker Profile status is nil in input request * make client changes after rebase * rebase * update workerProfiles references and UTs * fix golint errors * remove duplicate logic of verifing workerProfilesStatus not nil --------- Co-authored-by: gniranjan --- .sha256sum | 2 +- pkg/api/admin/openshiftcluster.go | 57 ++++++++++--------- pkg/api/admin/openshiftcluster_convert.go | 29 ++++++++++ pkg/api/defaults.go | 6 ++ pkg/api/defaults_test.go | 5 ++ pkg/api/openshiftcluster.go | 13 +++++ pkg/api/openshiftclusterdocument_example.go | 23 ++++++++ pkg/api/util/subnet/subnet.go | 4 +- pkg/api/util/subnet/subnet_test.go | 17 ++++++ .../openshiftcluster_convert.go | 11 +++- .../openshiftcluster_example.go | 1 + pkg/api/v20200430/openshiftcluster_convert.go | 11 +++- pkg/api/v20200430/openshiftcluster_example.go | 1 + .../openshiftcluster_convert.go | 11 +++- .../openshiftcluster_example.go | 1 + pkg/api/v20220401/openshiftcluster_convert.go | 11 +++- pkg/api/v20220401/openshiftcluster_example.go | 1 + pkg/api/v20220904/openshiftcluster_convert.go | 11 +++- pkg/api/v20220904/openshiftcluster_example.go | 1 + pkg/api/v20230401/openshiftcluster_convert.go | 11 +++- pkg/api/v20230401/openshiftcluster_example.go | 1 + .../openshiftcluster_convert.go | 11 +++- .../openshiftcluster_example.go | 1 + pkg/api/v20230904/openshiftcluster.go | 3 + pkg/api/v20230904/openshiftcluster_convert.go | 35 +++++++++++- pkg/api/v20230904/openshiftcluster_example.go | 20 +++++-- .../openshiftcluster_validatestatic.go | 3 + .../openshiftcluster_validatestatic_test.go | 16 ++++++ .../mgmt/2023-09-04/redhatopenshift/models.go | 35 ++++++++++++ pkg/cluster/deploybaseresources.go | 4 +- pkg/cluster/deploybaseresources_additional.go | 4 +- pkg/cluster/ensureendpoints.go | 5 +- pkg/cluster/ipaddresses.go | 5 +- pkg/cluster/ipaddresses_test.go | 46 +++++++++++++++ pkg/cluster/storageaccounts.go | 4 +- pkg/cluster/storageclass.go | 8 ++- pkg/cluster/storageclass_test.go | 17 ++++++ pkg/frontend/adminactions/resources_list.go | 5 +- pkg/frontend/openshiftcluster_putorpatch.go | 3 + pkg/frontend/quota_validation.go | 4 +- pkg/frontend/sku_test.go | 21 +++++++ pkg/frontend/sku_validation.go | 4 +- pkg/swagger/examples.go | 11 +++- pkg/swagger/generator.go | 39 +++++++------ pkg/swagger/typewalker.go | 3 + pkg/util/clusterdata/worker_profile.go | 4 +- pkg/util/clusterdata/worker_profile_test.go | 2 +- pkg/validate/dynamic/diskencryptionset.go | 6 +- .../dynamic/diskencryptionset_test.go | 25 ++++++++ pkg/validate/dynamic/encryptionathost.go | 5 +- pkg/validate/dynamic/encryptionathost_test.go | 29 ++++++++++ .../openshiftcluster_validatedynamic.go | 6 +- .../v2023_09_04/models/_models.py | 12 ++++ .../v2023_09_04/models/_models_py3.py | 12 ++++ .../examples/OpenShiftClusters_Get.json | 23 ++++++++ .../examples/OpenShiftClusters_List.json | 23 ++++++++ ...OpenShiftClusters_ListByResourceGroup.json | 23 ++++++++ .../stable/2023-09-04/redhatopenshift.json | 15 +++-- 58 files changed, 629 insertions(+), 91 deletions(-) diff --git a/.sha256sum b/.sha256sum index 6370c91994b..39368fd9c13 100644 --- a/.sha256sum +++ b/.sha256sum @@ -4,4 +4,4 @@ 1d167031baf0209fe8c46df9654585c64e8cc9a0c89555d7479c4ed6dc150251 swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/redhatopenshift.json 622404e8311c62f27fba778e30e760bb1901e5bd221b23de72f449cafbdf0c45 swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-04-01/redhatopenshift.json 3aede70b183bad612c23cb776fe5a932c5709334e1fe1ad7ff8772b58be3661f swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/preview/2023-07-01-preview/redhatopenshift.json -0c2bfc4b4308ff10d3cdd1c66c1356ba4153342ce536d478bcbb515fa1fe5958 swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/redhatopenshift.json +3127f0a6acebf9ce09623df69dbd88824384b58967fe36c19acf2e2cf34c46b2 swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/redhatopenshift.json diff --git a/pkg/api/admin/openshiftcluster.go b/pkg/api/admin/openshiftcluster.go index 261fbe8099a..79f4c3b87be 100644 --- a/pkg/api/admin/openshiftcluster.go +++ b/pkg/api/admin/openshiftcluster.go @@ -28,33 +28,36 @@ type OpenShiftCluster struct { // OpenShiftClusterProperties represents an OpenShift cluster's properties. type OpenShiftClusterProperties struct { - ArchitectureVersion ArchitectureVersion `json:"architectureVersion"` // ArchitectureVersion is int so 0 is valid value to be returned - ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` - LastProvisioningState ProvisioningState `json:"lastProvisioningState,omitempty"` - FailedProvisioningState ProvisioningState `json:"failedProvisioningState,omitempty"` - LastAdminUpdateError string `json:"lastAdminUpdateError,omitempty"` - MaintenanceTask MaintenanceTask `json:"maintenanceTask,omitempty" mutable:"true"` - OperatorFlags OperatorFlags `json:"operatorFlags,omitempty" mutable:"true"` - OperatorVersion string `json:"operatorVersion,omitempty" mutable:"true"` - CreatedAt time.Time `json:"createdAt,omitempty"` - CreatedBy string `json:"createdBy,omitempty"` - ProvisionedBy string `json:"provisionedBy,omitempty"` - ClusterProfile ClusterProfile `json:"clusterProfile,omitempty"` - FeatureProfile FeatureProfile `json:"featureProfile,omitempty"` - ConsoleProfile ConsoleProfile `json:"consoleProfile,omitempty"` - ServicePrincipalProfile ServicePrincipalProfile `json:"servicePrincipalProfile,omitempty"` - NetworkProfile NetworkProfile `json:"networkProfile,omitempty"` - MasterProfile MasterProfile `json:"masterProfile,omitempty"` - WorkerProfiles []WorkerProfile `json:"workerProfiles,omitempty"` - APIServerProfile APIServerProfile `json:"apiserverProfile,omitempty"` - IngressProfiles []IngressProfile `json:"ingressProfiles,omitempty"` - Install *Install `json:"install,omitempty"` - StorageSuffix string `json:"storageSuffix,omitempty"` - RegistryProfiles []RegistryProfile `json:"registryProfiles,omitempty"` - ImageRegistryStorageAccountName string `json:"imageRegistryStorageAccountName,omitempty"` - InfraID string `json:"infraId,omitempty"` - HiveProfile HiveProfile `json:"hiveProfile,omitempty"` - PucmPending bool `json:"pucmPending,omitempty"` + ArchitectureVersion ArchitectureVersion `json:"architectureVersion"` // ArchitectureVersion is int so 0 is valid value to be returned + ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` + LastProvisioningState ProvisioningState `json:"lastProvisioningState,omitempty"` + FailedProvisioningState ProvisioningState `json:"failedProvisioningState,omitempty"` + LastAdminUpdateError string `json:"lastAdminUpdateError,omitempty"` + MaintenanceTask MaintenanceTask `json:"maintenanceTask,omitempty" mutable:"true"` + OperatorFlags OperatorFlags `json:"operatorFlags,omitempty" mutable:"true"` + OperatorVersion string `json:"operatorVersion,omitempty" mutable:"true"` + CreatedAt time.Time `json:"createdAt,omitempty"` + CreatedBy string `json:"createdBy,omitempty"` + ProvisionedBy string `json:"provisionedBy,omitempty"` + ClusterProfile ClusterProfile `json:"clusterProfile,omitempty"` + FeatureProfile FeatureProfile `json:"featureProfile,omitempty"` + ConsoleProfile ConsoleProfile `json:"consoleProfile,omitempty"` + ServicePrincipalProfile ServicePrincipalProfile `json:"servicePrincipalProfile,omitempty"` + NetworkProfile NetworkProfile `json:"networkProfile,omitempty"` + MasterProfile MasterProfile `json:"masterProfile,omitempty"` + // WorkerProfiles is used to store the worker profile data that was sent in the api request + WorkerProfiles []WorkerProfile `json:"workerProfiles,omitempty"` + // WorkerProfilesStatus is used to store the enriched worker profile data + WorkerProfilesStatus []WorkerProfile `json:"workerProfilesStatus,omitempty"` + APIServerProfile APIServerProfile `json:"apiserverProfile,omitempty"` + IngressProfiles []IngressProfile `json:"ingressProfiles,omitempty"` + Install *Install `json:"install,omitempty"` + StorageSuffix string `json:"storageSuffix,omitempty"` + RegistryProfiles []RegistryProfile `json:"registryProfiles,omitempty"` + ImageRegistryStorageAccountName string `json:"imageRegistryStorageAccountName,omitempty"` + InfraID string `json:"infraId,omitempty"` + HiveProfile HiveProfile `json:"hiveProfile,omitempty"` + PucmPending bool `json:"pucmPending,omitempty"` } // ProvisioningState represents a provisioning state. diff --git a/pkg/api/admin/openshiftcluster_convert.go b/pkg/api/admin/openshiftcluster_convert.go index 42e17d5a8a0..cefd30798d5 100644 --- a/pkg/api/admin/openshiftcluster_convert.go +++ b/pkg/api/admin/openshiftcluster_convert.go @@ -131,6 +131,21 @@ func (c openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfac } } + if oc.Properties.WorkerProfilesStatus != nil { + out.Properties.WorkerProfilesStatus = make([]WorkerProfile, 0, len(oc.Properties.WorkerProfilesStatus)) + for _, p := range oc.Properties.WorkerProfilesStatus { + out.Properties.WorkerProfilesStatus = append(out.Properties.WorkerProfilesStatus, WorkerProfile{ + Name: p.Name, + VMSize: VMSize(p.VMSize), + DiskSizeGB: p.DiskSizeGB, + SubnetID: p.SubnetID, + Count: p.Count, + EncryptionAtHost: EncryptionAtHost(p.EncryptionAtHost), + DiskEncryptionSetID: p.DiskEncryptionSetID, + }) + } + } + if oc.Properties.IngressProfiles != nil { out.Properties.IngressProfiles = make([]IngressProfile, 0, len(oc.Properties.IngressProfiles)) for _, p := range oc.Properties.IngressProfiles { @@ -285,6 +300,20 @@ func (c openShiftClusterConverter) ToInternal(_oc interface{}, out *api.OpenShif out.Properties.WorkerProfiles[i].DiskEncryptionSetID = oc.Properties.WorkerProfiles[i].DiskEncryptionSetID } } + if oc.Properties.WorkerProfilesStatus != nil { + out.Properties.WorkerProfilesStatus = make([]api.WorkerProfile, len(oc.Properties.WorkerProfilesStatus)) + for _, p := range oc.Properties.WorkerProfilesStatus { + out.Properties.WorkerProfilesStatus = append(out.Properties.WorkerProfilesStatus, api.WorkerProfile{ + Name: p.Name, + VMSize: api.VMSize(p.VMSize), + DiskSizeGB: p.DiskSizeGB, + SubnetID: p.SubnetID, + Count: p.Count, + EncryptionAtHost: api.EncryptionAtHost(p.EncryptionAtHost), + DiskEncryptionSetID: p.DiskEncryptionSetID, + }) + } + } out.Properties.APIServerProfile.Visibility = api.Visibility(oc.Properties.APIServerProfile.Visibility) out.Properties.APIServerProfile.URL = oc.Properties.APIServerProfile.URL out.Properties.APIServerProfile.IP = oc.Properties.APIServerProfile.IP diff --git a/pkg/api/defaults.go b/pkg/api/defaults.go index 72d2c229297..55ea87dee0f 100644 --- a/pkg/api/defaults.go +++ b/pkg/api/defaults.go @@ -21,6 +21,12 @@ func SetDefaults(doc *OpenShiftClusterDocument) { } } + for i, wp := range doc.OpenShiftCluster.Properties.WorkerProfilesStatus { + if wp.EncryptionAtHost == "" { + doc.OpenShiftCluster.Properties.WorkerProfilesStatus[i].EncryptionAtHost = EncryptionAtHostDisabled + } + } + if doc.OpenShiftCluster.Properties.ClusterProfile.FipsValidatedModules == "" { doc.OpenShiftCluster.Properties.ClusterProfile.FipsValidatedModules = FipsValidatedModulesDisabled } diff --git a/pkg/api/defaults_test.go b/pkg/api/defaults_test.go index 03c12c9834f..5dbe7d0b00c 100644 --- a/pkg/api/defaults_test.go +++ b/pkg/api/defaults_test.go @@ -31,6 +31,11 @@ func validOpenShiftClusterDocument() *OpenShiftClusterDocument { EncryptionAtHost: EncryptionAtHostDisabled, }, }, + WorkerProfilesStatus: []WorkerProfile{ + { + EncryptionAtHost: EncryptionAtHostDisabled, + }, + }, ClusterProfile: ClusterProfile{ FipsValidatedModules: FipsValidatedModulesDisabled, }, diff --git a/pkg/api/openshiftcluster.go b/pkg/api/openshiftcluster.go index 684b8b07893..fd8a4da8581 100644 --- a/pkg/api/openshiftcluster.go +++ b/pkg/api/openshiftcluster.go @@ -126,8 +126,12 @@ type OpenShiftClusterProperties struct { MasterProfile MasterProfile `json:"masterProfile,omitempty"` + // WorkerProfiles is used to store the worker profile data that was sent in the api request WorkerProfiles []WorkerProfile `json:"workerProfiles,omitempty"` + // WorkerProfilesStatus is used to store the enriched worker profile data + WorkerProfilesStatus []WorkerProfile `json:"workerProfilesStatus,omitempty"` + APIServerProfile APIServerProfile `json:"apiserverProfile,omitempty"` IngressProfiles []IngressProfile `json:"ingressProfiles,omitempty"` @@ -632,6 +636,15 @@ type WorkerProfile struct { DiskEncryptionSetID string `json:"diskEncryptionSetId,omitempty"` } +// GetEnrichedWorkerProfiles returns WorkerProfilesStatus if not nil, otherwise WorkerProfiles +// with their respective json property name +func GetEnrichedWorkerProfiles(ocp OpenShiftClusterProperties) ([]WorkerProfile, string) { + if ocp.WorkerProfilesStatus != nil { + return ocp.WorkerProfilesStatus, "workerProfilesStatus" + } + return ocp.WorkerProfiles, "workerProfiles" +} + // APIServerProfile represents an API server profile type APIServerProfile struct { MissingFields diff --git a/pkg/api/openshiftclusterdocument_example.go b/pkg/api/openshiftclusterdocument_example.go index fd6cd8f4815..3f2de969ab9 100644 --- a/pkg/api/openshiftclusterdocument_example.go +++ b/pkg/api/openshiftclusterdocument_example.go @@ -67,6 +67,29 @@ func ExampleOpenShiftClusterDocument() *OpenShiftClusterDocument { Count: 3, }, }, + WorkerProfilesStatus: []WorkerProfile{ + { + Name: "worker1", + VMSize: VMSizeStandardD2sV3, + DiskSizeGB: 128, + SubnetID: "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + Count: 1, + }, + { + Name: "worker2", + VMSize: VMSizeStandardD2sV3, + DiskSizeGB: 128, + SubnetID: "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + Count: 1, + }, + { + Name: "worker3", + VMSize: VMSizeStandardD2sV3, + DiskSizeGB: 128, + SubnetID: "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + Count: 1, + }, + }, APIServerProfile: APIServerProfile{ Visibility: VisibilityPublic, URL: "https://api.cluster.location.aroapp.io:6443/", diff --git a/pkg/api/util/subnet/subnet.go b/pkg/api/util/subnet/subnet.go index 2e2f506d514..be58f8ad6ee 100644 --- a/pkg/api/util/subnet/subnet.go +++ b/pkg/api/util/subnet/subnet.go @@ -33,7 +33,9 @@ func NetworkSecurityGroupID(oc *api.OpenShiftCluster, subnetID string) (string, infraID = "aro" } isWorkerSubnet := false - for _, s := range oc.Properties.WorkerProfiles { + workerProfiles, _ := api.GetEnrichedWorkerProfiles(oc.Properties) + + for _, s := range workerProfiles { if strings.EqualFold(subnetID, s.SubnetID) { isWorkerSubnet = true break diff --git a/pkg/api/util/subnet/subnet_test.go b/pkg/api/util/subnet/subnet_test.go index 80034381e2e..945874cd94b 100644 --- a/pkg/api/util/subnet/subnet_test.go +++ b/pkg/api/util/subnet/subnet_test.go @@ -32,6 +32,7 @@ func TestNetworkSecurityGroupID(t *testing.T) { infraID string archVersion api.ArchitectureVersion subnetID string + wpStatus bool wantNSGID string wantErr string }{ @@ -64,11 +65,27 @@ func TestNetworkSecurityGroupID(t *testing.T) { archVersion: api.ArchitectureVersion(42), wantErr: `unknown architecture version 42`, }, + { + name: "worker arch v2 to use enriched worker Profile", + infraID: "test-1234", + archVersion: api.ArchitectureVersionV2, + wpStatus: true, + subnetID: "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/Enrichedworker", + wantNSGID: "/subscriptions/subscriptionId/resourceGroups/clusterResourceGroup/providers/Microsoft.Network/networkSecurityGroups/test-1234-nsg", + }, } { t.Run(tt.name, func(t *testing.T) { oc.Properties.InfraID = tt.infraID oc.Properties.ArchitectureVersion = tt.archVersion + if tt.wpStatus { + oc.Properties.WorkerProfilesStatus = []api.WorkerProfile{ + { + SubnetID: "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/Enrichedworker", + }, + } + } + nsgID, err := NetworkSecurityGroupID(oc, tt.subnetID) utilerror.AssertErrorMessage(t, err, tt.wantErr) diff --git a/pkg/api/v20191231preview/openshiftcluster_convert.go b/pkg/api/v20191231preview/openshiftcluster_convert.go index 590efd4753b..c58d15744d5 100644 --- a/pkg/api/v20191231preview/openshiftcluster_convert.go +++ b/pkg/api/v20191231preview/openshiftcluster_convert.go @@ -51,8 +51,15 @@ func (c openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfac } if oc.Properties.WorkerProfiles != nil { - out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(oc.Properties.WorkerProfiles)) - for _, p := range oc.Properties.WorkerProfiles { + workerProfiles := oc.Properties.WorkerProfiles + + // Use enriched worker profile data when available + if oc.Properties.WorkerProfilesStatus != nil { + workerProfiles = oc.Properties.WorkerProfilesStatus + } + + out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(workerProfiles)) + for _, p := range workerProfiles { out.Properties.WorkerProfiles = append(out.Properties.WorkerProfiles, WorkerProfile{ Name: p.Name, VMSize: VMSize(p.VMSize), diff --git a/pkg/api/v20191231preview/openshiftcluster_example.go b/pkg/api/v20191231preview/openshiftcluster_example.go index a70273e5bf4..8aebcf8b6b8 100644 --- a/pkg/api/v20191231preview/openshiftcluster_example.go +++ b/pkg/api/v20191231preview/openshiftcluster_example.go @@ -9,6 +9,7 @@ import ( func exampleOpenShiftCluster() *OpenShiftCluster { doc := api.ExampleOpenShiftClusterDocument() + doc.OpenShiftCluster.Properties.WorkerProfilesStatus = nil return (&openShiftClusterConverter{}).ToExternal(doc.OpenShiftCluster).(*OpenShiftCluster) } diff --git a/pkg/api/v20200430/openshiftcluster_convert.go b/pkg/api/v20200430/openshiftcluster_convert.go index 468445a5c86..84739b3f059 100644 --- a/pkg/api/v20200430/openshiftcluster_convert.go +++ b/pkg/api/v20200430/openshiftcluster_convert.go @@ -51,8 +51,15 @@ func (c openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfac } if oc.Properties.WorkerProfiles != nil { - out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(oc.Properties.WorkerProfiles)) - for _, p := range oc.Properties.WorkerProfiles { + workerProfiles := oc.Properties.WorkerProfiles + + // Use enriched worker profile data when available + if oc.Properties.WorkerProfilesStatus != nil { + workerProfiles = oc.Properties.WorkerProfilesStatus + } + + out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(workerProfiles)) + for _, p := range workerProfiles { out.Properties.WorkerProfiles = append(out.Properties.WorkerProfiles, WorkerProfile{ Name: p.Name, VMSize: VMSize(p.VMSize), diff --git a/pkg/api/v20200430/openshiftcluster_example.go b/pkg/api/v20200430/openshiftcluster_example.go index 79a7dec3208..3a1d09d0467 100644 --- a/pkg/api/v20200430/openshiftcluster_example.go +++ b/pkg/api/v20200430/openshiftcluster_example.go @@ -9,6 +9,7 @@ import ( func exampleOpenShiftCluster() *OpenShiftCluster { doc := api.ExampleOpenShiftClusterDocument() + doc.OpenShiftCluster.Properties.WorkerProfilesStatus = nil return (&openShiftClusterConverter{}).ToExternal(doc.OpenShiftCluster).(*OpenShiftCluster) } diff --git a/pkg/api/v20210901preview/openshiftcluster_convert.go b/pkg/api/v20210901preview/openshiftcluster_convert.go index 51c414adc8a..77985131fbb 100644 --- a/pkg/api/v20210901preview/openshiftcluster_convert.go +++ b/pkg/api/v20210901preview/openshiftcluster_convert.go @@ -54,8 +54,15 @@ func (c openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfac } if oc.Properties.WorkerProfiles != nil { - out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(oc.Properties.WorkerProfiles)) - for _, p := range oc.Properties.WorkerProfiles { + workerProfiles := oc.Properties.WorkerProfiles + + // Use enriched worker profile data when available + if oc.Properties.WorkerProfilesStatus != nil { + workerProfiles = oc.Properties.WorkerProfilesStatus + } + + out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(workerProfiles)) + for _, p := range workerProfiles { out.Properties.WorkerProfiles = append(out.Properties.WorkerProfiles, WorkerProfile{ Name: p.Name, VMSize: VMSize(p.VMSize), diff --git a/pkg/api/v20210901preview/openshiftcluster_example.go b/pkg/api/v20210901preview/openshiftcluster_example.go index f2dfce860bf..a22b235855b 100644 --- a/pkg/api/v20210901preview/openshiftcluster_example.go +++ b/pkg/api/v20210901preview/openshiftcluster_example.go @@ -9,6 +9,7 @@ import ( func exampleOpenShiftCluster() *OpenShiftCluster { doc := api.ExampleOpenShiftClusterDocument() + doc.OpenShiftCluster.Properties.WorkerProfilesStatus = nil return (&openShiftClusterConverter{}).ToExternal(doc.OpenShiftCluster).(*OpenShiftCluster) } diff --git a/pkg/api/v20220401/openshiftcluster_convert.go b/pkg/api/v20220401/openshiftcluster_convert.go index 57634a19dd4..e87b58a9d9b 100644 --- a/pkg/api/v20220401/openshiftcluster_convert.go +++ b/pkg/api/v20220401/openshiftcluster_convert.go @@ -54,8 +54,15 @@ func (c openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfac } if oc.Properties.WorkerProfiles != nil { - out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(oc.Properties.WorkerProfiles)) - for _, p := range oc.Properties.WorkerProfiles { + workerProfiles := oc.Properties.WorkerProfiles + + // Use enriched worker profile data when available + if oc.Properties.WorkerProfilesStatus != nil { + workerProfiles = oc.Properties.WorkerProfilesStatus + } + + out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(workerProfiles)) + for _, p := range workerProfiles { out.Properties.WorkerProfiles = append(out.Properties.WorkerProfiles, WorkerProfile{ Name: p.Name, VMSize: VMSize(p.VMSize), diff --git a/pkg/api/v20220401/openshiftcluster_example.go b/pkg/api/v20220401/openshiftcluster_example.go index ff41b8dcbd1..e9b5649e6e3 100644 --- a/pkg/api/v20220401/openshiftcluster_example.go +++ b/pkg/api/v20220401/openshiftcluster_example.go @@ -9,6 +9,7 @@ import ( func exampleOpenShiftCluster() *OpenShiftCluster { doc := api.ExampleOpenShiftClusterDocument() + doc.OpenShiftCluster.Properties.WorkerProfilesStatus = nil return (&openShiftClusterConverter{}).ToExternal(doc.OpenShiftCluster).(*OpenShiftCluster) } diff --git a/pkg/api/v20220904/openshiftcluster_convert.go b/pkg/api/v20220904/openshiftcluster_convert.go index 10807a618bb..13ff15533f4 100644 --- a/pkg/api/v20220904/openshiftcluster_convert.go +++ b/pkg/api/v20220904/openshiftcluster_convert.go @@ -54,8 +54,15 @@ func (c openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfac } if oc.Properties.WorkerProfiles != nil { - out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(oc.Properties.WorkerProfiles)) - for _, p := range oc.Properties.WorkerProfiles { + workerProfiles := oc.Properties.WorkerProfiles + + // Use enriched worker profile data when available + if oc.Properties.WorkerProfilesStatus != nil { + workerProfiles = oc.Properties.WorkerProfilesStatus + } + + out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(workerProfiles)) + for _, p := range workerProfiles { out.Properties.WorkerProfiles = append(out.Properties.WorkerProfiles, WorkerProfile{ Name: p.Name, VMSize: VMSize(p.VMSize), diff --git a/pkg/api/v20220904/openshiftcluster_example.go b/pkg/api/v20220904/openshiftcluster_example.go index cc06fb1f72e..fa615f62576 100644 --- a/pkg/api/v20220904/openshiftcluster_example.go +++ b/pkg/api/v20220904/openshiftcluster_example.go @@ -9,6 +9,7 @@ import ( func exampleOpenShiftCluster() *OpenShiftCluster { doc := api.ExampleOpenShiftClusterDocument() + doc.OpenShiftCluster.Properties.WorkerProfilesStatus = nil return (&openShiftClusterConverter{}).ToExternal(doc.OpenShiftCluster).(*OpenShiftCluster) } diff --git a/pkg/api/v20230401/openshiftcluster_convert.go b/pkg/api/v20230401/openshiftcluster_convert.go index 1c2c953cc15..34b93331984 100644 --- a/pkg/api/v20230401/openshiftcluster_convert.go +++ b/pkg/api/v20230401/openshiftcluster_convert.go @@ -55,8 +55,15 @@ func (c openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfac } if oc.Properties.WorkerProfiles != nil { - out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(oc.Properties.WorkerProfiles)) - for _, p := range oc.Properties.WorkerProfiles { + workerProfiles := oc.Properties.WorkerProfiles + + // Use enriched worker profile data when available + if oc.Properties.WorkerProfilesStatus != nil { + workerProfiles = oc.Properties.WorkerProfilesStatus + } + + out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(workerProfiles)) + for _, p := range workerProfiles { out.Properties.WorkerProfiles = append(out.Properties.WorkerProfiles, WorkerProfile{ Name: p.Name, VMSize: VMSize(p.VMSize), diff --git a/pkg/api/v20230401/openshiftcluster_example.go b/pkg/api/v20230401/openshiftcluster_example.go index 9efc52c10e7..90eedbb97ee 100644 --- a/pkg/api/v20230401/openshiftcluster_example.go +++ b/pkg/api/v20230401/openshiftcluster_example.go @@ -9,6 +9,7 @@ import ( func exampleOpenShiftCluster() *OpenShiftCluster { doc := api.ExampleOpenShiftClusterDocument() + doc.OpenShiftCluster.Properties.WorkerProfilesStatus = nil return (&openShiftClusterConverter{}).ToExternal(doc.OpenShiftCluster).(*OpenShiftCluster) } diff --git a/pkg/api/v20230701preview/openshiftcluster_convert.go b/pkg/api/v20230701preview/openshiftcluster_convert.go index f795c9e3fc8..cbdf23e72f6 100644 --- a/pkg/api/v20230701preview/openshiftcluster_convert.go +++ b/pkg/api/v20230701preview/openshiftcluster_convert.go @@ -96,8 +96,15 @@ func (c openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfac } if oc.Properties.WorkerProfiles != nil { - out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(oc.Properties.WorkerProfiles)) - for _, p := range oc.Properties.WorkerProfiles { + workerProfiles := oc.Properties.WorkerProfiles + + // Use enriched worker profile data when available + if oc.Properties.WorkerProfilesStatus != nil { + workerProfiles = oc.Properties.WorkerProfilesStatus + } + + out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(workerProfiles)) + for _, p := range workerProfiles { out.Properties.WorkerProfiles = append(out.Properties.WorkerProfiles, WorkerProfile{ Name: p.Name, VMSize: VMSize(p.VMSize), diff --git a/pkg/api/v20230701preview/openshiftcluster_example.go b/pkg/api/v20230701preview/openshiftcluster_example.go index a57ec2ab6f5..a225b28df23 100644 --- a/pkg/api/v20230701preview/openshiftcluster_example.go +++ b/pkg/api/v20230701preview/openshiftcluster_example.go @@ -9,6 +9,7 @@ import ( func exampleOpenShiftCluster() *OpenShiftCluster { doc := api.ExampleOpenShiftClusterDocument() + doc.OpenShiftCluster.Properties.WorkerProfilesStatus = nil return (&openShiftClusterConverter{}).ToExternal(doc.OpenShiftCluster).(*OpenShiftCluster) } diff --git a/pkg/api/v20230904/openshiftcluster.go b/pkg/api/v20230904/openshiftcluster.go index 5141bc9615e..00e35a48e2f 100644 --- a/pkg/api/v20230904/openshiftcluster.go +++ b/pkg/api/v20230904/openshiftcluster.go @@ -64,6 +64,9 @@ type OpenShiftClusterProperties struct { // The cluster worker profiles. WorkerProfiles []WorkerProfile `json:"workerProfiles,omitempty"` + // The cluster worker profiles status. + WorkerProfilesStatus []WorkerProfile `json:"workerProfilesStatus,omitempty"` + // The cluster API server profile. APIServerProfile APIServerProfile `json:"apiserverProfile,omitempty"` diff --git a/pkg/api/v20230904/openshiftcluster_convert.go b/pkg/api/v20230904/openshiftcluster_convert.go index 79b5afb6ac1..ce8a571946b 100644 --- a/pkg/api/v20230904/openshiftcluster_convert.go +++ b/pkg/api/v20230904/openshiftcluster_convert.go @@ -56,8 +56,9 @@ func (c openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfac } if oc.Properties.WorkerProfiles != nil { - out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(oc.Properties.WorkerProfiles)) - for _, p := range oc.Properties.WorkerProfiles { + workerProfiles := oc.Properties.WorkerProfiles + out.Properties.WorkerProfiles = make([]WorkerProfile, 0, len(workerProfiles)) + for _, p := range workerProfiles { out.Properties.WorkerProfiles = append(out.Properties.WorkerProfiles, WorkerProfile{ Name: p.Name, VMSize: VMSize(p.VMSize), @@ -70,6 +71,22 @@ func (c openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfac } } + if oc.Properties.WorkerProfilesStatus != nil { + workerProfiles := oc.Properties.WorkerProfilesStatus + out.Properties.WorkerProfilesStatus = make([]WorkerProfile, 0, len(workerProfiles)) + for _, p := range workerProfiles { + out.Properties.WorkerProfilesStatus = append(out.Properties.WorkerProfilesStatus, WorkerProfile{ + Name: p.Name, + VMSize: VMSize(p.VMSize), + DiskSizeGB: p.DiskSizeGB, + SubnetID: p.SubnetID, + Count: p.Count, + EncryptionAtHost: EncryptionAtHost(p.EncryptionAtHost), + DiskEncryptionSetID: p.DiskEncryptionSetID, + }) + } + } + if oc.Properties.IngressProfiles != nil { out.Properties.IngressProfiles = make([]IngressProfile, 0, len(oc.Properties.IngressProfiles)) for _, p := range oc.Properties.IngressProfiles { @@ -162,6 +179,20 @@ func (c openShiftClusterConverter) ToInternal(_oc interface{}, out *api.OpenShif out.Properties.WorkerProfiles[i].DiskEncryptionSetID = oc.Properties.WorkerProfiles[i].DiskEncryptionSetID } } + if oc.Properties.WorkerProfilesStatus != nil { + out.Properties.WorkerProfilesStatus = make([]api.WorkerProfile, len(oc.Properties.WorkerProfilesStatus)) + for _, p := range oc.Properties.WorkerProfilesStatus { + out.Properties.WorkerProfilesStatus = append(out.Properties.WorkerProfilesStatus, api.WorkerProfile{ + Name: p.Name, + VMSize: api.VMSize(p.VMSize), + DiskSizeGB: p.DiskSizeGB, + SubnetID: p.SubnetID, + Count: p.Count, + EncryptionAtHost: api.EncryptionAtHost(p.EncryptionAtHost), + DiskEncryptionSetID: p.DiskEncryptionSetID, + }) + } + } out.Properties.APIServerProfile.Visibility = api.Visibility(oc.Properties.APIServerProfile.Visibility) out.Properties.APIServerProfile.URL = oc.Properties.APIServerProfile.URL out.Properties.APIServerProfile.IP = oc.Properties.APIServerProfile.IP diff --git a/pkg/api/v20230904/openshiftcluster_example.go b/pkg/api/v20230904/openshiftcluster_example.go index 919e4ea72b2..cd6be9bdb7b 100644 --- a/pkg/api/v20230904/openshiftcluster_example.go +++ b/pkg/api/v20230904/openshiftcluster_example.go @@ -18,7 +18,7 @@ func ExampleOpenShiftClusterPatchParameter() interface{} { oc := ExampleOpenShiftClusterPutParameter().(*OpenShiftCluster) oc.Location = "" oc.SystemData = nil - + oc.Properties.WorkerProfilesStatus = nil return oc } @@ -37,17 +37,29 @@ func ExampleOpenShiftClusterPutParameter() interface{} { oc.Properties.APIServerProfile.IP = "" oc.Properties.IngressProfiles[0].IP = "" oc.Properties.MasterProfile.EncryptionAtHost = EncryptionAtHostEnabled + oc.Properties.WorkerProfilesStatus = nil oc.SystemData = nil return oc } // ExampleOpenShiftClusterResponse returns an example OpenShiftCluster object -// that the RP might return to an end-user -func ExampleOpenShiftClusterResponse() interface{} { +// that the RP might return to an end-user in a GET response +func ExampleOpenShiftClusterGetResponse() interface{} { + oc := exampleOpenShiftCluster() + oc.Properties.ClusterProfile.PullSecret = "" + oc.Properties.ServicePrincipalProfile.ClientSecret = "" + + return oc +} + +// ExampleOpenShiftClusterResponse returns an example OpenShiftCluster object +// that the RP might return to an end-user in a PUT/PATCH response +func ExampleOpenShiftClusterPutOrPatchResponse() interface{} { oc := exampleOpenShiftCluster() oc.Properties.ClusterProfile.PullSecret = "" oc.Properties.ServicePrincipalProfile.ClientSecret = "" + oc.Properties.WorkerProfilesStatus = nil return oc } @@ -57,7 +69,7 @@ func ExampleOpenShiftClusterResponse() interface{} { func ExampleOpenShiftClusterListResponse() interface{} { return &OpenShiftClusterList{ OpenShiftClusters: []*OpenShiftCluster{ - ExampleOpenShiftClusterResponse().(*OpenShiftCluster), + ExampleOpenShiftClusterGetResponse().(*OpenShiftCluster), }, } } diff --git a/pkg/api/v20230904/openshiftcluster_validatestatic.go b/pkg/api/v20230904/openshiftcluster_validatestatic.go index 45854e6c045..1f13933382e 100644 --- a/pkg/api/v20230904/openshiftcluster_validatestatic.go +++ b/pkg/api/v20230904/openshiftcluster_validatestatic.go @@ -104,6 +104,9 @@ func (sv openShiftClusterStaticValidator) validateProperties(path string, p *Ope if err := sv.validateAPIServerProfile(path+".apiserverProfile", &p.APIServerProfile); err != nil { return err } + if len(p.WorkerProfilesStatus) != 0 { + return api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidParameter, path+".workerProfilesStatus", "Worker Profile Status must be set to nil.") + } if isCreate { if len(p.WorkerProfiles) != 1 { diff --git a/pkg/api/v20230904/openshiftcluster_validatestatic_test.go b/pkg/api/v20230904/openshiftcluster_validatestatic_test.go index 26df325d2bf..bf518a53ff8 100644 --- a/pkg/api/v20230904/openshiftcluster_validatestatic_test.go +++ b/pkg/api/v20230904/openshiftcluster_validatestatic_test.go @@ -243,6 +243,22 @@ func TestOpenShiftClusterStaticValidateProperties(t *testing.T) { }, wantErr: "400: InvalidParameter: properties.provisioningState: The provided provisioning state 'invalid' is invalid.", }, + { + name: "workerProfileStatus nonNil", + modify: func(oc *OpenShiftCluster) { + oc.Properties.WorkerProfilesStatus = []WorkerProfile{ + { + Name: "worker", + VMSize: "Standard_D4s_v3", + EncryptionAtHost: EncryptionAtHostDisabled, + DiskSizeGB: 128, + SubnetID: fmt.Sprintf("/subscriptions/%s/resourceGroups/vnet/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/worker", subscriptionID), + Count: 3, + }, + } + }, + wantErr: "400: InvalidParameter: properties.workerProfilesStatus: Worker Profile Status must be set to nil.", + }, } createTests := []*validateTest{ { diff --git a/pkg/client/services/redhatopenshift/mgmt/2023-09-04/redhatopenshift/models.go b/pkg/client/services/redhatopenshift/mgmt/2023-09-04/redhatopenshift/models.go index 272890e8f0c..88cacef54bc 100644 --- a/pkg/client/services/redhatopenshift/mgmt/2023-09-04/redhatopenshift/models.go +++ b/pkg/client/services/redhatopenshift/mgmt/2023-09-04/redhatopenshift/models.go @@ -748,12 +748,47 @@ type OpenShiftClusterProperties struct { MasterProfile *MasterProfile `json:"masterProfile,omitempty"` // WorkerProfiles - The cluster worker profiles. WorkerProfiles *[]WorkerProfile `json:"workerProfiles,omitempty"` + // WorkerProfilesStatus - READ-ONLY; The cluster worker profiles status. + WorkerProfilesStatus *[]WorkerProfile `json:"workerProfilesStatus,omitempty"` // ApiserverProfile - The cluster API server profile. ApiserverProfile *APIServerProfile `json:"apiserverProfile,omitempty"` // IngressProfiles - The cluster ingress profiles. IngressProfiles *[]IngressProfile `json:"ingressProfiles,omitempty"` } +// MarshalJSON is the custom marshaler for OpenShiftClusterProperties. +func (oscp OpenShiftClusterProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if oscp.ProvisioningState != "" { + objectMap["provisioningState"] = oscp.ProvisioningState + } + if oscp.ClusterProfile != nil { + objectMap["clusterProfile"] = oscp.ClusterProfile + } + if oscp.ConsoleProfile != nil { + objectMap["consoleProfile"] = oscp.ConsoleProfile + } + if oscp.ServicePrincipalProfile != nil { + objectMap["servicePrincipalProfile"] = oscp.ServicePrincipalProfile + } + if oscp.NetworkProfile != nil { + objectMap["networkProfile"] = oscp.NetworkProfile + } + if oscp.MasterProfile != nil { + objectMap["masterProfile"] = oscp.MasterProfile + } + if oscp.WorkerProfiles != nil { + objectMap["workerProfiles"] = oscp.WorkerProfiles + } + if oscp.ApiserverProfile != nil { + objectMap["apiserverProfile"] = oscp.ApiserverProfile + } + if oscp.IngressProfiles != nil { + objectMap["ingressProfiles"] = oscp.IngressProfiles + } + return json.Marshal(objectMap) +} + // OpenShiftClustersCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a // long-running operation. type OpenShiftClustersCreateOrUpdateFuture struct { diff --git a/pkg/cluster/deploybaseresources.go b/pkg/cluster/deploybaseresources.go index 83fc5d1921b..f964fe8ff1b 100644 --- a/pkg/cluster/deploybaseresources.go +++ b/pkg/cluster/deploybaseresources.go @@ -182,10 +182,12 @@ func (m *manager) attachNSGs(ctx context.Context) error { if m.doc.OpenShiftCluster.Properties.NetworkProfile.PreconfiguredNSG == api.PreconfiguredNSGEnabled { return nil } + workerProfiles, _ := api.GetEnrichedWorkerProfiles(m.doc.OpenShiftCluster.Properties) + workerSubnetId := workerProfiles[0].SubnetID for _, subnetID := range []string{ m.doc.OpenShiftCluster.Properties.MasterProfile.SubnetID, - m.doc.OpenShiftCluster.Properties.WorkerProfiles[0].SubnetID, + workerSubnetId, } { m.log.Printf("attaching network security group to subnet %s", subnetID) diff --git a/pkg/cluster/deploybaseresources_additional.go b/pkg/cluster/deploybaseresources_additional.go index 028d442dc0d..01a6d162256 100644 --- a/pkg/cluster/deploybaseresources_additional.go +++ b/pkg/cluster/deploybaseresources_additional.go @@ -92,13 +92,15 @@ func (m *manager) storageAccount(name, region string, encrypted bool) *arm.Resou // Virtual network rules to allow the cluster subnets to directly reach the storage accounts // are only needed when egress lockdown is not enabled. if !m.doc.OpenShiftCluster.Properties.FeatureProfile.GatewayEnabled { + workerProfiles, _ := api.GetEnrichedWorkerProfiles(m.doc.OpenShiftCluster.Properties) + workerSubnetId := workerProfiles[0].SubnetID virtualNetworkRules = append(virtualNetworkRules, []mgmtstorage.VirtualNetworkRule{ { VirtualNetworkResourceID: &m.doc.OpenShiftCluster.Properties.MasterProfile.SubnetID, Action: mgmtstorage.Allow, }, { - VirtualNetworkResourceID: &m.doc.OpenShiftCluster.Properties.WorkerProfiles[0].SubnetID, + VirtualNetworkResourceID: &workerSubnetId, Action: mgmtstorage.Allow, }, }...) diff --git a/pkg/cluster/ensureendpoints.go b/pkg/cluster/ensureendpoints.go index e19adeecdcf..a39630d9bad 100644 --- a/pkg/cluster/ensureendpoints.go +++ b/pkg/cluster/ensureendpoints.go @@ -6,6 +6,8 @@ package cluster import ( "context" "fmt" + + "github.com/Azure/ARO-RP/pkg/api" ) // ensureServiceEndpoints should enable service endpoints on @@ -24,8 +26,9 @@ func (m *manager) getSubnetIds() ([]string, error) { subnets := []string{ m.doc.OpenShiftCluster.Properties.MasterProfile.SubnetID, } + workerProfiles, _ := api.GetEnrichedWorkerProfiles(m.doc.OpenShiftCluster.Properties) - for _, wp := range m.doc.OpenShiftCluster.Properties.WorkerProfiles { + for _, wp := range workerProfiles { if len(wp.SubnetID) == 0 { return nil, fmt.Errorf("WorkerProfile '%s' has no SubnetID; check that the corresponding MachineSet is valid", wp.Name) } diff --git a/pkg/cluster/ipaddresses.go b/pkg/cluster/ipaddresses.go index 1e9955e6a1f..b2e2903115e 100644 --- a/pkg/cluster/ipaddresses.go +++ b/pkg/cluster/ipaddresses.go @@ -107,7 +107,10 @@ func (m *manager) createOrUpdateRouterIPEarly(ctx context.Context) error { // with this. // https://docs.microsoft.com/en-us/azure/virtual-network/private-ip-addresses#allocation-method var err error - ipAddress, err = m.subnet.GetHighestFreeIP(ctx, m.doc.OpenShiftCluster.Properties.WorkerProfiles[0].SubnetID) + + workerProfiles, _ := api.GetEnrichedWorkerProfiles(m.doc.OpenShiftCluster.Properties) + workerSubnetId := workerProfiles[0].SubnetID + ipAddress, err = m.subnet.GetHighestFreeIP(ctx, workerSubnetId) if err != nil { return err } diff --git a/pkg/cluster/ipaddresses_test.go b/pkg/cluster/ipaddresses_test.go index bf5d00f0813..d2f95a40643 100644 --- a/pkg/cluster/ipaddresses_test.go +++ b/pkg/cluster/ipaddresses_test.go @@ -274,6 +274,52 @@ func TestCreateOrUpdateRouterIPEarly(t *testing.T) { Return(nil) }, }, + { + name: "private - use enriched worker profile", + fixtureChecker: func(fixture *testdatabase.Fixture, checker *testdatabase.Checker, dbClient *cosmosdb.FakeOpenShiftClusterDocumentClient) { + doc := &api.OpenShiftClusterDocument{ + Key: strings.ToLower(key), + OpenShiftCluster: &api.OpenShiftCluster{ + ID: key, + Properties: api.OpenShiftClusterProperties{ + ClusterProfile: api.ClusterProfile{ + ResourceGroupID: resourceGroupID, + }, + WorkerProfiles: []api.WorkerProfile{ + { + SubnetID: "subnetid", + }, + }, + WorkerProfilesStatus: []api.WorkerProfile{ + { + SubnetID: "enricheWPsubnetid", + }, + }, + IngressProfiles: []api.IngressProfile{ + { + Visibility: api.VisibilityPrivate, + }, + }, + ProvisioningState: api.ProvisioningStateCreating, + InfraID: "infra", + }, + }, + } + fixture.AddOpenShiftClusterDocuments(doc) + + doc.Dequeues = 1 + doc.OpenShiftCluster.Properties.IngressProfiles[0].IP = "1.2.3.4" + checker.AddOpenShiftClusterDocuments(doc) + }, + mocks: func(publicIPAddresses *mock_network.MockPublicIPAddressesClient, dns *mock_dns.MockManager, subnet *mock_subnet.MockManager) { + subnet.EXPECT(). + GetHighestFreeIP(gomock.Any(), "enricheWPsubnetid"). + Return("1.2.3.4", nil) + dns.EXPECT(). + CreateOrUpdateRouter(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + }, + }, } { t.Run(tt.name, func(t *testing.T) { controller := gomock.NewController(t) diff --git a/pkg/cluster/storageaccounts.go b/pkg/cluster/storageaccounts.go index 35c8032b273..daf5fc717ac 100644 --- a/pkg/cluster/storageaccounts.go +++ b/pkg/cluster/storageaccounts.go @@ -18,7 +18,9 @@ import ( // The encryption flag is set to false/disabled for legacy storage accounts. func (m *manager) migrateStorageAccounts(ctx context.Context) error { resourceGroup := stringutils.LastTokenByte(m.doc.OpenShiftCluster.Properties.ClusterProfile.ResourceGroupID, '/') - if len(m.doc.OpenShiftCluster.Properties.WorkerProfiles) == 0 { + workerProfiles, _ := api.GetEnrichedWorkerProfiles(m.doc.OpenShiftCluster.Properties) + + if len(workerProfiles) == 0 { m.log.Error("skipping migrateStorageAccounts due to missing WorkerProfiles.") return nil } diff --git a/pkg/cluster/storageclass.go b/pkg/cluster/storageclass.go index 9ff72868ba4..e33c40f0344 100644 --- a/pkg/cluster/storageclass.go +++ b/pkg/cluster/storageclass.go @@ -13,6 +13,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/util/retry" + "github.com/Azure/ARO-RP/pkg/api" "github.com/Azure/ARO-RP/pkg/util/version" ) @@ -28,7 +29,10 @@ const ( // configureDefaultStorageClass replaces default storage class provided by OCP with // a new one which uses disk encryption set (if one supplied by a customer). func (m *manager) configureDefaultStorageClass(ctx context.Context) error { - if m.doc.OpenShiftCluster.Properties.WorkerProfiles[0].DiskEncryptionSetID == "" { + workerProfiles, _ := api.GetEnrichedWorkerProfiles(m.doc.OpenShiftCluster.Properties) + workerDiskEncryptionSetID := workerProfiles[0].DiskEncryptionSetID + + if workerDiskEncryptionSetID == "" { return nil } @@ -63,7 +67,7 @@ func (m *manager) configureDefaultStorageClass(ctx context.Context) error { return err } - encryptedSC := newEncryptedStorageClass(m.doc.OpenShiftCluster.Properties.WorkerProfiles[0].DiskEncryptionSetID, encryptedStorageClassName, provisioner) + encryptedSC := newEncryptedStorageClass(workerDiskEncryptionSetID, encryptedStorageClassName, provisioner) _, err = m.kubernetescli.StorageV1().StorageClasses().Create(ctx, encryptedSC, metav1.CreateOptions{}) if err != nil && !kerrors.IsAlreadyExists(err) { return err diff --git a/pkg/cluster/storageclass_test.go b/pkg/cluster/storageclass_test.go index b32c6d91310..f53d1dab471 100644 --- a/pkg/cluster/storageclass_test.go +++ b/pkg/cluster/storageclass_test.go @@ -25,6 +25,7 @@ func TestConfigureStorageClass(t *testing.T) { name string mocks func(kubernetescli *fake.Clientset) desID string + wpStatus bool ocpVersion string wantErr string wantNewSC bool @@ -39,6 +40,13 @@ func TestConfigureStorageClass(t *testing.T) { ocpVersion: "4.10.40", wantNewSC: true, }, + { + name: "Use disk encryption set provided in enriched worker profile", + desID: "fake-des-id", + wpStatus: true, + ocpVersion: "4.10.40", + wantNewSC: true, + }, { name: "error getting old default StorageClass", desID: "fake-des-id", @@ -148,6 +156,15 @@ func TestConfigureStorageClass(t *testing.T) { }, } + if tt.wpStatus { + m.doc.OpenShiftCluster.Properties.WorkerProfiles = nil + m.doc.OpenShiftCluster.Properties.WorkerProfilesStatus = []api.WorkerProfile{ + { + DiskEncryptionSetID: tt.desID, + }, + } + } + err = m.configureDefaultStorageClass(ctx) utilerror.AssertErrorMessage(t, err, tt.wantErr) diff --git a/pkg/frontend/adminactions/resources_list.go b/pkg/frontend/adminactions/resources_list.go index d31633c39a7..2c78521800e 100644 --- a/pkg/frontend/adminactions/resources_list.go +++ b/pkg/frontend/adminactions/resources_list.go @@ -11,6 +11,7 @@ import ( mgmtfeatures "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2019-07-01/features" "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/ARO-RP/pkg/api" apisubnet "github.com/Azure/ARO-RP/pkg/api/util/subnet" "github.com/Azure/ARO-RP/pkg/util/arm" "github.com/Azure/ARO-RP/pkg/util/azureclient" @@ -134,7 +135,9 @@ func (a *azureActions) appendAzureNetworkResources(ctx context.Context, armResou for _, snet := range *vnet.Subnets { //we already have the VNet resource, filtering subnets instead of fetching them individually with a SubnetClient interestingSubnet := (*snet.ID == a.oc.Properties.MasterProfile.SubnetID) - for _, wProfile := range a.oc.Properties.WorkerProfiles { + workerProfiles, _ := api.GetEnrichedWorkerProfiles(a.oc.Properties) + + for _, wProfile := range workerProfiles { interestingSubnet = interestingSubnet || (*snet.ID == wProfile.SubnetID) } if !interestingSubnet { diff --git a/pkg/frontend/openshiftcluster_putorpatch.go b/pkg/frontend/openshiftcluster_putorpatch.go index 0ce1146f24e..66bef843161 100644 --- a/pkg/frontend/openshiftcluster_putorpatch.go +++ b/pkg/frontend/openshiftcluster_putorpatch.go @@ -245,6 +245,9 @@ func (f *frontend) _putOrPatchOpenShiftCluster(ctx context.Context, log *logrus. doc.OpenShiftCluster.Properties.ClusterProfile.PullSecret = "" doc.OpenShiftCluster.Properties.ServicePrincipalProfile.ClientSecret = "" + // We don't return enriched worker profile data on PUT/PATCH operations + doc.OpenShiftCluster.Properties.WorkerProfilesStatus = nil + b, err := json.MarshalIndent(converter.ToExternal(doc.OpenShiftCluster), "", " ") if err != nil { return nil, err diff --git a/pkg/frontend/quota_validation.go b/pkg/frontend/quota_validation.go index e87c7fb3867..a8cd8657ce1 100644 --- a/pkg/frontend/quota_validation.go +++ b/pkg/frontend/quota_validation.go @@ -58,8 +58,10 @@ func validateQuota(ctx context.Context, oc *api.OpenShiftCluster, spNetworkUsage if err != nil { return err } + + workerProfiles, _ := api.GetEnrichedWorkerProfiles(oc.Properties) //worker node resource calculation - for _, w := range oc.Properties.WorkerProfiles { + for _, w := range workerProfiles { err := addRequiredResources(requiredResources, w.VMSize, w.Count) if err != nil { return err diff --git a/pkg/frontend/sku_test.go b/pkg/frontend/sku_test.go index 1c2ca47b173..70e132c5dd7 100644 --- a/pkg/frontend/sku_test.go +++ b/pkg/frontend/sku_test.go @@ -31,6 +31,7 @@ func TestValidateVMSku(t *testing.T) { availableSku2 string restrictedSku string resourceSkusClientErr error + wpStatus bool wantErr string }{ { @@ -40,6 +41,14 @@ func TestValidateVMSku(t *testing.T) { masterProfileSku: "Standard_D4s_v2", availableSku: "Standard_D4s_v2", }, + { + name: "worker profile is enriched and skus are valid", + workerProfile1Sku: "Standard_D4s_v2", + workerProfile2Sku: "Standard_D4s_v2", + masterProfileSku: "Standard_D4s_v2", + availableSku: "Standard_D4s_v2", + wpStatus: true, + }, { name: "worker and master skus are distinct, both valid", workerProfile1Sku: "Standard_E104i_v5", @@ -203,6 +212,18 @@ func TestValidateVMSku(t *testing.T) { }, } + if tt.wpStatus { + oc.Properties.WorkerProfiles = nil + oc.Properties.WorkerProfilesStatus = []api.WorkerProfile{ + { + VMSize: api.VMSize(tt.workerProfile1Sku), + }, + { + VMSize: api.VMSize(tt.workerProfile2Sku), + }, + } + } + resourceSkusClient := mock_compute.NewMockResourceSkusClient(controller) resourceSkusClient.EXPECT(). List(gomock.Any(), fmt.Sprintf("location eq %v", "eastus")). diff --git a/pkg/frontend/sku_validation.go b/pkg/frontend/sku_validation.go index 8df0027d821..61dbcb9a28f 100644 --- a/pkg/frontend/sku_validation.go +++ b/pkg/frontend/sku_validation.go @@ -52,9 +52,11 @@ func validateVMSku(ctx context.Context, oc *api.OpenShiftCluster, resourceSkusCl return err } + workerProfiles, _ := api.GetEnrichedWorkerProfiles(oc.Properties) + // In case there are multiple WorkerProfiles listed in the cluster document (such as post-install), // compare VMSize in each WorkerProfile to the resourceSkusClient call above to ensure that the sku is available in region. - for i, workerprofile := range oc.Properties.WorkerProfiles { + for i, workerprofile := range workerProfiles { workerProfileSku := string(workerprofile.VMSize) err = checkSKUAvailability(filteredSkus, location, fmt.Sprintf("properties.workerProfiles[%d].VMSize", i), workerProfileSku) diff --git a/pkg/swagger/examples.go b/pkg/swagger/examples.go index ad0a843d1b4..194e7bc469a 100644 --- a/pkg/swagger/examples.go +++ b/pkg/swagger/examples.go @@ -154,7 +154,16 @@ func (g *generator) generateExamples(outputDir string, s *Swagger) error { case "#/definitions/SecretList": body = g.exampleSecretListResponse() case "#/definitions/OpenShiftCluster": - body = g.exampleOpenShiftClusterResponse() + if g.workerProfilesStatus { + switch op { + case pi.Get: + body = g.exampleOpenShiftClusterGetResponse() + case pi.Put, pi.Patch: + body = g.exampleOpenShiftClusterPutOrPatchResponse() + } + } else { + body = g.exampleOpenShiftClusterResponse() + } case "#/definitions/OpenShiftClusterCredentials": body = g.exampleOpenShiftClusterCredentialsResponse() case "#/definitions/OpenShiftClusterAdminKubeconfig": diff --git a/pkg/swagger/generator.go b/pkg/swagger/generator.go index 472b2d6ea73..899b3896ce3 100644 --- a/pkg/swagger/generator.go +++ b/pkg/swagger/generator.go @@ -44,20 +44,23 @@ type generator struct { exampleOpenShiftClusterPutParameter func() interface{} exampleOpenShiftClusterPatchParameter func() interface{} exampleOpenShiftClusterResponse func() interface{} + exampleOpenShiftClusterGetResponse func() interface{} + exampleOpenShiftClusterPutOrPatchResponse func() interface{} exampleOpenShiftClusterCredentialsResponse func() interface{} exampleOpenShiftClusterAdminKubeconfigResponse func() interface{} exampleOpenShiftClusterListResponse func() interface{} exampleOpenShiftVersionListResponse func() interface{} exampleOperationListResponse func() interface{} - systemData bool - kubeConfig bool - installVersionList bool - clusterManager bool - xmsEnum []string - xmsSecretList []string - xmsIdentifiers []string - commonTypesVersion string + systemData bool + kubeConfig bool + installVersionList bool + clusterManager bool + workerProfilesStatus bool + xmsEnum []string + xmsSecretList []string + xmsIdentifiers []string + commonTypesVersion string } var apis = map[string]*generator{ @@ -227,21 +230,23 @@ var apis = map[string]*generator{ exampleSecretListResponse: v20230904.ExampleSecretListResponse, exampleOpenShiftClusterPutParameter: v20230904.ExampleOpenShiftClusterPutParameter, exampleOpenShiftClusterPatchParameter: v20230904.ExampleOpenShiftClusterPatchParameter, - exampleOpenShiftClusterResponse: v20230904.ExampleOpenShiftClusterResponse, + exampleOpenShiftClusterGetResponse: v20230904.ExampleOpenShiftClusterGetResponse, + exampleOpenShiftClusterPutOrPatchResponse: v20230904.ExampleOpenShiftClusterPutOrPatchResponse, exampleOpenShiftClusterCredentialsResponse: v20230904.ExampleOpenShiftClusterCredentialsResponse, exampleOpenShiftClusterListResponse: v20230904.ExampleOpenShiftClusterListResponse, exampleOpenShiftClusterAdminKubeconfigResponse: v20230904.ExampleOpenShiftClusterAdminKubeconfigResponse, exampleOpenShiftVersionListResponse: v20230904.ExampleOpenShiftVersionListResponse, exampleOperationListResponse: api.ExampleOperationListResponse, - xmsEnum: []string{"EncryptionAtHost", "FipsValidatedModules", "SoftwareDefinedNetwork", "Visibility", "OutboundType", "PreconfiguredNSG"}, - xmsSecretList: []string{"kubeconfig", "kubeadminPassword", "secretResources"}, - xmsIdentifiers: []string{}, - commonTypesVersion: "v3", - systemData: true, - clusterManager: true, - installVersionList: true, - kubeConfig: true, + xmsEnum: []string{"EncryptionAtHost", "FipsValidatedModules", "SoftwareDefinedNetwork", "Visibility", "OutboundType"}, + xmsSecretList: []string{"kubeconfig", "kubeadminPassword", "secretResources"}, + xmsIdentifiers: []string{}, + commonTypesVersion: "v3", + systemData: true, + clusterManager: true, + installVersionList: true, + kubeConfig: true, + workerProfilesStatus: true, }, } diff --git a/pkg/swagger/typewalker.go b/pkg/swagger/typewalker.go index 23fb8b1c1e4..4ca94f458c4 100644 --- a/pkg/swagger/typewalker.go +++ b/pkg/swagger/typewalker.go @@ -141,6 +141,9 @@ func (tw *typeWalker) schemaFromType(t types.Type, deps map[*types.Named]struct{ properties := tw.schemaFromType(field.Type(), deps) properties.Description = strings.Trim(node.Doc.Text(), "\n") + if field.Name() == "WorkerProfilesStatus" { + properties.ReadOnly = true + } if field.Name() == "EffectiveOutboundIPs" { properties.ReadOnly = true diff --git a/pkg/util/clusterdata/worker_profile.go b/pkg/util/clusterdata/worker_profile.go index 1870bdd01d3..455bce06888 100644 --- a/pkg/util/clusterdata/worker_profile.go +++ b/pkg/util/clusterdata/worker_profile.go @@ -102,10 +102,10 @@ func (ce machineClientEnricher) Enrich( oc.Lock.Lock() defer oc.Lock.Unlock() - oc.Properties.WorkerProfiles = workerProfiles + oc.Properties.WorkerProfilesStatus = workerProfiles return nil } func (ce machineClientEnricher) SetDefaults(oc *api.OpenShiftCluster) { - oc.Properties.WorkerProfiles = nil + oc.Properties.WorkerProfilesStatus = nil } diff --git a/pkg/util/clusterdata/worker_profile_test.go b/pkg/util/clusterdata/worker_profile_test.go index 593459e514c..f89452bec2c 100644 --- a/pkg/util/clusterdata/worker_profile_test.go +++ b/pkg/util/clusterdata/worker_profile_test.go @@ -192,7 +192,7 @@ func getWantOc(clusID string, workerprofile []api.WorkerProfile) *api.OpenShiftC return &api.OpenShiftCluster{ ID: clusID, Properties: api.OpenShiftClusterProperties{ - WorkerProfiles: workerprofile, + WorkerProfilesStatus: workerprofile, }, } } diff --git a/pkg/validate/dynamic/diskencryptionset.go b/pkg/validate/dynamic/diskencryptionset.go index 8c61a417d81..be7fc11b918 100644 --- a/pkg/validate/dynamic/diskencryptionset.go +++ b/pkg/validate/dynamic/diskencryptionset.go @@ -31,7 +31,9 @@ func (dv *dynamic) ValidateDiskEncryptionSets(ctx context.Context, oc *api.OpenS ids = append(ids, oc.Properties.MasterProfile.DiskEncryptionSetID) paths = append(paths, "properties.masterProfile.diskEncryptionSetId") } - for i, wp := range oc.Properties.WorkerProfiles { + + workerProfiles, propertyName := api.GetEnrichedWorkerProfiles(oc.Properties) + for i, wp := range workerProfiles { if wp.DiskEncryptionSetID != "" { lowercasedId := strings.ToLower(wp.DiskEncryptionSetID) if _, ok := uniqueIds[lowercasedId]; ok { @@ -40,7 +42,7 @@ func (dv *dynamic) ValidateDiskEncryptionSets(ctx context.Context, oc *api.OpenS uniqueIds[lowercasedId] = struct{}{} ids = append(ids, wp.DiskEncryptionSetID) - paths = append(paths, fmt.Sprintf("properties.workerProfiles[%d].diskEncryptionSetId", i)) + paths = append(paths, fmt.Sprintf("properties.%s[%d].diskEncryptionSetId", propertyName, i)) } } diff --git a/pkg/validate/dynamic/diskencryptionset_test.go b/pkg/validate/dynamic/diskencryptionset_test.go index 4c4f43fb580..3b684ff2183 100644 --- a/pkg/validate/dynamic/diskencryptionset_test.go +++ b/pkg/validate/dynamic/diskencryptionset_test.go @@ -78,6 +78,31 @@ func TestValidateDiskEncryptionSets(t *testing.T) { Return(mgmtcompute.DiskEncryptionSet{Location: to.StringPtr("eastus")}, nil) }, }, + { + name: "valid disk encryption set by enriched worker profile", + oc: &api.OpenShiftCluster{ + Location: "eastus", + Properties: api.OpenShiftClusterProperties{ + MasterProfile: api.MasterProfile{ + DiskEncryptionSetID: fakeDesID1, + }, + WorkerProfilesStatus: []api.WorkerProfile{{ + DiskEncryptionSetID: fakeDesID1, + }}, + }, + }, + mocks: func(permissions *mock_authorization.MockPermissionsClient, diskEncryptionSets *mock_compute.MockDiskEncryptionSetsClient, cancel context.CancelFunc) { + permissions.EXPECT(). + ListForResource(gomock.Any(), fakeDesR1.ResourceGroup, fakeDesR1.Provider, "", fakeDesR1.ResourceType, fakeDesR1.ResourceName). + Return([]mgmtauthorization.Permission{{ + Actions: &[]string{"Microsoft.Compute/diskEncryptionSets/read"}, + NotActions: &[]string{}, + }}, nil) + diskEncryptionSets.EXPECT(). + Get(gomock.Any(), fakeDesR1.ResourceGroup, fakeDesR1.ResourceName). + Return(mgmtcompute.DiskEncryptionSet{Location: to.StringPtr("eastus")}, nil) + }, + }, { name: "valid permissions multiple disk encryption sets", oc: &api.OpenShiftCluster{ diff --git a/pkg/validate/dynamic/encryptionathost.go b/pkg/validate/dynamic/encryptionathost.go index e5a97724a58..a98b1a3c860 100644 --- a/pkg/validate/dynamic/encryptionathost.go +++ b/pkg/validate/dynamic/encryptionathost.go @@ -22,9 +22,10 @@ func (dv *dynamic) ValidateEncryptionAtHost(ctx context.Context, oc *api.OpenShi } } - for i, wp := range oc.Properties.WorkerProfiles { + workerProfiles, propertyName := api.GetEnrichedWorkerProfiles(oc.Properties) + for i, wp := range workerProfiles { if wp.EncryptionAtHost == api.EncryptionAtHostEnabled { - err := dv.validateEncryptionAtHostSupport(wp.VMSize, fmt.Sprintf("properties.workerProfiles[%d].encryptionAtHost", i)) + err := dv.validateEncryptionAtHostSupport(wp.VMSize, fmt.Sprintf("properties.%s[%d].encryptionAtHost", propertyName, i)) if err != nil { return err } diff --git a/pkg/validate/dynamic/encryptionathost_test.go b/pkg/validate/dynamic/encryptionathost_test.go index 2a5a7e2ee76..ef61f5a355c 100644 --- a/pkg/validate/dynamic/encryptionathost_test.go +++ b/pkg/validate/dynamic/encryptionathost_test.go @@ -58,6 +58,35 @@ func TestValidateEncryptionAtHost(t *testing.T) { }, nil) }, }, + { + name: "encryption at host enabled with valid VM SKU and enriched worker profile available", + oc: &api.OpenShiftCluster{ + Properties: api.OpenShiftClusterProperties{ + MasterProfile: api.MasterProfile{ + EncryptionAtHost: api.EncryptionAtHostEnabled, + VMSize: api.VMSizeStandardD8sV3, + }, + WorkerProfilesStatus: []api.WorkerProfile{{ + EncryptionAtHost: api.EncryptionAtHostEnabled, + VMSize: api.VMSizeStandardD4asV4, + }}, + }, + }, + mocks: func(env *mock_env.MockInterface) { + env.EXPECT().VMSku(string(api.VMSizeStandardD8sV3)). + Return(&mgmtcompute.ResourceSku{ + Capabilities: &([]mgmtcompute.ResourceSkuCapabilities{ + {Name: to.StringPtr("EncryptionAtHostSupported"), Value: to.StringPtr("True")}, + }), + }, nil) + env.EXPECT().VMSku(string(api.VMSizeStandardD4asV4)). + Return(&mgmtcompute.ResourceSku{ + Capabilities: &([]mgmtcompute.ResourceSkuCapabilities{ + {Name: to.StringPtr("EncryptionAtHostSupported"), Value: to.StringPtr("True")}, + }), + }, nil) + }, + }, { name: "encryption at host enabled with unsupported master VM SKU", oc: &api.OpenShiftCluster{ diff --git a/pkg/validate/openshiftcluster_validatedynamic.go b/pkg/validate/openshiftcluster_validatedynamic.go index e321666e530..abaf897fd9e 100644 --- a/pkg/validate/openshiftcluster_validatedynamic.go +++ b/pkg/validate/openshiftcluster_validatedynamic.go @@ -122,10 +122,12 @@ func (dv *openShiftClusterDynamicValidator) Dynamic(ctx context.Context) error { ID: dv.oc.Properties.MasterProfile.SubnetID, Path: "properties.masterProfile.subnetId", }} - for i, wp := range dv.oc.Properties.WorkerProfiles { + + workerProfiles, propertyName := api.GetEnrichedWorkerProfiles(dv.oc.Properties) + for i, wp := range workerProfiles { subnets = append(subnets, dynamic.Subnet{ ID: wp.SubnetID, - Path: fmt.Sprintf("properties.workerProfiles[%d].subnetId", i), + Path: fmt.Sprintf("properties.%s[%d].subnetId", propertyName, i), }) } diff --git a/python/client/azure/mgmt/redhatopenshift/v2023_09_04/models/_models.py b/python/client/azure/mgmt/redhatopenshift/v2023_09_04/models/_models.py index 4029febe2f2..b8ed32762e5 100644 --- a/python/client/azure/mgmt/redhatopenshift/v2023_09_04/models/_models.py +++ b/python/client/azure/mgmt/redhatopenshift/v2023_09_04/models/_models.py @@ -633,6 +633,9 @@ class OpenShiftCluster(TrackedResource): :vartype master_profile: ~azure.mgmt.redhatopenshift.v2023_09_04.models.MasterProfile :ivar worker_profiles: The cluster worker profiles. :vartype worker_profiles: list[~azure.mgmt.redhatopenshift.v2023_09_04.models.WorkerProfile] + :ivar worker_profiles_status: The cluster worker profiles status. + :vartype worker_profiles_status: + list[~azure.mgmt.redhatopenshift.v2023_09_04.models.WorkerProfile] :ivar apiserver_profile: The cluster API server profile. :vartype apiserver_profile: ~azure.mgmt.redhatopenshift.v2023_09_04.models.APIServerProfile :ivar ingress_profiles: The cluster ingress profiles. @@ -645,6 +648,7 @@ class OpenShiftCluster(TrackedResource): 'type': {'readonly': True}, 'system_data': {'readonly': True}, 'location': {'required': True}, + 'worker_profiles_status': {'readonly': True}, } _attribute_map = { @@ -661,6 +665,7 @@ class OpenShiftCluster(TrackedResource): 'network_profile': {'key': 'properties.networkProfile', 'type': 'NetworkProfile'}, 'master_profile': {'key': 'properties.masterProfile', 'type': 'MasterProfile'}, 'worker_profiles': {'key': 'properties.workerProfiles', 'type': '[WorkerProfile]'}, + 'worker_profiles_status': {'key': 'properties.workerProfilesStatus', 'type': '[WorkerProfile]'}, 'apiserver_profile': {'key': 'properties.apiserverProfile', 'type': 'APIServerProfile'}, 'ingress_profiles': {'key': 'properties.ingressProfiles', 'type': '[IngressProfile]'}, } @@ -705,6 +710,7 @@ def __init__( self.network_profile = kwargs.get('network_profile', None) self.master_profile = kwargs.get('master_profile', None) self.worker_profiles = kwargs.get('worker_profiles', None) + self.worker_profiles_status = None self.apiserver_profile = kwargs.get('apiserver_profile', None) self.ingress_profiles = kwargs.get('ingress_profiles', None) @@ -816,6 +822,9 @@ class OpenShiftClusterUpdate(msrest.serialization.Model): :vartype master_profile: ~azure.mgmt.redhatopenshift.v2023_09_04.models.MasterProfile :ivar worker_profiles: The cluster worker profiles. :vartype worker_profiles: list[~azure.mgmt.redhatopenshift.v2023_09_04.models.WorkerProfile] + :ivar worker_profiles_status: The cluster worker profiles status. + :vartype worker_profiles_status: + list[~azure.mgmt.redhatopenshift.v2023_09_04.models.WorkerProfile] :ivar apiserver_profile: The cluster API server profile. :vartype apiserver_profile: ~azure.mgmt.redhatopenshift.v2023_09_04.models.APIServerProfile :ivar ingress_profiles: The cluster ingress profiles. @@ -824,6 +833,7 @@ class OpenShiftClusterUpdate(msrest.serialization.Model): _validation = { 'system_data': {'readonly': True}, + 'worker_profiles_status': {'readonly': True}, } _attribute_map = { @@ -836,6 +846,7 @@ class OpenShiftClusterUpdate(msrest.serialization.Model): 'network_profile': {'key': 'properties.networkProfile', 'type': 'NetworkProfile'}, 'master_profile': {'key': 'properties.masterProfile', 'type': 'MasterProfile'}, 'worker_profiles': {'key': 'properties.workerProfiles', 'type': '[WorkerProfile]'}, + 'worker_profiles_status': {'key': 'properties.workerProfilesStatus', 'type': '[WorkerProfile]'}, 'apiserver_profile': {'key': 'properties.apiserverProfile', 'type': 'APIServerProfile'}, 'ingress_profiles': {'key': 'properties.ingressProfiles', 'type': '[IngressProfile]'}, } @@ -880,6 +891,7 @@ def __init__( self.network_profile = kwargs.get('network_profile', None) self.master_profile = kwargs.get('master_profile', None) self.worker_profiles = kwargs.get('worker_profiles', None) + self.worker_profiles_status = None self.apiserver_profile = kwargs.get('apiserver_profile', None) self.ingress_profiles = kwargs.get('ingress_profiles', None) diff --git a/python/client/azure/mgmt/redhatopenshift/v2023_09_04/models/_models_py3.py b/python/client/azure/mgmt/redhatopenshift/v2023_09_04/models/_models_py3.py index 163e4c79124..51a225a2206 100644 --- a/python/client/azure/mgmt/redhatopenshift/v2023_09_04/models/_models_py3.py +++ b/python/client/azure/mgmt/redhatopenshift/v2023_09_04/models/_models_py3.py @@ -684,6 +684,9 @@ class OpenShiftCluster(TrackedResource): :vartype master_profile: ~azure.mgmt.redhatopenshift.v2023_09_04.models.MasterProfile :ivar worker_profiles: The cluster worker profiles. :vartype worker_profiles: list[~azure.mgmt.redhatopenshift.v2023_09_04.models.WorkerProfile] + :ivar worker_profiles_status: The cluster worker profiles status. + :vartype worker_profiles_status: + list[~azure.mgmt.redhatopenshift.v2023_09_04.models.WorkerProfile] :ivar apiserver_profile: The cluster API server profile. :vartype apiserver_profile: ~azure.mgmt.redhatopenshift.v2023_09_04.models.APIServerProfile :ivar ingress_profiles: The cluster ingress profiles. @@ -696,6 +699,7 @@ class OpenShiftCluster(TrackedResource): 'type': {'readonly': True}, 'system_data': {'readonly': True}, 'location': {'required': True}, + 'worker_profiles_status': {'readonly': True}, } _attribute_map = { @@ -712,6 +716,7 @@ class OpenShiftCluster(TrackedResource): 'network_profile': {'key': 'properties.networkProfile', 'type': 'NetworkProfile'}, 'master_profile': {'key': 'properties.masterProfile', 'type': 'MasterProfile'}, 'worker_profiles': {'key': 'properties.workerProfiles', 'type': '[WorkerProfile]'}, + 'worker_profiles_status': {'key': 'properties.workerProfilesStatus', 'type': '[WorkerProfile]'}, 'apiserver_profile': {'key': 'properties.apiserverProfile', 'type': 'APIServerProfile'}, 'ingress_profiles': {'key': 'properties.ingressProfiles', 'type': '[IngressProfile]'}, } @@ -768,6 +773,7 @@ def __init__( self.network_profile = network_profile self.master_profile = master_profile self.worker_profiles = worker_profiles + self.worker_profiles_status = None self.apiserver_profile = apiserver_profile self.ingress_profiles = ingress_profiles @@ -887,6 +893,9 @@ class OpenShiftClusterUpdate(msrest.serialization.Model): :vartype master_profile: ~azure.mgmt.redhatopenshift.v2023_09_04.models.MasterProfile :ivar worker_profiles: The cluster worker profiles. :vartype worker_profiles: list[~azure.mgmt.redhatopenshift.v2023_09_04.models.WorkerProfile] + :ivar worker_profiles_status: The cluster worker profiles status. + :vartype worker_profiles_status: + list[~azure.mgmt.redhatopenshift.v2023_09_04.models.WorkerProfile] :ivar apiserver_profile: The cluster API server profile. :vartype apiserver_profile: ~azure.mgmt.redhatopenshift.v2023_09_04.models.APIServerProfile :ivar ingress_profiles: The cluster ingress profiles. @@ -895,6 +904,7 @@ class OpenShiftClusterUpdate(msrest.serialization.Model): _validation = { 'system_data': {'readonly': True}, + 'worker_profiles_status': {'readonly': True}, } _attribute_map = { @@ -907,6 +917,7 @@ class OpenShiftClusterUpdate(msrest.serialization.Model): 'network_profile': {'key': 'properties.networkProfile', 'type': 'NetworkProfile'}, 'master_profile': {'key': 'properties.masterProfile', 'type': 'MasterProfile'}, 'worker_profiles': {'key': 'properties.workerProfiles', 'type': '[WorkerProfile]'}, + 'worker_profiles_status': {'key': 'properties.workerProfilesStatus', 'type': '[WorkerProfile]'}, 'apiserver_profile': {'key': 'properties.apiserverProfile', 'type': 'APIServerProfile'}, 'ingress_profiles': {'key': 'properties.ingressProfiles', 'type': '[IngressProfile]'}, } @@ -962,6 +973,7 @@ def __init__( self.network_profile = network_profile self.master_profile = master_profile self.worker_profiles = worker_profiles + self.worker_profiles_status = None self.apiserver_profile = apiserver_profile self.ingress_profiles = ingress_profiles diff --git a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_Get.json b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_Get.json index c664e74d902..3c6d656092c 100644 --- a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_Get.json +++ b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_Get.json @@ -54,6 +54,29 @@ "count": 3 } ], + "workerProfilesStatus": [ + { + "name": "worker1", + "vmSize": "Standard_D2s_v3", + "diskSizeGB": 128, + "subnetId": "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + "count": 1 + }, + { + "name": "worker2", + "vmSize": "Standard_D2s_v3", + "diskSizeGB": 128, + "subnetId": "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + "count": 1 + }, + { + "name": "worker3", + "vmSize": "Standard_D2s_v3", + "diskSizeGB": 128, + "subnetId": "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + "count": 1 + } + ], "apiserverProfile": { "visibility": "Public", "url": "https://api.cluster.location.aroapp.io:6443/", diff --git a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_List.json b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_List.json index 21f1a360743..7e3e54c8ff2 100644 --- a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_List.json +++ b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_List.json @@ -54,6 +54,29 @@ "count": 3 } ], + "workerProfilesStatus": [ + { + "name": "worker1", + "vmSize": "Standard_D2s_v3", + "diskSizeGB": 128, + "subnetId": "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + "count": 1 + }, + { + "name": "worker2", + "vmSize": "Standard_D2s_v3", + "diskSizeGB": 128, + "subnetId": "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + "count": 1 + }, + { + "name": "worker3", + "vmSize": "Standard_D2s_v3", + "diskSizeGB": 128, + "subnetId": "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + "count": 1 + } + ], "apiserverProfile": { "visibility": "Public", "url": "https://api.cluster.location.aroapp.io:6443/", diff --git a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_ListByResourceGroup.json b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_ListByResourceGroup.json index 983daf1e49c..552454c7cad 100644 --- a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_ListByResourceGroup.json +++ b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/examples/OpenShiftClusters_ListByResourceGroup.json @@ -55,6 +55,29 @@ "count": 3 } ], + "workerProfilesStatus": [ + { + "name": "worker1", + "vmSize": "Standard_D2s_v3", + "diskSizeGB": 128, + "subnetId": "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + "count": 1 + }, + { + "name": "worker2", + "vmSize": "Standard_D2s_v3", + "diskSizeGB": 128, + "subnetId": "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + "count": 1 + }, + { + "name": "worker3", + "vmSize": "Standard_D2s_v3", + "diskSizeGB": 128, + "subnetId": "/subscriptions/subscriptionId/resourceGroups/vnetResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet/subnets/worker", + "count": 1 + } + ], "apiserverProfile": { "visibility": "Public", "url": "https://api.cluster.location.aroapp.io:6443/", diff --git a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/redhatopenshift.json b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/redhatopenshift.json index 60479e8ab23..9441465a767 100644 --- a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/redhatopenshift.json +++ b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/redhatopenshift.json @@ -2097,6 +2097,15 @@ }, "x-ms-identifiers": [] }, + "workerProfilesStatus": { + "description": "The cluster worker profiles status.", + "type": "array", + "items": { + "$ref": "#/definitions/WorkerProfile" + }, + "readOnly": true, + "x-ms-identifiers": [] + }, "apiserverProfile": { "$ref": "#/definitions/APIServerProfile", "description": "The cluster API server profile." @@ -2234,11 +2243,7 @@ "Disabled", "Enabled" ], - "type": "string", - "x-ms-enum": { - "name": "PreconfiguredNSG", - "modelAsString": true - } + "type": "string" }, "ProvisioningState": { "description": "ProvisioningState represents a provisioning state.",