PageRenderTime 4068ms CodeModel.GetById 28ms RepoModel.GetById 2ms app.codeStats 0ms

/pkg/armhelpers/graph.go

https://bitbucket.org/afawkes/acs-engine
Go | 125 lines | 97 code | 19 blank | 9 comment | 11 complexity | 5f1d5d0dd16f6d4421eb32989b6ace06 MD5 | raw file
Possible License(s): MIT, Apache-2.0, 0BSD, AGPL-3.0, BSD-3-Clause, LGPL-3.0
  1. package armhelpers
  2. import (
  3. "fmt"
  4. "regexp"
  5. "time"
  6. "github.com/Azure/azure-sdk-for-go/arm/authorization"
  7. "github.com/Azure/azure-sdk-for-go/arm/graphrbac"
  8. "github.com/Azure/go-autorest/autorest/date"
  9. "github.com/Azure/go-autorest/autorest/to"
  10. "github.com/satori/go.uuid"
  11. log "github.com/sirupsen/logrus"
  12. )
  13. const (
  14. // AADContributorRoleID is the role id that exists in every subscription for 'Contributor'
  15. AADContributorRoleID = "b24988ac-6180-42a0-ab88-20f7382dd24c"
  16. // AADRoleReferenceTemplate is a template for a roleDefinitionId
  17. AADRoleReferenceTemplate = "/subscriptions/%s/providers/Microsoft.Authorization/roleDefinitions/%s"
  18. // AADRoleResourceGroupScopeTemplate is a template for a roleDefinition scope
  19. AADRoleResourceGroupScopeTemplate = "/subscriptions/%s/resourceGroups/%s"
  20. )
  21. // CreateGraphApplication creates an application via the graphrbac client
  22. func (az *AzureClient) CreateGraphApplication(applicationCreateParameters graphrbac.ApplicationCreateParameters) (graphrbac.Application, error) {
  23. return az.applicationsClient.Create(applicationCreateParameters)
  24. }
  25. // CreateGraphPrincipal creates a service principal via the graphrbac client
  26. func (az *AzureClient) CreateGraphPrincipal(servicePrincipalCreateParameters graphrbac.ServicePrincipalCreateParameters) (graphrbac.ServicePrincipal, error) {
  27. return az.servicePrincipalsClient.Create(servicePrincipalCreateParameters)
  28. }
  29. // CreateRoleAssignment creates a role assignment via the authorization client
  30. func (az *AzureClient) CreateRoleAssignment(scope string, roleAssignmentName string, parameters authorization.RoleAssignmentCreateParameters) (authorization.RoleAssignment, error) {
  31. return az.authorizationClient.Create(scope, roleAssignmentName, parameters)
  32. }
  33. // CreateApp is a simpler method for creating an application
  34. func (az *AzureClient) CreateApp(appName, appURL string, replyURLs *[]string, requiredResourceAccess *[]graphrbac.RequiredResourceAccess) (applicationID, servicePrincipalObjectID, servicePrincipalClientSecret string, err error) {
  35. notBefore := time.Now()
  36. notAfter := time.Now().Add(10000 * 24 * time.Hour)
  37. startDate := date.Time{Time: notBefore}
  38. endDate := date.Time{Time: notAfter}
  39. servicePrincipalClientSecret = uuid.NewV4().String()
  40. log.Debugf("ad: creating application with name=%q identifierURL=%q", appName, appURL)
  41. applicationReq := graphrbac.ApplicationCreateParameters{
  42. AvailableToOtherTenants: to.BoolPtr(false),
  43. DisplayName: to.StringPtr(appName),
  44. Homepage: to.StringPtr(appURL),
  45. IdentifierUris: to.StringSlicePtr([]string{appURL}),
  46. ReplyUrls: replyURLs,
  47. PasswordCredentials: &[]graphrbac.PasswordCredential{
  48. {
  49. KeyID: to.StringPtr(uuid.NewV4().String()),
  50. StartDate: &startDate,
  51. EndDate: &endDate,
  52. Value: to.StringPtr(servicePrincipalClientSecret),
  53. },
  54. },
  55. RequiredResourceAccess: requiredResourceAccess,
  56. }
  57. applicationResp, err := az.CreateGraphApplication(applicationReq)
  58. if err != nil {
  59. return "", "", "", err
  60. }
  61. applicationID = to.String(applicationResp.AppID)
  62. log.Debugf("ad: creating servicePrincipal for applicationID: %q", applicationID)
  63. servicePrincipalReq := graphrbac.ServicePrincipalCreateParameters{
  64. AppID: applicationResp.AppID,
  65. AccountEnabled: to.BoolPtr(true),
  66. }
  67. servicePrincipalResp, err := az.servicePrincipalsClient.Create(servicePrincipalReq)
  68. if err != nil {
  69. return "", "", "", err
  70. }
  71. servicePrincipalObjectID = to.String(servicePrincipalResp.ObjectID)
  72. return applicationID, servicePrincipalObjectID, servicePrincipalClientSecret, nil
  73. }
  74. // CreateRoleAssignmentSimple is a wrapper around RoleAssignmentsClient.Create
  75. func (az *AzureClient) CreateRoleAssignmentSimple(resourceGroup, servicePrincipalObjectID string) error {
  76. roleAssignmentName := uuid.NewV4().String()
  77. roleDefinitionID := fmt.Sprintf(AADRoleReferenceTemplate, az.subscriptionID, AADContributorRoleID)
  78. scope := fmt.Sprintf(AADRoleResourceGroupScopeTemplate, az.subscriptionID, resourceGroup)
  79. roleAssignmentParameters := authorization.RoleAssignmentCreateParameters{
  80. Properties: &authorization.RoleAssignmentProperties{
  81. RoleDefinitionID: to.StringPtr(roleDefinitionID),
  82. PrincipalID: to.StringPtr(servicePrincipalObjectID),
  83. },
  84. }
  85. re := regexp.MustCompile("(?i)status=(\\d+)")
  86. for {
  87. _, err := az.CreateRoleAssignment(
  88. scope,
  89. roleAssignmentName,
  90. roleAssignmentParameters,
  91. )
  92. if err != nil {
  93. match := re.FindStringSubmatch(err.Error())
  94. if match != nil && (match[1] == "403") {
  95. //insufficient permissions. stop now
  96. log.Debugf("Failed to create role assignment (will abort now): %q", err)
  97. return err
  98. }
  99. log.Debugf("Failed to create role assignment (will retry): %q", err)
  100. time.Sleep(3 * time.Second)
  101. continue
  102. }
  103. break
  104. }
  105. return nil
  106. }