2024-05-31 16:09:53 +03:00
|
|
|
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"
|
|
|
|
)
|
|
|
|
|
2024-06-26 16:36:56 +03:00
|
|
|
func getRoleSetsFromEnv() ([]api.PlatformWorkloadIdentityRoleSetProperties, error) {
|
2024-05-31 16:09:53 +03:00
|
|
|
const envKey = envPlatformWorkloadIdentityRoleSets
|
2024-06-26 16:36:56 +03:00
|
|
|
var roleSets []api.PlatformWorkloadIdentityRoleSetProperties
|
2024-05-31 16:09:53 +03:00
|
|
|
|
2024-06-18 00:12:17 +03:00
|
|
|
// Unmarshal env data into type api.PlatformWorkloadIdentityRoleSet
|
2024-06-28 19:02:13 +03:00
|
|
|
return roleSets, getEnvironmentData(envKey, &roleSets)
|
2024-05-31 16:09:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func getPlatformWorkloadIdentityRoleSetDatabase(ctx context.Context, log *logrus.Entry) (database.PlatformWorkloadIdentityRoleSets, error) {
|
2024-06-17 23:34:39 +03:00
|
|
|
_env, err := env.NewCore(ctx, log, env.COMPONENT_UPDATE_ROLE_SETS)
|
2024-05-31 16:09:53 +03:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-06-28 19:02:13 +03:00
|
|
|
return database.NewPlatformWorkloadIdentityRoleSets(ctx, dbc, dbName)
|
2024-05-31 16:09:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func updatePlatformWorkloadIdentityRoleSetsInCosmosDB(ctx context.Context, dbPlatformWorkloadIdentityRoleSets database.PlatformWorkloadIdentityRoleSets, log *logrus.Entry) error {
|
2024-06-17 23:34:39 +03:00
|
|
|
existingRoleSets, err := dbPlatformWorkloadIdentityRoleSets.ListAll(ctx)
|
2024-05-31 16:09:53 +03:00
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-06-18 00:12:17 +03:00
|
|
|
incomingRoleSets, err := getRoleSetsFromEnv()
|
2024-05-31 16:09:53 +03:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-06-26 16:36:56 +03:00
|
|
|
newRoleSets := make(map[string]api.PlatformWorkloadIdentityRoleSetProperties)
|
2024-06-18 00:12:17 +03:00
|
|
|
for _, doc := range incomingRoleSets {
|
2024-06-26 16:36:56 +03:00
|
|
|
newRoleSets[doc.OpenShiftVersion] = doc
|
2024-05-31 16:09:53 +03:00
|
|
|
}
|
|
|
|
|
2024-06-17 23:34:39 +03:00
|
|
|
for _, doc := range existingRoleSets.PlatformWorkloadIdentityRoleSetDocuments {
|
2024-07-02 21:11:19 +03:00
|
|
|
incoming, found := newRoleSets[doc.PlatformWorkloadIdentityRoleSet.Properties.OpenShiftVersion]
|
2024-05-31 16:09:53 +03:00
|
|
|
if found {
|
2024-07-02 21:11:19 +03:00
|
|
|
log.Printf("Found Version %q, patching", incoming.OpenShiftVersion)
|
2024-05-31 16:09:53 +03:00
|
|
|
_, err := dbPlatformWorkloadIdentityRoleSets.Patch(ctx, doc.ID, func(inFlightDoc *api.PlatformWorkloadIdentityRoleSetDocument) error {
|
2024-07-02 21:11:19 +03:00
|
|
|
inFlightDoc.PlatformWorkloadIdentityRoleSet.Properties = incoming
|
2024-05-31 16:09:53 +03:00
|
|
|
return nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-07-02 21:11:19 +03:00
|
|
|
log.Printf("Version %q found", incoming.OpenShiftVersion)
|
|
|
|
delete(newRoleSets, incoming.OpenShiftVersion)
|
2024-05-31 16:09:53 +03:00
|
|
|
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 {
|
2024-06-26 16:36:56 +03:00
|
|
|
log.Printf("Version %q not found in database, creating", doc.OpenShiftVersion)
|
2024-05-31 16:09:53 +03:00
|
|
|
newDoc := api.PlatformWorkloadIdentityRoleSetDocument{
|
2024-06-26 16:36:56 +03:00
|
|
|
ID: dbPlatformWorkloadIdentityRoleSets.NewUUID(),
|
|
|
|
PlatformWorkloadIdentityRoleSet: &api.PlatformWorkloadIdentityRoleSet{
|
|
|
|
Properties: doc,
|
|
|
|
},
|
2024-05-31 16:09:53 +03:00
|
|
|
}
|
2024-06-26 16:36:56 +03:00
|
|
|
|
2024-05-31 16:09:53 +03:00
|
|
|
_, 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
|
|
|
|
}
|