Skip to content

Commit

Permalink
OpenShift AAD automatic service principal and authentication integrat…
Browse files Browse the repository at this point in the history
…ion (#2795)

* bump azure-sdk-for-go and go-autorest

* add ad authentication
  • Loading branch information
jim-minter authored and jackfrancis committed May 4, 2018
1 parent bee0d43 commit 6f5c9a3
Show file tree
Hide file tree
Showing 849 changed files with 121,428 additions and 28,670 deletions.
26 changes: 25 additions & 1 deletion cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"github.com/Azure/acs-engine/pkg/armhelpers"
"github.com/Azure/acs-engine/pkg/helpers"
"github.com/Azure/acs-engine/pkg/i18n"
"github.com/Azure/azure-sdk-for-go/arm/graphrbac"
"github.com/Azure/go-autorest/autorest/to"
)

const (
Expand Down Expand Up @@ -221,7 +223,29 @@ func autofillApimodel(dc *deployCmd) {
// TODO: consider caching the creds here so they persist between subsequent runs of 'deploy'
appName := dc.containerService.Properties.MasterProfile.DNSPrefix
appURL := fmt.Sprintf("https://%s/", appName)
applicationID, servicePrincipalObjectID, secret, err := dc.client.CreateApp(appName, appURL)
var replyURLs *[]string
var requiredResourceAccess *[]graphrbac.RequiredResourceAccess
if dc.containerService.Properties.OrchestratorProfile.OrchestratorType == api.OpenShift {
appName = fmt.Sprintf("%s.%s.cloudapp.azure.com", appName, dc.containerService.Properties.AzProfile.Location)
appURL = fmt.Sprintf("https://%s:8443/", appName)
replyURLs = to.StringSlicePtr([]string{fmt.Sprintf("https://%s:8443/oauth2callback/Azure%%20AD", appName)})
ra := []graphrbac.ResourceAccess{
{
// TODO: where is this UUID defined?
ID: to.StringPtr("311a71cc-e848-46a1-bdf8-97ff7156d8e6"),
Type: to.StringPtr("Scope"),
},
}
rra := []graphrbac.RequiredResourceAccess{
{
// TODO: where is this UUID defined?
ResourceAppID: to.StringPtr("00000002-0000-0000-c000-000000000000"),
ResourceAccess: &ra,
},
}
requiredResourceAccess = &rra
}
applicationID, servicePrincipalObjectID, secret, err := dc.client.CreateApp(appName, appURL, replyURLs, requiredResourceAccess)
if err != nil {
log.Fatalf("apimodel invalid: ServicePrincipalProfile was empty, and we failed to create valid credentials: %q", err)
}
Expand Down
3 changes: 2 additions & 1 deletion examples/openshift.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"orchestratorType": "OpenShift",
"openShiftConfig": {
"clusterUsername": "",
"clusterPassword": ""
"clusterPassword": "",
"enableAADAuthentication": false
}
},
"azProfile": {
Expand Down
8 changes: 4 additions & 4 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions glide.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package: github.com/Azure/acs-engine
import:
- package: github.com/Azure/azure-sdk-for-go
version: ~v10.1.0-beta
version: ~v11.0.0-beta
subpackages:
- arm/compute
- arm/network
Expand All @@ -11,7 +11,7 @@ import:
- arm/disk
- storage
- package: github.com/Azure/go-autorest
version: ~8.1.0
version: ~8.4.0
subpackages:
- autorest
- autorest/adal
Expand Down
7 changes: 4 additions & 3 deletions pkg/acsengine/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -747,9 +747,10 @@ func openShiftSetDefaultCerts(a *api.Properties) (bool, error) {
},
Port: 8443,
},
ExternalMasterHostname: externalMasterHostname,
ClusterUsername: a.OrchestratorProfile.OpenShiftConfig.ClusterUsername,
ClusterPassword: a.OrchestratorProfile.OpenShiftConfig.ClusterPassword,
ExternalMasterHostname: externalMasterHostname,
ClusterUsername: a.OrchestratorProfile.OpenShiftConfig.ClusterUsername,
ClusterPassword: a.OrchestratorProfile.OpenShiftConfig.ClusterPassword,
EnableAADAuthentication: a.OrchestratorProfile.OpenShiftConfig.EnableAADAuthentication,
AzureConfig: certgen.AzureConfig{
TenantID: a.AzProfile.TenantID,
SubscriptionID: a.AzProfile.SubscriptionID,
Expand Down
1 change: 1 addition & 0 deletions pkg/api/converterfromapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ func convertOpenShiftConfigToVLabs(api *OpenShiftConfig, vl *vlabs.OpenShiftConf
}
vl.ClusterUsername = api.ClusterUsername
vl.ClusterPassword = api.ClusterPassword
vl.EnableAADAuthentication = api.EnableAADAuthentication
}

func convertDcosConfigToVLabs(api *DcosConfig, vl *vlabs.DcosConfig) {
Expand Down
1 change: 1 addition & 0 deletions pkg/api/convertertoapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ func convertVLabsOpenShiftConfig(vlabs *vlabs.OpenShiftConfig, api *OpenShiftCon
}
api.ClusterUsername = vlabs.ClusterUsername
api.ClusterPassword = vlabs.ClusterPassword
api.EnableAADAuthentication = vlabs.EnableAADAuthentication
}

func convertVLabsKubernetesConfig(vlabs *vlabs.KubernetesConfig, api *KubernetesConfig) {
Expand Down
6 changes: 4 additions & 2 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,13 @@ type DcosConfig struct {
type OpenShiftConfig struct {
KubernetesConfig *KubernetesConfig `json:"kubernetesConfig,omitempty"`

// ClusterUsername and ClusterPassword are temporary before AAD
// authentication is enabled, and will be removed subsequently.
// ClusterUsername and ClusterPassword are temporary, do not rely on them.
ClusterUsername string `json:"clusterUsername,omitempty"`
ClusterPassword string `json:"clusterPassword,omitempty"`

// EnableAADAuthentication is temporary, do not rely on it.
EnableAADAuthentication bool `json:"enableAADAuthentication,omitempty"`

ConfigBundles map[string][]byte `json:"-"`
ExternalMasterHostname string `json:"-"`
RouterLBHostname string `json:"-"`
Expand Down
6 changes: 4 additions & 2 deletions pkg/api/vlabs/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,12 @@ type DcosConfig struct {
type OpenShiftConfig struct {
KubernetesConfig *KubernetesConfig `json:"kubernetesConfig,omitempty"`

// ClusterUsername and ClusterPassword are temporary before AAD
// authentication is enabled, and will be removed subsequently.
// ClusterUsername and ClusterPassword are temporary, do not rely on them.
ClusterUsername string `json:"clusterUsername,omitempty"`
ClusterPassword string `json:"clusterPassword,omitempty"`

// EnableAADAuthentication is temporary, do not rely on it.
EnableAADAuthentication bool `json:"enableAADAuthentication,omitempty"`
}

// MasterProfile represents the definition of the master cluster
Expand Down
4 changes: 3 additions & 1 deletion pkg/armhelpers/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (az *AzureClient) CreateRoleAssignment(scope string, roleAssignmentName str
}

// CreateApp is a simpler method for creating an application
func (az *AzureClient) CreateApp(appName, appURL string) (applicationID, servicePrincipalObjectID, servicePrincipalClientSecret string, err error) {
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)

Expand All @@ -53,6 +53,7 @@ func (az *AzureClient) CreateApp(appName, appURL string) (applicationID, service
DisplayName: to.StringPtr(appName),
Homepage: to.StringPtr(appURL),
IdentifierUris: to.StringSlicePtr([]string{appURL}),
ReplyUrls: replyURLs,
PasswordCredentials: &[]graphrbac.PasswordCredential{
{
KeyID: to.StringPtr(uuid.NewV4().String()),
Expand All @@ -61,6 +62,7 @@ func (az *AzureClient) CreateApp(appName, appURL string) (applicationID, service
Value: to.StringPtr(servicePrincipalClientSecret),
},
},
RequiredResourceAccess: requiredResourceAccess,
}
applicationResp, err := az.CreateGraphApplication(applicationReq)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/armhelpers/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type ACSEngineClient interface {

// CreateGraphPrincipal creates a service principal via the graphrbac client
CreateGraphPrincipal(servicePrincipalCreateParameters graphrbac.ServicePrincipalCreateParameters) (graphrbac.ServicePrincipal, error)
CreateApp(applicationName, applicationURL string) (applicationID, servicePrincipalObjectID, secret string, err error)
CreateApp(applicationName, applicationURL string, replyURLs *[]string, requiredResourceAccess *[]graphrbac.RequiredResourceAccess) (applicationID, servicePrincipalObjectID, secret string, err error)

// RBAC
CreateRoleAssignment(scope string, roleAssignmentName string, parameters authorization.RoleAssignmentCreateParameters) (authorization.RoleAssignment, error)
Expand Down
2 changes: 1 addition & 1 deletion pkg/armhelpers/mockclients.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ func (mc *MockACSEngineClient) CreateGraphPrincipal(servicePrincipalCreateParame
}

// CreateApp is a simpler method for creating an application
func (mc *MockACSEngineClient) CreateApp(applicationName, applicationURL string) (applicationID, servicePrincipalObjectID, secret string, err error) {
func (mc *MockACSEngineClient) CreateApp(applicationName, applicationURL string, replyURLs *[]string, requiredResourceAccess *[]graphrbac.RequiredResourceAccess) (applicationID, servicePrincipalObjectID, secret string, err error) {
return "app-id", "client-id", "client-secret", nil
}

Expand Down
21 changes: 11 additions & 10 deletions pkg/openshift/certgen/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ import (

// Config represents an OpenShift configuration
type Config struct {
ExternalMasterHostname string
serial serial
cas map[string]CertAndKey
AuthSecret string
EncSecret string
Master *Master
Bootstrap KubeConfig
ClusterUsername string
ClusterPassword string
AzureConfig AzureConfig
ExternalMasterHostname string
serial serial
cas map[string]CertAndKey
AuthSecret string
EncSecret string
Master *Master
Bootstrap KubeConfig
ClusterUsername string
ClusterPassword string
EnableAADAuthentication bool
AzureConfig AzureConfig
}

// AzureConfig represents the azure.conf configuration
Expand Down
2 changes: 1 addition & 1 deletion pkg/openshift/certgen/templates/bindata.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,33 @@ oauthConfig:
grantConfig:
method: auto
identityProviders:
- challenge: true
{{- if .EnableAADAuthentication}}
- name: Azure AD
challenge: false
login: true
mappingMethod: claim
provider:
apiVersion: v1
kind: OpenIDIdentityProvider
clientID: {{ .AzureConfig.AADClientID }}
clientSecret: {{ .AzureConfig.AADClientSecret }}
claims:
id:
- sub
preferredUsername:
- unique_name
name:
- name
email:
- email
urls:
authorize: https://login.microsoftonline.com/{{ .AzureConfig.TenantID }}/oauth2/authorize
token: https://login.microsoftonline.com/{{ .AzureConfig.TenantID }}/oauth2/token
{{- end}}
- name: Local password
challenge: true
login: true
mappingMethod: claim
name: htpasswd_auth
provider:
apiVersion: v1
file: /etc/origin/master/htpasswd
Expand Down
16 changes: 12 additions & 4 deletions vendor/github.com/Azure/azure-sdk-for-go/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6f5c9a3

Please sign in to comment.