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