diff --git a/pkg/api/admin/platformworkloadidentityroleset.go b/pkg/api/admin/platformworkloadidentityroleset.go new file mode 100644 index 00000000000..9ed4680bceb --- /dev/null +++ b/pkg/api/admin/platformworkloadidentityroleset.go @@ -0,0 +1,46 @@ +package admin + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +// PlatformWorkloadIdentityRoleSetList represents a List of role sets. +type PlatformWorkloadIdentityRoleSetList struct { + // The list of role sets. + PlatformWorkloadIdentityRoleSets []*PlatformWorkloadIdentityRoleSet `json:"value"` +} + +// PlatformWorkloadIdentityRoleSet represents a mapping from the names of OCP operators to the built-in roles that should be assigned to those operator's corresponding managed identities for a particular OCP version. +type PlatformWorkloadIdentityRoleSet struct { + // The ID for the resource. + ID string `json:"id,omitempty" mutable:"case"` + + // Name of the resource. + Name string `json:"name,omitempty" mutable:"case"` + + // The properties for the PlatformWorkloadIdentityRoleSet resource. + Properties PlatformWorkloadIdentityRoleSetProperties `json:"properties,omitempty"` +} + +// PlatformWorkloadIdentityRoleSetProperties represents the properties of a PlatformWorkloadIdentityRoleSet resource. +type PlatformWorkloadIdentityRoleSetProperties struct { + // OpenShiftVersion represents the version associated with this set of roles. + OpenShiftVersion string `json:"openShiftVersion,omitempty"` + + // PlatformWorkloadIdentityRoles represents the set of roles associated with this version. + PlatformWorkloadIdentityRoles []PlatformWorkloadIdentityRole `json:"platformWorkloadIdentityRoles,omitempty" mutable:"true"` +} + +// PlatformWorkloadIdentityRole represents a mapping from a particular OCP operator to the built-in role that should be assigned to that operator's corresponding managed identity. +type PlatformWorkloadIdentityRole struct { + // OperatorName represents the name of the operator that this role is for. + OperatorName string `json:"operatorName,omitempty" mutable:"true"` + + // RoleDefinitionName represents the name of the role. + RoleDefinitionName string `json:"roleDefinitionName,omitempty" mutable:"true"` + + // RoleDefinitionID represents the resource ID of the role definition. + RoleDefinitionID string `json:"roleDefinitionId,omitempty" mutable:"true"` + + // ServiceAccounts represents the set of service accounts associated with the given operator, since each service account needs its own federated credential. + ServiceAccounts []string `json:"serviceAccounts,omitempty" mutable:"true"` +} diff --git a/pkg/api/admin/platformworkloadidentityroleset_convert.go b/pkg/api/admin/platformworkloadidentityroleset_convert.go new file mode 100644 index 00000000000..b1caa21cb63 --- /dev/null +++ b/pkg/api/admin/platformworkloadidentityroleset_convert.go @@ -0,0 +1,67 @@ +package admin + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +/* +TODO: Uncomment once API endpoints have been implemented and this code is being used. + +type platformWorkloadIdentityRoleSetConverter struct{} + +// platformWorkloadIdentityRoleSetConverter.ToExternal returns a new external representation +// of the internal object, reading from the subset of the internal object's +// fields that appear in the external representation. ToExternal does not +// modify its argument; there is no pointer aliasing between the passed and +// returned objects. +func (c platformWorkloadIdentityRoleSetConverter) ToExternal(s *api.PlatformWorkloadIdentityRoleSet) interface{} { + out := &PlatformWorkloadIdentityRoleSet{ + Properties: PlatformWorkloadIdentityRoleSetProperties{ + OpenShiftVersion: s.Properties.OpenShiftVersion, + PlatformWorkloadIdentityRoles: make([]PlatformWorkloadIdentityRole, 0, len(s.Properties.PlatformWorkloadIdentityRoles)), + }, + } + + for i, r := range s.Properties.PlatformWorkloadIdentityRoles { + out.Properties.PlatformWorkloadIdentityRoles[i].OperatorName = r.OperatorName + out.Properties.PlatformWorkloadIdentityRoles[i].RoleDefinitionName = r.RoleDefinitionName + out.Properties.PlatformWorkloadIdentityRoles[i].RoleDefinitionID = r.RoleDefinitionID + out.Properties.PlatformWorkloadIdentityRoles[i].ServiceAccounts = make([]string, 0, len(r.ServiceAccounts)) + out.Properties.PlatformWorkloadIdentityRoles[i].ServiceAccounts = append(out.Properties.PlatformWorkloadIdentityRoles[i].ServiceAccounts, r.ServiceAccounts...) + } + + return out +} + +// ToExternalList returns a slice of external representations of the internal +// objects +func (c platformWorkloadIdentityRoleSetConverter) ToExternalList(sets []*api.PlatformWorkloadIdentityRoleSet) interface{} { + l := &PlatformWorkloadIdentityRoleSetList{ + PlatformWorkloadIdentityRoleSets: make([]*PlatformWorkloadIdentityRoleSet, 0, len(sets)), + } + + for _, set := range sets { + l.PlatformWorkloadIdentityRoleSets = append(l.PlatformWorkloadIdentityRoleSets, c.ToExternal(set).(*PlatformWorkloadIdentityRoleSet)) + } + + return l +} + +// ToInternal overwrites in place a pre-existing internal object, setting (only) +// all mapped fields from the external representation. ToInternal modifies its +// argument; there is no pointer aliasing between the passed and returned +// objects +func (c platformWorkloadIdentityRoleSetConverter) ToInternal(_new interface{}, out *api.PlatformWorkloadIdentityRoleSet) { + new := _new.(*PlatformWorkloadIdentityRoleSet) + + out.Properties.OpenShiftVersion = new.Properties.OpenShiftVersion + out.Properties.PlatformWorkloadIdentityRoles = make([]api.PlatformWorkloadIdentityRole, 0, len(new.Properties.PlatformWorkloadIdentityRoles)) + + for i, r := range new.Properties.PlatformWorkloadIdentityRoles { + out.Properties.PlatformWorkloadIdentityRoles[i].OperatorName = r.OperatorName + out.Properties.PlatformWorkloadIdentityRoles[i].RoleDefinitionName = r.RoleDefinitionName + out.Properties.PlatformWorkloadIdentityRoles[i].RoleDefinitionID = r.RoleDefinitionID + out.Properties.PlatformWorkloadIdentityRoles[i].ServiceAccounts = make([]string, 0, len(r.ServiceAccounts)) + out.Properties.PlatformWorkloadIdentityRoles[i].ServiceAccounts = append(out.Properties.PlatformWorkloadIdentityRoles[i].ServiceAccounts, r.ServiceAccounts...) + } +} +*/ diff --git a/pkg/api/admin/platformworkloadidentityroleset_validatestatic.go b/pkg/api/admin/platformworkloadidentityroleset_validatestatic.go new file mode 100644 index 00000000000..a45348e069c --- /dev/null +++ b/pkg/api/admin/platformworkloadidentityroleset_validatestatic.go @@ -0,0 +1,67 @@ +package admin + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +/* +TODO: Uncomment once API endpoints have been implemented and this code is being used. + +type platformWorkloadIdentityRoleSetStaticValidator struct{} + +func (sv platformWorkloadIdentityRoleSetStaticValidator) Static(_new interface{}, _current *api.PlatformWorkloadIdentityRoleSet) error { + new := _new.(*PlatformWorkloadIdentityRoleSet) + + var current *PlatformWorkloadIdentityRoleSet + if _current != nil { + current = (&platformWorkloadIdentityRoleSetConverter{}).ToExternal(_current).(*PlatformWorkloadIdentityRoleSet) + } + + err := sv.validate(new, current == nil) + if err != nil { + return err + } + + if current == nil { + return nil + } + + return sv.validateDelta(new, current) +} + +func (sv platformWorkloadIdentityRoleSetStaticValidator) validate(new *PlatformWorkloadIdentityRoleSet, isCreate bool) error { + if new.Properties.OpenShiftVersion == "" { + return api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidParameter, "properties.openShiftVersion", "Must be provided") + } + + if new.Properties.PlatformWorkloadIdentityRoles == nil || len(new.Properties.PlatformWorkloadIdentityRoles) == 0 { + return api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidParameter, "properties.platformWorkloadIdentityRoles", "Must be provided and must be non-empty") + } + + errs := []error{} + + for i, r := range new.Properties.PlatformWorkloadIdentityRoles { + if r.OperatorName == "" { + errs = append(errs, api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidParameter, fmt.Sprintf("properties.platformWorkloadIdentityRoles[%d].operatorName", i), "Must be provided")) + } + + if r.RoleDefinitionName == "" { + errs = append(errs, api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidParameter, fmt.Sprintf("properties.platformWorkloadIdentityRoles[%d].roleDefinitionName", i), "Must be provided")) + } + + if r.RoleDefinitionID == "" { + errs = append(errs, api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidParameter, fmt.Sprintf("properties.platformWorkloadIdentityRoles[%d].roleDefinitionId", i), "Must be provided")) + } + } + + return errors.Join(errs...) +} + +func (sv platformWorkloadIdentityRoleSetStaticValidator) validateDelta(new, current *PlatformWorkloadIdentityRoleSet) error { + err := immutable.Validate("", new, current) + if err != nil { + err := err.(*immutable.ValidationError) + return api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodePropertyChangeNotAllowed, err.Target, err.Message) + } + return nil +} +*/ diff --git a/pkg/api/platformworkloadidentityroleset.go b/pkg/api/platformworkloadidentityroleset.go new file mode 100644 index 00000000000..372eab1c883 --- /dev/null +++ b/pkg/api/platformworkloadidentityroleset.go @@ -0,0 +1,30 @@ +package api + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +// PlatformWorkloadIdentityRoleSet represents a mapping from the names of OCP operators to the built-in roles that should be assigned to those operator's corresponding managed identities for a particular OCP version. +type PlatformWorkloadIdentityRoleSet struct { + MissingFields + + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` + Deleting bool `json:"deleting,omitempty"` // https://docs.microsoft.com/en-us/azure/cosmos-db/change-feed-design-patterns#deletes + + Properties PlatformWorkloadIdentityRoleSetProperties `json:"properties,omitempty"` +} + +// PlatformWorkloadIdentityRoleSetProperties represents the properties of a PlatformWorkloadIdentityRoleSet resource. +type PlatformWorkloadIdentityRoleSetProperties struct { + OpenShiftVersion string `json:"openShiftVersion,omitempty"` + PlatformWorkloadIdentityRoles []PlatformWorkloadIdentityRole `json:"platformWorkloadIdentityRoles,omitempty"` +} + +// PlatformWorkloadIdentityRole represents a mapping from a particular OCP operator to the built-in role that should be assigned to that operator's corresponding managed identity. +type PlatformWorkloadIdentityRole struct { + OperatorName string `json:"operatorName,omitempty"` + RoleDefinitionName string `json:"roleDefinitionName,omitempty"` + RoleDefinitionID string `json:"roleDefinitionId,omitempty"` + ServiceAccounts []string `json:"serviceAccounts,omitempty"` +} diff --git a/pkg/api/platformworkloadidentityrolesetdocument.go b/pkg/api/platformworkloadidentityrolesetdocument.go new file mode 100644 index 00000000000..f9eee2d8b02 --- /dev/null +++ b/pkg/api/platformworkloadidentityrolesetdocument.go @@ -0,0 +1,38 @@ +package api + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +// PlatformWorkloadIdentityRoleSetDocuments represents a set of PlatformWorkloadIdentityRoleSetDocuments. +// pkg/database/cosmosdb requires its definition. +type PlatformWorkloadIdentityRoleSetDocuments struct { + Count int `json:"_count,omitempty"` + ResourceID string `json:"_rid,omitempty"` + PlatformWorkloadIdentityRoleSetDocuments []*PlatformWorkloadIdentityRoleSetDocument `json:"Documents,omitempty"` +} + +func (c *PlatformWorkloadIdentityRoleSetDocuments) String() string { + return encodeJSON(c) +} + +// PlatformWorkloadIdentityRoleSetDocument represents a document specifying a mapping from the names of OCP operators to the built-in roles that should be assigned to those operator's corresponding managed identities for a particular OCP version. +// pkg/database/cosmosdb requires its definition. +type PlatformWorkloadIdentityRoleSetDocument struct { + MissingFields + + ID string `json:"id,omitempty"` + ResourceID string `json:"_rid,omitempty"` + Timestamp int `json:"_ts,omitempty"` + Self string `json:"_self,omitempty"` + ETag string `json:"_etag,omitempty" deep:"-"` + Attachments string `json:"_attachments,omitempty"` + TTL int `json:"ttl,omitempty"` + LSN int `json:"_lsn,omitempty"` + Metadata map[string]interface{} `json:"_metadata,omitempty"` + + PlatformWorkloadIdentityRoleSet *PlatformWorkloadIdentityRoleSet `json:"platformWorkloadIdentityRoleSet,omitempty"` +} + +func (c *PlatformWorkloadIdentityRoleSetDocument) String() string { + return encodeJSON(c) +} diff --git a/pkg/api/platformworkloadidentityrolesetdocument_example.go b/pkg/api/platformworkloadidentityrolesetdocument_example.go new file mode 100644 index 00000000000..12fd32f2362 --- /dev/null +++ b/pkg/api/platformworkloadidentityrolesetdocument_example.go @@ -0,0 +1,29 @@ +package api + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +func ExamplePlatformWorkloadIdentityRoleSetDocument() *PlatformWorkloadIdentityRoleSetDocument { + return &PlatformWorkloadIdentityRoleSetDocument{ + MissingFields: MissingFields{}, + ID: "00000000-0000-0000-0000-000000000000", + PlatformWorkloadIdentityRoleSet: &PlatformWorkloadIdentityRoleSet{ + ID: "00000000-0000-0000-0000-000000000000", + Name: "4.14", + Type: "Microsoft.RedHatOpenShift/PlatformWorkloadIdentityRoleSet", + Properties: PlatformWorkloadIdentityRoleSetProperties{ + OpenShiftVersion: "4.14", + PlatformWorkloadIdentityRoles: []PlatformWorkloadIdentityRole{ + { + OperatorName: "ServiceOperator", + RoleDefinitionName: "AzureRedHatOpenShiftServiceOperator", + RoleDefinitionID: "/providers/Microsoft.Authorization/roleDefinitions/00000000-0000-0000-0000-000000000000", + ServiceAccounts: []string{ + "aro-operator-master", + }, + }, + }, + }, + }, + } +} diff --git a/pkg/api/v20240812preview/platformworkloadidentityroleset.go b/pkg/api/v20240812preview/platformworkloadidentityroleset.go new file mode 100644 index 00000000000..b944b967547 --- /dev/null +++ b/pkg/api/v20240812preview/platformworkloadidentityroleset.go @@ -0,0 +1,51 @@ +package v20240812preview + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +// PlatformWorkloadIdentityRoleSetList represents a List of role sets. +type PlatformWorkloadIdentityRoleSetList struct { + // The list of role sets. + PlatformWorkloadIdentityRoleSets []*PlatformWorkloadIdentityRoleSet `json:"value"` + + // Next Link to next operation. + NextLink string `json:"nextLink,omitempty"` +} + +// PlatformWorkloadIdentityRoleSet represents a mapping from the names of OCP operators to the built-in roles that should be assigned to those operator's corresponding managed identities for a particular OCP version. +type PlatformWorkloadIdentityRoleSet struct { + proxyResource bool + + // The ID for the resource. + ID string `json:"id,omitempty" mutable:"case"` + + // Name of the resource. + Name string `json:"name,omitempty" mutable:"case"` + + // The resource type. + Type string `json:"type,omitempty" mutable:"case"` + + // The properties for the PlatformWorkloadIdentityRoleSet resource. + Properties PlatformWorkloadIdentityRoleSetProperties `json:"properties,omitempty"` +} + +// PlatformWorkloadIdentityRoleSetProperties represents the properties of a PlatformWorkloadIdentityRoleSet resource. +type PlatformWorkloadIdentityRoleSetProperties struct { + // OpenShiftVersion represents the version associated with this set of roles. + OpenShiftVersion string `json:"openShiftVersion,omitempty"` + + // PlatformWorkloadIdentityRoles represents the set of roles associated with this version. + PlatformWorkloadIdentityRoles []PlatformWorkloadIdentityRole `json:"platformWorkloadIdentityRoles,omitempty"` +} + +// PlatformWorkloadIdentityRole represents a mapping from a particular OCP operator to the built-in role that should be assigned to that operator's corresponding managed identity. +type PlatformWorkloadIdentityRole struct { + // OperatorName represents the name of the operator that this role is for. + OperatorName string `json:"operatorName,omitempty"` + + // RoleDefinitionName represents the name of the role. + RoleDefinitionName string `json:"roleDefinitionName,omitempty"` + + // RoleDefinitionID represents the resource ID of the role definition. + RoleDefinitionID string `json:"roleDefinitionId,omitempty"` +} diff --git a/pkg/api/v20240812preview/platformworkloadidentityroleset_convert.go b/pkg/api/v20240812preview/platformworkloadidentityroleset_convert.go new file mode 100644 index 00000000000..a651229c16f --- /dev/null +++ b/pkg/api/v20240812preview/platformworkloadidentityroleset_convert.go @@ -0,0 +1,65 @@ +package v20240812preview + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import ( + "github.com/Azure/ARO-RP/pkg/api" +) + +type platformWorkloadIdentityRoleSetConverter struct{} + +// platformWorkloadIdentityRoleSetConverter.ToExternal returns a new external representation +// of the internal object, reading from the subset of the internal object's +// fields that appear in the external representation. ToExternal does not +// modify its argument; there is no pointer aliasing between the passed and +// returned objects. +func (c platformWorkloadIdentityRoleSetConverter) ToExternal(s *api.PlatformWorkloadIdentityRoleSet) interface{} { + out := &PlatformWorkloadIdentityRoleSet{ + ID: s.ID, + proxyResource: true, + Properties: PlatformWorkloadIdentityRoleSetProperties{ + OpenShiftVersion: s.Properties.OpenShiftVersion, + PlatformWorkloadIdentityRoles: make([]PlatformWorkloadIdentityRole, 0, len(s.Properties.PlatformWorkloadIdentityRoles)), + }, + } + + for i, r := range s.Properties.PlatformWorkloadIdentityRoles { + out.Properties.PlatformWorkloadIdentityRoles[i].OperatorName = r.OperatorName + out.Properties.PlatformWorkloadIdentityRoles[i].RoleDefinitionName = r.RoleDefinitionName + out.Properties.PlatformWorkloadIdentityRoles[i].RoleDefinitionID = r.RoleDefinitionID + } + + return out +} + +// ToExternalList returns a slice of external representations of the internal +// objects +func (c platformWorkloadIdentityRoleSetConverter) ToExternalList(sets []*api.PlatformWorkloadIdentityRoleSet) interface{} { + l := &PlatformWorkloadIdentityRoleSetList{ + PlatformWorkloadIdentityRoleSets: make([]*PlatformWorkloadIdentityRoleSet, 0, len(sets)), + } + + for _, set := range sets { + l.PlatformWorkloadIdentityRoleSets = append(l.PlatformWorkloadIdentityRoleSets, c.ToExternal(set).(*PlatformWorkloadIdentityRoleSet)) + } + + return l +} + +// ToInternal overwrites in place a pre-existing internal object, setting (only) +// all mapped fields from the external representation. ToInternal modifies its +// argument; there is no pointer aliasing between the passed and returned +// objects +func (c platformWorkloadIdentityRoleSetConverter) ToInternal(_new interface{}, out *api.PlatformWorkloadIdentityRoleSet) { + new := _new.(*PlatformWorkloadIdentityRoleSet) + + out.Properties.OpenShiftVersion = new.Properties.OpenShiftVersion + out.Properties.PlatformWorkloadIdentityRoles = make([]api.PlatformWorkloadIdentityRole, 0, len(new.Properties.PlatformWorkloadIdentityRoles)) + + for i, r := range new.Properties.PlatformWorkloadIdentityRoles { + out.Properties.PlatformWorkloadIdentityRoles[i].OperatorName = r.OperatorName + out.Properties.PlatformWorkloadIdentityRoles[i].RoleDefinitionName = r.RoleDefinitionName + out.Properties.PlatformWorkloadIdentityRoles[i].RoleDefinitionID = r.RoleDefinitionID + } +} diff --git a/pkg/api/v20240812preview/platformworkloadidentityroleset_example.go b/pkg/api/v20240812preview/platformworkloadidentityroleset_example.go new file mode 100644 index 00000000000..6cf6a1d0934 --- /dev/null +++ b/pkg/api/v20240812preview/platformworkloadidentityroleset_example.go @@ -0,0 +1,24 @@ +package v20240812preview + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import "github.com/Azure/ARO-RP/pkg/api" + +func examplePlatformWorkloadIdentityRoleSet() *PlatformWorkloadIdentityRoleSet { + doc := api.ExamplePlatformWorkloadIdentityRoleSetDocument() + ext := (&platformWorkloadIdentityRoleSetConverter{}).ToExternal(doc.PlatformWorkloadIdentityRoleSet) + return ext.(*PlatformWorkloadIdentityRoleSet) +} + +func ExamplePlatformWorkloadIdentityRoleSetResponse() interface{} { + return examplePlatformWorkloadIdentityRoleSet() +} + +func ExamplePlatformWorkloadIdentityRoleSetListResponse() interface{} { + return &PlatformWorkloadIdentityRoleSetList{ + PlatformWorkloadIdentityRoleSets: []*PlatformWorkloadIdentityRoleSet{ + ExamplePlatformWorkloadIdentityRoleSetResponse().(*PlatformWorkloadIdentityRoleSet), + }, + } +}