diff --git a/deploy/cluster-predeploy.json b/deploy/cluster-predeploy.json index f4e9422ff..4f37948e7 100644 --- a/deploy/cluster-predeploy.json +++ b/deploy/cluster-predeploy.json @@ -82,66 +82,6 @@ "[resourceid('Microsoft.Network/virtualNetworks/subnets', 'dev-vnet', concat(parameters('clusterName'), '-master'))]" ], "location": "[resourceGroup().location]" - }, - { - "name": "[concat('dev-vnet', '/Microsoft.Authorization/', guid(resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet'), parameters('clusterServicePrincipalId'), '4d97b98b-1d4f-4787-a291-c67834d212e7'))]", - "type": "Microsoft.Network/virtualNetworks/providers/roleAssignments", - "properties": { - "scope": "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]", - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "principalId": "[parameters('clusterServicePrincipalId')]", - "principalType": "ServicePrincipal" - }, - "condition": null, - "apiVersion": "2018-09-01-preview", - "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]" - ] - }, - { - "name": "[concat('dev-vnet', '/Microsoft.Authorization/', guid(resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet'), parameters('fpServicePrincipalId'), '4d97b98b-1d4f-4787-a291-c67834d212e7'))]", - "type": "Microsoft.Network/virtualNetworks/providers/roleAssignments", - "properties": { - "scope": "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]", - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "principalId": "[parameters('fpServicePrincipalId')]", - "principalType": "ServicePrincipal" - }, - "condition": null, - "apiVersion": "2018-09-01-preview", - "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]" - ] - }, - { - "name": "[concat(concat(parameters('clusterName'), '-rt'), '/Microsoft.Authorization/', guid(resourceId('Microsoft.Network/routeTables', concat(parameters('clusterName'), '-rt')), parameters('clusterServicePrincipalId'), '4d97b98b-1d4f-4787-a291-c67834d212e7'))]", - "type": "Microsoft.Network/routeTables/providers/roleAssignments", - "properties": { - "scope": "[resourceId('Microsoft.Network/routeTables', concat(parameters('clusterName'), '-rt'))]", - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "principalId": "[parameters('clusterServicePrincipalId')]", - "principalType": "ServicePrincipal" - }, - "condition": null, - "apiVersion": "2018-09-01-preview", - "dependsOn": [ - "[resourceId('Microsoft.Network/routeTables', concat(parameters('clusterName'), '-rt'))]" - ] - }, - { - "name": "[concat(concat(parameters('clusterName'), '-rt'), '/Microsoft.Authorization/', guid(resourceId('Microsoft.Network/routeTables', concat(parameters('clusterName'), '-rt')), parameters('fpServicePrincipalId'), '4d97b98b-1d4f-4787-a291-c67834d212e7'))]", - "type": "Microsoft.Network/routeTables/providers/roleAssignments", - "properties": { - "scope": "[resourceId('Microsoft.Network/routeTables', concat(parameters('clusterName'), '-rt'))]", - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "principalId": "[parameters('fpServicePrincipalId')]", - "principalType": "ServicePrincipal" - }, - "condition": null, - "apiVersion": "2018-09-01-preview", - "dependsOn": [ - "[resourceId('Microsoft.Network/routeTables', concat(parameters('clusterName'), '-rt'))]" - ] } ] } diff --git a/pkg/deploy/bindata.go b/pkg/deploy/bindata.go index 0a4e29a0e..c84a018db 100644 --- a/pkg/deploy/bindata.go +++ b/pkg/deploy/bindata.go @@ -91,7 +91,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _clusterPredeployJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x57\x5b\x6f\xdb\x36\x14\x7e\xf7\xaf\x10\xb4\x01\x72\x00\xcb\x92\xbc\x6c\x8e\xf3\x16\x2c\xc3\x10\x60\xeb\x82\x36\xe8\x4b\x90\x07\x9a\x3c\x76\xb8\xd2\x24\x41\x52\xee\xd2\xc2\xff\x7d\xa0\x68\x39\xba\x50\x8e\xe3\x5c\xb6\xb4\xb6\x9f\xc4\xcb\xb9\x7c\xe7\xfb\x0e\xc9\xaf\xbd\x20\x08\x82\xf0\x47\x8d\x6f\x61\x81\xc2\xd3\x20\xbc\x35\x46\xea\xd3\x24\x71\x23\xc3\x05\xe2\x68\x0e\x0b\xe0\x66\x88\xbe\xe4\x0a\x86\x58\x2c\xd6\x73\x3a\x19\xa5\xd9\xcf\x71\x9a\xc5\x69\x96\x10\x90\x4c\xdc\xd9\x75\x57\xb0\x90\x0c\x19\x18\xfe\xad\x05\xff\x21\x1c\x38\x0f\x58\x70\x03\xdc\x7c\x04\xa5\xa9\xe0\xd6\x51\x36\x4c\xed\xbf\x5c\x20\x91\x42\x0b\x30\xa0\x74\x78\x1a\xb8\xb0\xdc\x46\x96\x6b\x03\xea\x1d\x5a\x40\x6d\xa2\x98\x34\x77\xd2\x8e\x86\xda\x28\xca\xe7\xe1\x66\x72\x35\x68\x19\xf8\x00\x6a\x49\x31\x5c\x2a\xca\x31\x95\x88\x5d\x90\xfd\xcc\xcd\xe4\xb3\x59\xca\x19\x3b\x2f\x60\xeb\xde\x3f\x15\x82\x85\x83\xfa\x1c\x81\x19\xca\x99\xf9\x88\x58\x6e\xd7\xcc\x10\xd3\xe0\x75\xb0\x40\x36\xf1\x33\x42\x14\x68\x7d\xa9\x60\x46\xff\xd9\x2f\xd2\xcf\x42\x7d\xda\xdf\x50\xaf\x62\x2e\x54\xa0\x45\xae\x30\xd8\x2a\x5f\x6f\xd6\x34\x4c\x49\x25\x24\x28\x43\x41\xb7\xdc\x14\xf3\xc8\x45\xf2\x41\x22\xdc\x26\x45\x73\x95\x8b\xb7\xe1\xb0\xb5\x38\x4b\x1d\x1d\x93\x49\xe8\x5d\x74\xd3\x1a\x5d\xd5\x46\x56\x8d\x22\x71\xc7\xd7\x90\xc0\x32\x5e\x72\x30\xcd\x22\x96\x68\xfd\x49\xb1\x12\x5a\xcc\xcc\xf0\x1d\x18\x8b\x73\xb2\xa4\xca\xe4\x88\xad\x3f\x75\x73\x23\x13\x18\x99\xb5\x84\xae\x4b\x34\x7f\x57\x22\x97\xfd\xa3\x61\x39\x79\xd3\xdc\x85\x05\x27\x74\xb3\xed\x5e\x6b\xfd\xe8\x9e\x85\xd1\x51\x6b\x1b\x92\xb4\xa2\xd8\x51\x9a\x4d\xe2\x74\x1c\xa7\x99\x97\x26\x5f\xfd\x08\x5c\x63\xc1\x31\x32\xfd\xaa\xd3\x8a\xa8\xa3\xa3\x41\x10\xc5\xca\x78\xbc\x77\x63\xa4\x44\x6e\xe0\x0a\x4d\x19\x3c\x13\x3e\x4f\x49\x74\x47\xb6\x6e\x74\x53\xc7\xdf\x23\xd2\x36\x14\x85\x9d\xfb\xa4\xbb\x39\x4f\x49\x2d\x6f\x4a\xfa\xd1\x56\xf4\xa2\x41\xb0\x6b\x79\xbc\x41\xb9\x3a\xa1\xb9\x4d\x9d\xe7\x8c\xb5\x55\xe2\x49\x44\xbb\x06\xfa\x1b\x27\x52\x50\x6e\xba\x95\xe9\x4f\xb2\x6a\xa3\x4e\x8f\x5f\x05\x37\x88\x72\x50\xef\x61\x4e\xb5\x51\x77\x7e\x2d\xaf\x5a\xa3\x37\x9e\x28\xa5\xa2\x4b\x64\xe0\x0f\xca\x3f\xad\x3b\xfe\x1a\xbf\x4b\xc1\x28\x76\xd5\x0e\xcf\xa9\xb6\x38\x92\x70\xa7\x66\x50\x4a\x21\x2a\xbb\x42\x12\x0d\x82\xad\xc0\x3b\x76\x3c\x4a\x1b\x8d\xfe\x91\xe8\x7c\xca\xc1\xb4\x74\xd2\xc9\xf8\xd6\x69\x23\x81\x13\xfd\x17\xf7\x56\xe9\x21\xaa\x35\x82\x89\x06\xc1\x26\xf7\x0e\x96\xbf\x14\x77\x7b\x5b\xea\xbd\x6b\xd3\x78\xf1\x66\xe0\x39\x68\x3b\x60\xfa\x1f\x6a\xe8\x85\x24\xe0\x30\xf9\x66\x24\x50\x06\x53\x93\xc2\x6e\x4c\x2e\x9b\xc1\xeb\xb1\xb9\xb3\x6a\x36\xfa\xe4\x3e\xd7\xb3\xdc\xdc\x0a\x45\xbf\x14\x96\x6d\x45\xe7\x39\x25\xfd\xd2\xf5\xc5\xe3\x5b\x83\x97\x13\xed\x8b\x77\x81\xcb\x31\x99\x8c\xa7\x93\x93\x69\x9c\x91\xe3\x59\x7c\x3c\x3e\x19\xc7\x68\x34\xc9\x62\xfc\xcb\xf8\xe4\xa7\x63\x32\xca\x46\x30\xf6\x1c\x5f\x8f\xe0\x8f\x54\x62\x49\x09\x28\x9d\x28\xc1\xe0\x4c\x6b\x3a\xe7\xf6\xa9\xd3\x62\xd4\x43\xea\xd7\x58\x38\x9f\xd7\x4f\xc0\xa6\xe3\x72\xc0\xe0\x1c\x66\x94\x17\xb7\xbc\x0b\x77\x0d\xd0\xf9\x54\x63\x45\xa5\x1d\x7a\xef\x75\x58\x2f\x5c\xdd\x48\xe1\x76\x37\x70\xbd\x21\xc9\xda\x03\xa9\xde\xe8\xb6\x54\x74\xbb\xad\xab\x75\xd1\x9a\x3b\xb7\x1f\xc0\xd5\xeb\xaf\xbd\xa6\x3c\xd4\x08\x4e\xe2\x74\x62\x1f\xb6\x52\xc1\x92\xc2\xe7\x7d\x1b\xc2\x5e\xc5\xad\x4b\xfb\xed\x88\xd4\xf7\x30\x3e\xe8\xb3\xb4\xfc\xc6\xf4\xe9\x2f\xe6\x41\x9a\x95\xdf\x3e\xd2\xdc\xf5\xbe\xfa\x74\xe1\xee\x79\x4f\xfe\x6f\xcf\xdd\x4a\xd0\xaf\xaf\xe9\x67\x7c\x15\xbf\x35\xb5\x7f\xcf\xa7\xf1\x33\x3d\x28\xbf\xfd\x66\xf0\x8a\xe7\xfb\xa1\x0f\x1c\x4e\xfd\xb7\xdc\x02\x7a\xee\x7b\xd5\xfb\x37\x00\x00\xff\xff\x53\x34\x37\xf2\x5f\x1b\x00\x00") +var _clusterPredeployJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x55\x5d\x6b\xdb\x3c\x14\xbe\xcf\xaf\x30\x7a\x5f\x70\x0a\xfe\x2c\x8c\xd1\xde\x8d\x75\x8c\xc1\xd6\x95\xb5\xf4\xa6\xf4\x42\x95\x4e\x52\xad\xb2\x24\xa4\xe3\x6c\x5d\xc9\x7f\x1f\x8e\xe2\x34\xb6\xe5\x2e\xeb\x1a\x18\x23\x57\xd1\xf9\x7e\xce\xf3\x1c\x3f\x4c\xa2\x28\x8a\xc8\xff\x8e\xdd\x42\x45\xc9\x71\x44\x6e\x11\x8d\x3b\xce\x73\xff\x92\x55\x54\xd1\x39\x54\xa0\x30\xa3\x3f\x6a\x0b\x19\xd3\xd5\xda\xe6\xf2\xc3\xa2\x7c\x95\x16\x65\x5a\x94\x39\x07\x23\xf5\x7d\xe3\x77\x01\x95\x91\x14\x21\xfb\xea\xb4\xfa\x8f\x24\xbe\x02\xd3\x0a\x41\xe1\x25\x58\x27\xb4\x6a\x0a\x95\x59\xd1\xfc\x5a\x07\x43\x2d\xad\x00\xc1\x3a\x72\x1c\xf9\xb6\x7c\xa0\xac\x1d\x82\x3d\xa5\x15\x74\x0c\x2b\x23\xde\x9b\xe6\x95\x38\xb4\x42\xcd\xc9\xc6\xb8\x4c\x06\x09\xce\xc1\x2e\x04\x83\x33\x2b\x14\x13\x86\xca\x0f\xfc\x79\xe9\x66\xe6\xc5\x32\xd5\x52\x9e\xac\x60\x1b\x8f\xbf\xd1\x5a\x92\xa4\x6b\xe3\x30\xa3\xb5\xc4\x4b\x2a\xeb\xc6\x67\x46\xa5\x83\x60\x81\x8a\x36\x83\xbf\xe1\xdc\x82\x73\x67\x16\x66\xe2\xfb\xf3\x3a\xfd\xa6\xed\xdd\xf3\x13\x4d\xb6\xd2\x11\x0b\x4e\xd7\x96\x41\xb3\xe5\xab\x8d\x4f\x2f\x95\xb1\xda\x80\x45\x01\x6e\x50\x66\x65\xa7\xbe\x93\x73\x43\xd9\x90\x14\x7d\x2f\xdf\x6f\xaf\xe0\xc0\xb9\x2c\x3c\x1d\xf3\x23\x12\x74\xba\x1e\xbc\x2e\x3b\x2f\xcb\xde\x92\x94\xe7\x2b\xe1\xb0\x48\x17\x0a\xb0\xbf\xc4\x16\xad\x4f\x82\x59\xed\xf4\x0c\xb3\x53\xc0\x06\xe7\x7c\x21\x2c\xd6\x54\xae\xff\xba\x7e\xa0\xd4\x8c\xe2\x5a\x42\x57\x2d\x9a\xef\xad\xae\xcd\xf4\x20\x6b\x8d\xd7\xfd\x28\xa6\x15\x17\x9b\xb0\x47\xad\x4d\xe3\x47\x16\xc6\x07\x83\x30\x6a\xc4\x96\x62\x0f\x8b\xf2\x28\x2d\x5e\xa7\x45\x19\xa4\xc9\x43\x18\x81\x2b\xa6\x15\xa3\x38\xdd\x2e\xba\x25\xea\xf8\x20\x89\xe2\xd4\x62\xa0\xfa\x38\x46\x56\xd7\x08\x17\xf4\x46\xc2\x0b\xe1\xf3\x27\x83\xee\xc8\xd6\x8d\x6e\xba\xf8\x07\x44\x3a\x84\x62\x95\xe7\x71\xe8\x71\xce\x0b\xde\x99\x5b\xf0\x69\xfc\x24\x7a\x71\x12\xed\xba\x9e\x60\x53\x7e\x4f\x74\xde\x8c\xae\x6a\x29\x87\x2a\x09\x0c\xe2\xfc\x01\x7d\xa7\xb8\xd1\x42\xe1\xb8\x32\xc3\x43\x6e\xe7\xe8\xd2\xe3\xad\x56\x48\x85\x02\xfb\x05\xe6\xc2\xa1\xbd\x0f\x6b\x79\x39\x78\xbd\x0e\x74\x69\xac\x58\x50\x84\x8f\x42\xdd\xad\x2f\xfe\x1a\xbf\x33\x2d\x05\xf3\xdb\x26\x27\xc2\x35\x38\x72\xb2\xd3\x31\x68\xa5\x10\xb7\x57\x21\x8f\x93\xe8\x49\xe0\x3d\x3b\x7e\x4b\x1b\xbd\xfb\x91\xbb\xfa\x46\x01\x0e\x74\x32\xca\xf8\xc1\xd7\xc6\x80\xe2\xee\xb3\x0a\x6e\xe9\x57\x54\xeb\x35\x13\x27\xd1\x66\xf6\x11\x96\xef\x8b\xbb\x93\x27\xf6\xbd\xeb\xd1\xd8\xfb\x31\x08\x7c\x68\x47\x60\xfa\x0b\x35\xb4\x27\x09\x78\x4c\xfe\x19\x09\xb4\xcd\x74\xa4\xb0\x1b\x93\xdb\x63\xf0\xe2\x6c\x9e\xf8\xfd\x2d\x27\x3f\x03\x00\x00\xff\xff\x05\x63\xc4\x18\x0f\x0c\x00\x00") func clusterPredeployJsonBytes() ([]byte, error) { return bindataRead( diff --git a/pkg/deploy/generator/templates.go b/pkg/deploy/generator/templates.go index b8aac8bb8..47cd5f73c 100644 --- a/pkg/deploy/generator/templates.go +++ b/pkg/deploy/generator/templates.go @@ -8,7 +8,6 @@ import ( "encoding/json" "github.com/Azure/ARO-RP/pkg/util/arm" - "github.com/Azure/ARO-RP/pkg/util/rbac" ) func (g *generator) clusterPredeploy() *arm.Template { @@ -38,10 +37,6 @@ func (g *generator) clusterPredeploy() *arm.Template { clusterRouteTable(), clusterMasterSubnet(), clusterWorkerSubnet(), - rbac.ResourceRoleAssignment(rbac.RoleNetworkContributor, "parameters('clusterServicePrincipalId')", "Microsoft.Network/virtualNetworks", "'dev-vnet'"), - rbac.ResourceRoleAssignment(rbac.RoleNetworkContributor, "parameters('fpServicePrincipalId')", "Microsoft.Network/virtualNetworks", "'dev-vnet'"), - rbac.ResourceRoleAssignment(rbac.RoleNetworkContributor, "parameters('clusterServicePrincipalId')", "Microsoft.Network/routeTables", "concat(parameters('clusterName'), '-rt')"), - rbac.ResourceRoleAssignment(rbac.RoleNetworkContributor, "parameters('fpServicePrincipalId')", "Microsoft.Network/routeTables", "concat(parameters('clusterName'), '-rt')"), ) return t diff --git a/pkg/env/dev.go b/pkg/env/dev.go index 0c6749661..a89c57e44 100644 --- a/pkg/env/dev.go +++ b/pkg/env/dev.go @@ -22,6 +22,7 @@ import ( "github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/authorization" "github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/features" "github.com/Azure/ARO-RP/pkg/util/clientauthorizer" + "github.com/Azure/ARO-RP/pkg/util/rbac" "github.com/Azure/ARO-RP/pkg/util/refreshable" "github.com/Azure/ARO-RP/pkg/util/version" ) @@ -128,7 +129,7 @@ func (d *dev) CreateARMResourceGroupRoleAssignment(ctx context.Context, fpAuthor _, err = d.roleassignments.Create(ctx, "/subscriptions/"+d.SubscriptionID()+"/resourceGroups/"+resourceGroup, uuid.NewV4().String(), mgmtauthorization.RoleAssignmentCreateParameters{ RoleAssignmentProperties: &mgmtauthorization.RoleAssignmentProperties{ - RoleDefinitionID: to.StringPtr("/subscriptions/" + d.SubscriptionID() + "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635"), + RoleDefinitionID: to.StringPtr("/subscriptions/" + d.SubscriptionID() + "/providers/Microsoft.Authorization/roleDefinitions/" + rbac.RoleOwner), PrincipalID: res.Value, }, }) diff --git a/pkg/util/cluster/cluster.go b/pkg/util/cluster/cluster.go index 93ed894b5..f72060e49 100644 --- a/pkg/util/cluster/cluster.go +++ b/pkg/util/cluster/cluster.go @@ -13,10 +13,12 @@ import ( "time" mgmtnetwork "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-07-01/network" + mgmtauthorization "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-09-01-preview/authorization" 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/go-autorest/autorest/azure/auth" "github.com/Azure/go-autorest/autorest/to" + uuid "github.com/satori/go.uuid" "github.com/sirupsen/logrus" mgmtredhatopenshift "github.com/Azure/ARO-RP/pkg/client/services/redhatopenshift/mgmt/2020-04-30/redhatopenshift" @@ -30,6 +32,7 @@ import ( "github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/redhatopenshift" "github.com/Azure/ARO-RP/pkg/util/deployment" "github.com/Azure/ARO-RP/pkg/util/instancemetadata" + "github.com/Azure/ARO-RP/pkg/util/rbac" "github.com/Azure/ARO-RP/pkg/util/subnet" ) @@ -178,6 +181,41 @@ func (c *Cluster) Create(ctx context.Context, clusterName string) error { return err } + c.log.Info("creating role assignments") + for _, scope := range []string{ + "/subscriptions/" + c.SubscriptionID() + "/resourceGroups/" + c.ResourceGroup() + "/providers/Microsoft.Network/virtualNetworks/dev-vnet", + "/subscriptions/" + c.SubscriptionID() + "/resourceGroups/" + c.ResourceGroup() + "/providers/Microsoft.Network/routeTables/" + clusterName + "-rt", + } { + for _, principalID := range []string{spID, fpSPID} { + for i := 0; i < 5; i++ { + _, err = c.roleassignments.Create( + ctx, + scope, + uuid.NewV4().String(), + mgmtauthorization.RoleAssignmentCreateParameters{ + RoleAssignmentProperties: &mgmtauthorization.RoleAssignmentProperties{ + RoleDefinitionID: to.StringPtr("/subscriptions/" + c.SubscriptionID() + "/providers/Microsoft.Authorization/roleDefinitions/" + rbac.RoleNetworkContributor), + PrincipalID: &principalID, + PrincipalType: mgmtauthorization.ServicePrincipal, + }, + }, + ) + // TODO: tighten this error check + if err != nil && i < 4 { + // Sometimes we see HashConflictOnDifferentRoleAssignmentIds. + // Retry a few times. + c.log.Print(err) + continue + } + if err != nil { + return err + } + + break + } + } + } + c.log.Info("creating cluster") err = c.createCluster(ctx, clusterName, appID, appSecret) if err != nil { diff --git a/pkg/util/rbac/rbac.go b/pkg/util/rbac/rbac.go index f5f31ecd2..25e433de8 100644 --- a/pkg/util/rbac/rbac.go +++ b/pkg/util/rbac/rbac.go @@ -17,6 +17,7 @@ const ( RoleDocumentDBAccountContributor = "5bd9cd88-fe45-4216-938b-f97437e15450" RoleDNSZoneContributor = "befefa01-2a29-4197-83a8-272ff33ce314" RoleNetworkContributor = "4d97b98b-1d4f-4787-a291-c67834d212e7" + RoleOwner = "8e3af657-a8ff-443c-a75c-2fe8c4bcb635" RoleReader = "acdd72a7-3385-48ef-bd42-f606fba81ae7" )