Update cluster lifecycle API fields to readOnly (#3380)

* Exclude Python AAZ client from license hack script
* Update clusterProfile url, apiserverProfile url and ip, ingressProfile ip, systemdata to be readonly in v20231122 API
* Update swagger json (generated)
* Update API static validation tests and converter to respect readOnly fields
* Update generated client SDKs
This commit is contained in:
Tanmay Satam 2024-02-08 12:35:17 -05:00 коммит произвёл GitHub
Родитель b359efd540
Коммит 9eb8db1e4e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
9 изменённых файлов: 146 добавлений и 71 удалений

Просмотреть файл

@ -5,4 +5,4 @@ b1f1de0fe40d05de90742b17928968923b936adc294000f58974f50a297581dd swagger/redhat
01ba9562a8dac2824998ff0ad0d2465f79e6a66597bdb321e9409b9f2d12d222 swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-04-01/redhatopenshift.json
c023515341196746454c0ae7af077d40d3ec13f6b88b33cb558f0a7ab17a5a24 swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/preview/2023-07-01-preview/redhatopenshift.json
440748951dd1c3b34b5ccbdcb7cd966e3b89490887a1f1d64429561fad789515 swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-09-04/redhatopenshift.json
98b241e3225ff4bbe96f4046aea98dae06c2bac2cc0e25ab8d85583bfc7f1861 swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-11-22/redhatopenshift.json
a1052ac8642527343815b212823c7c22f1edf9690b1004041b9ef6bab5b10393 swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2023-11-22/redhatopenshift.json

Просмотреть файл

@ -106,7 +106,7 @@ func applyPythonLicense() error {
}
switch path {
case "python/client", "vendor":
case "python/client", "vendor", "python/az/aro/azext_aro/aaz":
return filepath.SkipDir
}

Просмотреть файл

@ -29,7 +29,7 @@ type OpenShiftCluster struct {
Location string `json:"location,omitempty"`
// SystemData - The system metadata relating to this resource
SystemData *SystemData `json:"systemData,omitempty"`
SystemData *SystemData `json:"systemData,omitempty" swagger:"readOnly"`
// The resource tags.
Tags Tags `json:"tags,omitempty" mutable:"true"`
@ -119,7 +119,7 @@ type ClusterProfile struct {
// ConsoleProfile represents a console profile.
type ConsoleProfile struct {
// The URL to access the cluster console.
URL string `json:"url,omitempty"`
URL string `json:"url,omitempty" swagger:"readOnly"`
}
// ServicePrincipalProfile represents a service principal profile.
@ -249,10 +249,10 @@ type APIServerProfile struct {
Visibility Visibility `json:"visibility,omitempty"`
// The URL to access the cluster API server.
URL string `json:"url,omitempty"`
URL string `json:"url,omitempty" swagger:"readOnly"`
// The IP of the cluster API server.
IP string `json:"ip,omitempty"`
IP string `json:"ip,omitempty" swagger:"readOnly"`
}
// Visibility represents visibility.
@ -273,7 +273,7 @@ type IngressProfile struct {
Visibility Visibility `json:"visibility,omitempty"`
// The IP of the ingress.
IP string `json:"ip,omitempty"`
IP string `json:"ip,omitempty" swagger:"readOnly"`
}
// CreatedByType by defines user type, which executed the request

Просмотреть файл

@ -174,7 +174,9 @@ func (c openShiftClusterConverter) ToInternal(_oc interface{}, out *api.OpenShif
out.Properties.ClusterProfile.Domain = oc.Properties.ClusterProfile.Domain
out.Properties.ClusterProfile.Version = oc.Properties.ClusterProfile.Version
out.Properties.ClusterProfile.ResourceGroupID = oc.Properties.ClusterProfile.ResourceGroupID
out.Properties.ConsoleProfile.URL = oc.Properties.ConsoleProfile.URL
if oc.Properties.ConsoleProfile.URL != "" {
out.Properties.ConsoleProfile.URL = oc.Properties.ConsoleProfile.URL
}
out.Properties.ClusterProfile.FipsValidatedModules = api.FipsValidatedModules(oc.Properties.ClusterProfile.FipsValidatedModules)
out.Properties.ServicePrincipalProfile.ClientID = oc.Properties.ServicePrincipalProfile.ClientID
out.Properties.ServicePrincipalProfile.ClientSecret = api.SecureString(oc.Properties.ServicePrincipalProfile.ClientSecret)
@ -238,25 +240,33 @@ func (c openShiftClusterConverter) ToInternal(_oc interface{}, out *api.OpenShif
}
}
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
if oc.Properties.APIServerProfile.URL != "" {
out.Properties.APIServerProfile.URL = oc.Properties.APIServerProfile.URL
}
if oc.Properties.APIServerProfile.IP != "" {
out.Properties.APIServerProfile.IP = oc.Properties.APIServerProfile.IP
}
out.Properties.IngressProfiles = nil
if oc.Properties.IngressProfiles != nil {
out.Properties.IngressProfiles = make([]api.IngressProfile, len(oc.Properties.IngressProfiles))
for i := range oc.Properties.IngressProfiles {
out.Properties.IngressProfiles[i].Name = oc.Properties.IngressProfiles[i].Name
out.Properties.IngressProfiles[i].Visibility = api.Visibility(oc.Properties.IngressProfiles[i].Visibility)
out.Properties.IngressProfiles[i].IP = oc.Properties.IngressProfiles[i].IP
if oc.Properties.IngressProfiles[i].IP != "" {
out.Properties.IngressProfiles[i].IP = oc.Properties.IngressProfiles[i].IP
}
}
}
out.SystemData = api.SystemData{
CreatedBy: oc.SystemData.CreatedBy,
CreatedAt: oc.SystemData.CreatedAt,
CreatedByType: api.CreatedByType(oc.SystemData.CreatedByType),
LastModifiedBy: oc.SystemData.LastModifiedBy,
LastModifiedAt: oc.SystemData.LastModifiedAt,
LastModifiedByType: api.CreatedByType(oc.SystemData.CreatedByType),
if oc.SystemData != nil {
out.SystemData = api.SystemData{
CreatedBy: oc.SystemData.CreatedBy,
CreatedAt: oc.SystemData.CreatedAt,
CreatedByType: api.CreatedByType(oc.SystemData.CreatedByType),
LastModifiedBy: oc.SystemData.LastModifiedBy,
LastModifiedAt: oc.SystemData.LastModifiedAt,
LastModifiedByType: api.CreatedByType(oc.SystemData.CreatedByType),
}
}
}

Просмотреть файл

@ -34,6 +34,11 @@ type testMode string
const (
testModeCreate testMode = "Create"
testModeUpdate testMode = "Update"
consoleProfileUrl = "https://console-openshift-console.apps.cluster.location.aroapp.io/"
apiserverProfileUrl = "https://api.cluster.location.aroapp.io:6443/"
apiserverProfileIp = "1.2.3.4"
ingressProfileIp = "1.2.3.4"
)
var (
@ -44,12 +49,23 @@ func getResourceID(clusterName string) string {
return fmt.Sprintf("/subscriptions/%s/resourcegroups/resourceGroup/providers/microsoft.redhatopenshift/openshiftclusters/%s", subscriptionID, clusterName)
}
func validOpenShiftCluster(name, location string) *OpenShiftCluster {
func validSystemData() *SystemData {
timestamp, err := time.Parse(time.RFC3339, "2021-01-23T12:34:54.0000000Z")
if err != nil {
panic(err)
}
return &SystemData{
CreatedBy: "00000000-0000-0000-0000-000000000000",
CreatedByType: CreatedByTypeApplication,
CreatedAt: &timestamp,
LastModifiedBy: "00000000-0000-0000-0000-000000000000",
LastModifiedByType: CreatedByTypeApplication,
LastModifiedAt: &timestamp,
}
}
func validOpenShiftCluster(name, location string) *OpenShiftCluster {
oc := &OpenShiftCluster{
ID: getResourceID(name),
Name: name,
@ -58,14 +74,6 @@ func validOpenShiftCluster(name, location string) *OpenShiftCluster {
Tags: Tags{
"key": "value",
},
SystemData: &SystemData{
CreatedBy: "00000000-0000-0000-0000-000000000000",
CreatedByType: CreatedByTypeApplication,
CreatedAt: &timestamp,
LastModifiedBy: "00000000-0000-0000-0000-000000000000",
LastModifiedByType: CreatedByTypeApplication,
LastModifiedAt: &timestamp,
},
Properties: OpenShiftClusterProperties{
ProvisioningState: ProvisioningStateSucceeded,
ClusterProfile: ClusterProfile{
@ -76,7 +84,7 @@ func validOpenShiftCluster(name, location string) *OpenShiftCluster {
FipsValidatedModules: FipsValidatedModulesDisabled,
},
ConsoleProfile: ConsoleProfile{
URL: "https://console-openshift-console.apps.cluster.location.aroapp.io/",
URL: "",
},
ServicePrincipalProfile: ServicePrincipalProfile{
ClientSecret: "clientSecret",
@ -109,14 +117,14 @@ func validOpenShiftCluster(name, location string) *OpenShiftCluster {
},
APIServerProfile: APIServerProfile{
Visibility: VisibilityPublic,
URL: "https://api.cluster.location.aroapp.io:6443/",
IP: "1.2.3.4",
URL: "",
IP: "",
},
IngressProfiles: []IngressProfile{
{
Name: "default",
Visibility: VisibilityPublic,
IP: "1.2.3.4",
IP: "",
},
},
},
@ -168,7 +176,15 @@ func runTests(t *testing.T, mode testMode, tests []*validateTest) {
var current *api.OpenShiftCluster
if mode == testModeUpdate {
current = &api.OpenShiftCluster{}
(&openShiftClusterConverter{}).ToInternal(validOCForTest(), current)
ext := validOCForTest()
ext.SystemData = validSystemData()
ext.Properties.ConsoleProfile.URL = consoleProfileUrl
ext.Properties.APIServerProfile.URL = apiserverProfileUrl
ext.Properties.APIServerProfile.IP = apiserverProfileIp
ext.Properties.IngressProfiles[0].IP = ingressProfileIp
(&openShiftClusterConverter{}).ToInternal(ext, current)
}
err := v.Static(oc, current, v.location, v.domain, tt.requireD2sV3Workers, v.resourceID)
@ -1075,14 +1091,15 @@ func TestOpenShiftClusterStaticValidateDelta(t *testing.T) {
modify: func(oc *OpenShiftCluster) {
oc.SystemData = &SystemData{}
},
wantErr: "400: PropertyChangeNotAllowed: systemData.createdBy: Changing property 'systemData.createdBy' is not allowed.",
wantErr: "400: PropertyChangeNotAllowed: systemData: Changing property 'systemData' is not allowed.",
},
{
name: "systemData LastUpdated changed",
modify: func(oc *OpenShiftCluster) {
oc.SystemData = &SystemData{}
oc.SystemData.LastModifiedBy = "Bob"
},
wantErr: "400: PropertyChangeNotAllowed: systemData.lastModifiedBy: Changing property 'systemData.lastModifiedBy' is not allowed.",
wantErr: "400: PropertyChangeNotAllowed: systemData: Changing property 'systemData' is not allowed.",
},
{
name: "update LoadBalancerProfile.ManagedOutboundIPs.Count",

Просмотреть файл

@ -36,12 +36,21 @@ const fqdn = "github.com/Azure/ARO-RP/pkg/client/services/redhatopenshift/mgmt/2
type APIServerProfile struct {
// Visibility - API server visibility. Possible values include: 'Private', 'Public'
Visibility Visibility `json:"visibility,omitempty"`
// URL - The URL to access the cluster API server.
// URL - READ-ONLY; The URL to access the cluster API server.
URL *string `json:"url,omitempty"`
// IP - The IP of the cluster API server.
// IP - READ-ONLY; The IP of the cluster API server.
IP *string `json:"ip,omitempty"`
}
// MarshalJSON is the custom marshaler for APIServerProfile.
func (asp APIServerProfile) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
if asp.Visibility != "" {
objectMap["visibility"] = asp.Visibility
}
return json.Marshal(objectMap)
}
// AzureEntityResource the resource model definition for an Azure Resource Manager resource with an etag.
type AzureEntityResource struct {
// Etag - READ-ONLY; Resource Etag.
@ -96,10 +105,16 @@ type ClusterProfile struct {
// ConsoleProfile consoleProfile represents a console profile.
type ConsoleProfile struct {
// URL - The URL to access the cluster console.
// URL - READ-ONLY; The URL to access the cluster console.
URL *string `json:"url,omitempty"`
}
// MarshalJSON is the custom marshaler for ConsoleProfile.
func (cp ConsoleProfile) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
return json.Marshal(objectMap)
}
// Display display represents the display details of an operation.
type Display struct {
// Provider - Friendly name of the resource provider.
@ -125,10 +140,22 @@ type IngressProfile struct {
Name *string `json:"name,omitempty"`
// Visibility - Ingress visibility. Possible values include: 'Private', 'Public'
Visibility Visibility `json:"visibility,omitempty"`
// IP - The IP of the ingress.
// IP - READ-ONLY; The IP of the ingress.
IP *string `json:"ip,omitempty"`
}
// MarshalJSON is the custom marshaler for IngressProfile.
func (IP IngressProfile) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
if IP.Name != nil {
objectMap["name"] = IP.Name
}
if IP.Visibility != "" {
objectMap["visibility"] = IP.Visibility
}
return json.Marshal(objectMap)
}
// LoadBalancerProfile loadBalancerProfile represents the profile of the cluster public load balancer.
type LoadBalancerProfile struct {
// ManagedOutboundIps - The desired managed outbound IPs for the cluster public load balancer.

Просмотреть файл

@ -20,6 +20,8 @@ import msrest.serialization
class APIServerProfile(msrest.serialization.Model):
"""APIServerProfile represents an API server profile.
Variables are only populated by the server, and will be ignored when sending a request.
:ivar visibility: API server visibility. Possible values include: "Private", "Public".
:vartype visibility: str or ~azure.mgmt.redhatopenshift.v2023_11_22.models.Visibility
:ivar url: The URL to access the cluster API server.
@ -28,6 +30,11 @@ class APIServerProfile(msrest.serialization.Model):
:vartype ip: str
"""
_validation = {
'url': {'readonly': True},
'ip': {'readonly': True},
}
_attribute_map = {
'visibility': {'key': 'visibility', 'type': 'str'},
'url': {'key': 'url', 'type': 'str'},
@ -41,15 +48,11 @@ class APIServerProfile(msrest.serialization.Model):
"""
:keyword visibility: API server visibility. Possible values include: "Private", "Public".
:paramtype visibility: str or ~azure.mgmt.redhatopenshift.v2023_11_22.models.Visibility
:keyword url: The URL to access the cluster API server.
:paramtype url: str
:keyword ip: The IP of the cluster API server.
:paramtype ip: str
"""
super(APIServerProfile, self).__init__(**kwargs)
self.visibility = kwargs.get('visibility', None)
self.url = kwargs.get('url', None)
self.ip = kwargs.get('ip', None)
self.url = None
self.ip = None
class CloudErrorBody(msrest.serialization.Model):
@ -153,10 +156,16 @@ class ClusterProfile(msrest.serialization.Model):
class ConsoleProfile(msrest.serialization.Model):
"""ConsoleProfile represents a console profile.
Variables are only populated by the server, and will be ignored when sending a request.
:ivar url: The URL to access the cluster console.
:vartype url: str
"""
_validation = {
'url': {'readonly': True},
}
_attribute_map = {
'url': {'key': 'url', 'type': 'str'},
}
@ -166,11 +175,9 @@ class ConsoleProfile(msrest.serialization.Model):
**kwargs
):
"""
:keyword url: The URL to access the cluster console.
:paramtype url: str
"""
super(ConsoleProfile, self).__init__(**kwargs)
self.url = kwargs.get('url', None)
self.url = None
class Display(msrest.serialization.Model):
@ -240,6 +247,8 @@ class EffectiveOutboundIP(msrest.serialization.Model):
class IngressProfile(msrest.serialization.Model):
"""IngressProfile represents an ingress profile.
Variables are only populated by the server, and will be ignored when sending a request.
:ivar name: The ingress profile name.
:vartype name: str
:ivar visibility: Ingress visibility. Possible values include: "Private", "Public".
@ -248,6 +257,10 @@ class IngressProfile(msrest.serialization.Model):
:vartype ip: str
"""
_validation = {
'ip': {'readonly': True},
}
_attribute_map = {
'name': {'key': 'name', 'type': 'str'},
'visibility': {'key': 'visibility', 'type': 'str'},
@ -263,13 +276,11 @@ class IngressProfile(msrest.serialization.Model):
:paramtype name: str
:keyword visibility: Ingress visibility. Possible values include: "Private", "Public".
:paramtype visibility: str or ~azure.mgmt.redhatopenshift.v2023_11_22.models.Visibility
:keyword ip: The IP of the ingress.
:paramtype ip: str
"""
super(IngressProfile, self).__init__(**kwargs)
self.name = kwargs.get('name', None)
self.visibility = kwargs.get('visibility', None)
self.ip = kwargs.get('ip', None)
self.ip = None
class LoadBalancerProfile(msrest.serialization.Model):

Просмотреть файл

@ -25,6 +25,8 @@ from ._azure_red_hat_open_shift_client_enums import *
class APIServerProfile(msrest.serialization.Model):
"""APIServerProfile represents an API server profile.
Variables are only populated by the server, and will be ignored when sending a request.
:ivar visibility: API server visibility. Possible values include: "Private", "Public".
:vartype visibility: str or ~azure.mgmt.redhatopenshift.v2023_11_22.models.Visibility
:ivar url: The URL to access the cluster API server.
@ -33,6 +35,11 @@ class APIServerProfile(msrest.serialization.Model):
:vartype ip: str
"""
_validation = {
'url': {'readonly': True},
'ip': {'readonly': True},
}
_attribute_map = {
'visibility': {'key': 'visibility', 'type': 'str'},
'url': {'key': 'url', 'type': 'str'},
@ -43,22 +50,16 @@ class APIServerProfile(msrest.serialization.Model):
self,
*,
visibility: Optional[Union[str, "Visibility"]] = None,
url: Optional[str] = None,
ip: Optional[str] = None,
**kwargs
):
"""
:keyword visibility: API server visibility. Possible values include: "Private", "Public".
:paramtype visibility: str or ~azure.mgmt.redhatopenshift.v2023_11_22.models.Visibility
:keyword url: The URL to access the cluster API server.
:paramtype url: str
:keyword ip: The IP of the cluster API server.
:paramtype ip: str
"""
super(APIServerProfile, self).__init__(**kwargs)
self.visibility = visibility
self.url = url
self.ip = ip
self.url = None
self.ip = None
class CloudErrorBody(msrest.serialization.Model):
@ -173,26 +174,28 @@ class ClusterProfile(msrest.serialization.Model):
class ConsoleProfile(msrest.serialization.Model):
"""ConsoleProfile represents a console profile.
Variables are only populated by the server, and will be ignored when sending a request.
:ivar url: The URL to access the cluster console.
:vartype url: str
"""
_validation = {
'url': {'readonly': True},
}
_attribute_map = {
'url': {'key': 'url', 'type': 'str'},
}
def __init__(
self,
*,
url: Optional[str] = None,
**kwargs
):
"""
:keyword url: The URL to access the cluster console.
:paramtype url: str
"""
super(ConsoleProfile, self).__init__(**kwargs)
self.url = url
self.url = None
class Display(msrest.serialization.Model):
@ -269,6 +272,8 @@ class EffectiveOutboundIP(msrest.serialization.Model):
class IngressProfile(msrest.serialization.Model):
"""IngressProfile represents an ingress profile.
Variables are only populated by the server, and will be ignored when sending a request.
:ivar name: The ingress profile name.
:vartype name: str
:ivar visibility: Ingress visibility. Possible values include: "Private", "Public".
@ -277,6 +282,10 @@ class IngressProfile(msrest.serialization.Model):
:vartype ip: str
"""
_validation = {
'ip': {'readonly': True},
}
_attribute_map = {
'name': {'key': 'name', 'type': 'str'},
'visibility': {'key': 'visibility', 'type': 'str'},
@ -288,7 +297,6 @@ class IngressProfile(msrest.serialization.Model):
*,
name: Optional[str] = None,
visibility: Optional[Union[str, "Visibility"]] = None,
ip: Optional[str] = None,
**kwargs
):
"""
@ -296,13 +304,11 @@ class IngressProfile(msrest.serialization.Model):
:paramtype name: str
:keyword visibility: Ingress visibility. Possible values include: "Private", "Public".
:paramtype visibility: str or ~azure.mgmt.redhatopenshift.v2023_11_22.models.Visibility
:keyword ip: The IP of the ingress.
:paramtype ip: str
"""
super(IngressProfile, self).__init__(**kwargs)
self.name = name
self.visibility = visibility
self.ip = ip
self.ip = None
class LoadBalancerProfile(msrest.serialization.Model):

Просмотреть файл

@ -1744,11 +1744,13 @@
},
"url": {
"description": "The URL to access the cluster API server.",
"type": "string"
"type": "string",
"readOnly": true
},
"ip": {
"description": "The IP of the cluster API server.",
"type": "string"
"type": "string",
"readOnly": true
}
}
},
@ -1820,7 +1822,8 @@
"properties": {
"url": {
"description": "The URL to access the cluster console.",
"type": "string"
"type": "string",
"readOnly": true
}
}
},
@ -1894,7 +1897,8 @@
},
"ip": {
"description": "The IP of the ingress.",
"type": "string"
"type": "string",
"readOnly": true
}
}
},