Skip to content

Commit

Permalink
Merge pull request #3617 from Azure/cadenmarchese/ARO-6449/go-script
Browse files Browse the repository at this point in the history
New cmd to populate PlatformWorkloadIdentityRoleSets in dev and prod
  • Loading branch information
mociarain authored Jul 12, 2024
2 parents 6effeb1 + f2d528d commit 3cd8bc5
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 5 deletions.
11 changes: 6 additions & 5 deletions cmd/aro/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ package main
// Licensed under the Apache License 2.0.

const (
envDatabaseName = "DATABASE_NAME"
envDatabaseAccountName = "DATABASE_ACCOUNT_NAME"
envKeyVaultPrefix = "KEYVAULT_PREFIX"
envOpenShiftVersions = "OPENSHIFT_VERSIONS"
envInstallerImageDigests = "INSTALLER_IMAGE_DIGESTS"
envDatabaseName = "DATABASE_NAME"
envDatabaseAccountName = "DATABASE_ACCOUNT_NAME"
envKeyVaultPrefix = "KEYVAULT_PREFIX"
envOpenShiftVersions = "OPENSHIFT_VERSIONS"
envInstallerImageDigests = "INSTALLER_IMAGE_DIGESTS"
envPlatformWorkloadIdentityRoleSets = "PLATFORM_WORKLOAD_IDENTITY_ROLE_SETS"
)
4 changes: 4 additions & 0 deletions cmd/aro/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func usage() {
fmt.Fprintf(flag.CommandLine.Output(), " %s rp\n", os.Args[0])
fmt.Fprintf(flag.CommandLine.Output(), " %s operator {master,worker}\n", os.Args[0])
fmt.Fprintf(flag.CommandLine.Output(), " %s update-versions\n", os.Args[0])
fmt.Fprintf(flag.CommandLine.Output(), " %s update-role-sets\n", os.Args[0])
flag.PrintDefaults()
}

Expand Down Expand Up @@ -71,6 +72,9 @@ func main() {
case "update-versions":
checkArgs(1)
err = updateOCPVersions(ctx, log)
case "update-role-sets":
checkArgs(1)
err = updatePlatformWorkloadIdentityRoleSets(ctx, log)
default:
usage()
os.Exit(2)
Expand Down
169 changes: 169 additions & 0 deletions cmd/aro/update_role_sets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package main

// Copyright (c) Microsoft Corporation.
// Licensed under the Apache License 2.0.

import (
"context"
"fmt"
"os"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy"
"github.com/sirupsen/logrus"

"github.com/Azure/ARO-RP/pkg/api"
"github.com/Azure/ARO-RP/pkg/database"
"github.com/Azure/ARO-RP/pkg/env"
"github.com/Azure/ARO-RP/pkg/metrics/statsd"
"github.com/Azure/ARO-RP/pkg/util/encryption"
"github.com/Azure/ARO-RP/pkg/util/keyvault"
)

func getRoleSetsFromEnv() ([]api.PlatformWorkloadIdentityRoleSetProperties, error) {
const envKey = envPlatformWorkloadIdentityRoleSets
var roleSets []api.PlatformWorkloadIdentityRoleSetProperties

// Unmarshal env data into type api.PlatformWorkloadIdentityRoleSet
return roleSets, getEnvironmentData(envKey, &roleSets)
}

func getPlatformWorkloadIdentityRoleSetDatabase(ctx context.Context, log *logrus.Entry) (database.PlatformWorkloadIdentityRoleSets, error) {
_env, err := env.NewCore(ctx, log, env.COMPONENT_UPDATE_ROLE_SETS)
if err != nil {
return nil, err
}

msiToken, err := _env.NewMSITokenCredential()
if err != nil {
return nil, fmt.Errorf("MSI Authorizer failed with: %s", err.Error())
}

msiKVAuthorizer, err := _env.NewMSIAuthorizer(_env.Environment().KeyVaultScope)
if err != nil {
return nil, fmt.Errorf("MSI KeyVault Authorizer failed with: %s", err.Error())
}

m := statsd.New(ctx, log.WithField("component", "update-role-sets"), _env, os.Getenv("MDM_ACCOUNT"), os.Getenv("MDM_NAMESPACE"), os.Getenv("MDM_STATSD_SOCKET"))

keyVaultPrefix := os.Getenv(envKeyVaultPrefix)
serviceKeyvaultURI := keyvault.URI(_env, env.ServiceKeyvaultSuffix, keyVaultPrefix)
serviceKeyvault := keyvault.NewManager(msiKVAuthorizer, serviceKeyvaultURI)

aead, err := encryption.NewMulti(ctx, serviceKeyvault, env.EncryptionSecretV2Name, env.EncryptionSecretName)
if err != nil {
return nil, err
}

if err := env.ValidateVars(envDatabaseAccountName); err != nil {
return nil, err
}
dbAccountName := os.Getenv(envDatabaseAccountName)
clientOptions := &policy.ClientOptions{
ClientOptions: _env.Environment().ManagedIdentityCredentialOptions().ClientOptions,
}

logrusEntry := log.WithField("component", "database")
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, logrusEntry, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
if err != nil {
return nil, err
}

dbc, err := database.NewDatabaseClient(log.WithField("component", "database"), _env, dbAuthorizer, m, aead, dbAccountName)
if err != nil {
return nil, err
}

dbName, err := DBName(_env.IsLocalDevelopmentMode())
if err != nil {
return nil, err
}

return database.NewPlatformWorkloadIdentityRoleSets(ctx, dbc, dbName)
}

func updatePlatformWorkloadIdentityRoleSetsInCosmosDB(ctx context.Context, dbPlatformWorkloadIdentityRoleSets database.PlatformWorkloadIdentityRoleSets, log *logrus.Entry) error {
existingRoleSets, err := dbPlatformWorkloadIdentityRoleSets.ListAll(ctx)
if err != nil {
return nil
}

incomingRoleSets, err := getRoleSetsFromEnv()
if err != nil {
return err
}

newRoleSets := make(map[string]api.PlatformWorkloadIdentityRoleSetProperties)
for _, doc := range incomingRoleSets {
newRoleSets[doc.OpenShiftVersion] = doc
}

for _, doc := range existingRoleSets.PlatformWorkloadIdentityRoleSetDocuments {
incoming, found := newRoleSets[doc.PlatformWorkloadIdentityRoleSet.Properties.OpenShiftVersion]
if found {
log.Printf("Found Version %q, patching", incoming.OpenShiftVersion)
_, err := dbPlatformWorkloadIdentityRoleSets.Patch(ctx, doc.ID, func(inFlightDoc *api.PlatformWorkloadIdentityRoleSetDocument) error {
inFlightDoc.PlatformWorkloadIdentityRoleSet.Properties = incoming
return nil
})
if err != nil {
return err
}
log.Printf("Version %q found", incoming.OpenShiftVersion)
delete(newRoleSets, incoming.OpenShiftVersion)
continue
}

log.Printf("Version %q not found, deleting", doc.PlatformWorkloadIdentityRoleSet.Properties.OpenShiftVersion)
// Delete via changefeed
_, err := dbPlatformWorkloadIdentityRoleSets.Patch(ctx, doc.ID,
func(d *api.PlatformWorkloadIdentityRoleSetDocument) error {
d.PlatformWorkloadIdentityRoleSet.Deleting = true
d.TTL = 60
return nil
})
if err != nil {
return err
}
}

for _, doc := range newRoleSets {
log.Printf("Version %q not found in database, creating", doc.OpenShiftVersion)
newDoc := api.PlatformWorkloadIdentityRoleSetDocument{
ID: dbPlatformWorkloadIdentityRoleSets.NewUUID(),
PlatformWorkloadIdentityRoleSet: &api.PlatformWorkloadIdentityRoleSet{
Properties: doc,
},
}

_, err := dbPlatformWorkloadIdentityRoleSets.Create(ctx, &newDoc)
if err != nil {
return err
}
}

return nil
}

func updatePlatformWorkloadIdentityRoleSets(ctx context.Context, log *logrus.Entry) error {
if err := env.ValidateVars("PLATFORM_WORKLOAD_IDENTITY_ROLE_SETS"); err != nil {
return err
}

if !env.IsLocalDevelopmentMode() {
if err := env.ValidateVars("MDM_ACCOUNT", "MDM_NAMESPACE"); err != nil {
return err
}
}

dbRoleSets, err := getPlatformWorkloadIdentityRoleSetDatabase(ctx, log)
if err != nil {
return err
}

err = updatePlatformWorkloadIdentityRoleSetsInCosmosDB(ctx, dbRoleSets, log)
if err != nil {
return err
}

return nil
}
1 change: 1 addition & 0 deletions pkg/env/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
COMPONENT_MIRROR ServiceComponent = "MIRROR"
COMPONENT_PORTAL ServiceComponent = "PORTAL"
COMPONENT_UPDATE_OCP_VERSIONS ServiceComponent = "UPDATE_OCP_VERSIONS"
COMPONENT_UPDATE_ROLE_SETS ServiceComponent = "UPDATE_ROLE_SETS"
COMPONENT_DEPLOY ServiceComponent = "DEPLOY"
COMPONENT_TOOLING ServiceComponent = "TOOLING"
)
Expand Down
34 changes: 34 additions & 0 deletions pkg/util/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import (
redhatopenshift20231122 "github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/redhatopenshift/2023-11-22/redhatopenshift"
utilgraph "github.com/Azure/ARO-RP/pkg/util/graph"
"github.com/Azure/ARO-RP/pkg/util/rbac"
"github.com/Azure/ARO-RP/pkg/util/rolesets"
"github.com/Azure/ARO-RP/pkg/util/uuid"
"github.com/Azure/ARO-RP/pkg/util/version"
)
Expand Down Expand Up @@ -466,6 +467,11 @@ func (c *Cluster) createCluster(ctx context.Context, vnetResourceGroup, clusterN
return err
}

err = c.insertPlatformWorkloadIdentityRoleSetsIntoCosmosdb()
if err != nil {
return err
}

oc.Properties.WorkerProfiles[0].VMSize = api.VMSizeStandardD2sV3
}

Expand Down Expand Up @@ -601,6 +607,34 @@ func (c *Cluster) ensureDefaultVersionInCosmosdb(ctx context.Context) error {
return resp.Body.Close()
}

func (c *Cluster) insertPlatformWorkloadIdentityRoleSetsIntoCosmosdb() error {
b, err := json.Marshal(rolesets.DefaultPlatformWorkloadIdentityRoleSet)
if err != nil {
return err
}

req, err := http.NewRequest(http.MethodPut, "https://localhost:8443/admin/platformworkloadidentityrolesets/", bytes.NewReader(b))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")

cli := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}

resp, err := cli.Do(req)
if err != nil {
return err
}

return resp.Body.Close()
}

func (c *Cluster) fixupNSGs(ctx context.Context, vnetResourceGroup, clusterName string) error {
timeoutCtx, cancel := context.WithTimeout(ctx, 10*time.Minute)
defer cancel()
Expand Down
84 changes: 84 additions & 0 deletions pkg/util/rolesets/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package rolesets

// Copyright (c) Microsoft Corporation.
// Licensed under the Apache License 2.0.

import (
"github.com/Azure/ARO-RP/pkg/api"
)

var DefaultPlatformWorkloadIdentityRoleSet = api.PlatformWorkloadIdentityRoleSet{
Properties: api.PlatformWorkloadIdentityRoleSetProperties{
OpenShiftVersion: "4.14",
PlatformWorkloadIdentityRoles: []api.PlatformWorkloadIdentityRole{
{
OperatorName: "CloudControllerManager",
RoleDefinitionName: "Azure RedHat OpenShift Cloud Controller Manager Role",
RoleDefinitionID: "/providers/Microsoft.Authorization/roleDefinitions/a1f96423-95ce-4224-ab27-4e3dc72facd4",
ServiceAccounts: []string{
"openshift-cloud-controller-manager:cloud-controller-manager",
},
},
{
OperatorName: "ClusterIngressOperator",
RoleDefinitionName: "Azure RedHat OpenShift Cluster Ingress Operator Role",
RoleDefinitionID: "/providers/Microsoft.Authorization/roleDefinitions/0336e1d3-7a87-462b-b6db-342b63f7802c",
ServiceAccounts: []string{
"openshift-ingress-operator:ingress-operator",
},
},
{
OperatorName: "MachineApiOperator",
RoleDefinitionName: "Azure RedHat OpenShift Machine API Operator Role",
RoleDefinitionID: "/providers/Microsoft.Authorization/roleDefinitions/0358943c-7e01-48ba-8889-02cc51d78637",
ServiceAccounts: []string{
"openshift-machine-api:machine-api-operator",
},
},
{
OperatorName: "StorageOperator",
RoleDefinitionName: "Azure RedHat OpenShift Storage Operator Role",
RoleDefinitionID: "/providers/Microsoft.Authorization/roleDefinitions/5b7237c5-45e1-49d6-bc18-a1f62f400748",
ServiceAccounts: []string{
"openshift-cluster-csi-drivers:azure-disk-csi-driver-operator",
"openshift-cluster-csi-drivers:azure-disk-csi-driver-controller-sa",
},
},
{
OperatorName: "NetworkOperator",
RoleDefinitionName: "Azure RedHat OpenShift Network Operator Role",
RoleDefinitionID: "/providers/Microsoft.Authorization/roleDefinitions/be7a6435-15ae-4171-8f30-4a343eff9e8f",
ServiceAccounts: []string{
"openshift-cloud-network-config-controller:cloud-network-config-controller",
},
},
{
OperatorName: "ImageRegistryOperator",
RoleDefinitionName: "Azure RedHat OpenShift Image Registry Operator Role",
RoleDefinitionID: "/providers/Microsoft.Authorization/roleDefinitions/8b32b316-c2f5-4ddf-b05b-83dacd2d08b5",
ServiceAccounts: []string{
"openshift-image-registry:cluster-image-registry-operator",
"openshift-image-registry:registry",
},
},
{
OperatorName: "AzureFilesStorageOperator",
RoleDefinitionName: "Azure RedHat OpenShift Azure Files Storage Operator Role",
RoleDefinitionID: "/providers/Microsoft.Authorization/roleDefinitions/0d7aedc0-15fd-4a67-a412-efad370c947e",
ServiceAccounts: []string{
"openshift-cluster-csi-drivers:azure-file-csi-driver-operator",
"openshift-cluster-csi-drivers:azure-file-csi-driver-controller-sa",
"openshift-cluster-csi-drivers:azure-file-csi-driver-node-sa",
},
},
{
OperatorName: "ServiceOperator",
RoleDefinitionName: "Azure RedHat OpenShift Service Operator",
RoleDefinitionID: "/providers/Microsoft.Authorization/roleDefinitions/4436bae4-7702-4c84-919b-c4069ff25ee2",
ServiceAccounts: []string{
"openshift-azure-operator:aro-operator-master",
},
},
},
},
}

0 comments on commit 3cd8bc5

Please sign in to comment.