func getServicePrincipal(client ad.ServicePrincipalsClient) (ad.ServicePrincipal, error) { // TODO(axw) filter by Service Principal Name (SPN). // It works without that, but the response is noisy. result, err := client.List("") if err != nil { return ad.ServicePrincipal{}, errors.Annotate(err, "listing service principals") } for _, sp := range result.Value { if sp.ApplicationID == jujuApplicationId { return sp, nil } } return ad.ServicePrincipal{}, errors.NotFoundf("service principal") }
func addServicePrincipalPasswordCredential( client ad.ServicePrincipalsClient, servicePrincipalObjectId string, passwordCredential ad.PasswordCredential, ) error { existing, err := client.ListPasswordCredentials(servicePrincipalObjectId) if err != nil { return errors.Trace(err) } passwordCredentials := append(existing.Value, passwordCredential) _, err = client.UpdatePasswordCredentials( servicePrincipalObjectId, ad.PasswordCredentialsUpdateParameters{passwordCredentials}, ) return errors.Trace(err) }
func createOrUpdateServicePrincipal( client ad.ServicePrincipalsClient, subscriptionId string, clock clock.Clock, newUUID func() (utils.UUID, error), ) (servicePrincipalObjectId, password string, _ error) { passwordCredential, err := preparePasswordCredential(clock, newUUID) if err != nil { return "", "", errors.Annotate(err, "preparing password credential") } servicePrincipal, err := client.Create( ad.ServicePrincipalCreateParameters{ ApplicationID: jujuApplicationId, AccountEnabled: true, PasswordCredentials: []ad.PasswordCredential{passwordCredential}, }, nil, // abort ) if err != nil { if !isMultipleObjectsWithSameKeyValueErr(err) { return "", "", errors.Trace(err) } // The service principal already exists, so we'll fall out // and update the service principal's password credentials. } else { // The service principal was created successfully, with the // requested password credential. return servicePrincipal.ObjectID, passwordCredential.Value, nil } // The service principal already exists, so we need to query // its object ID, and fetch the existing password credentials // to update. servicePrincipal, err = getServicePrincipal(client) if err != nil { return "", "", errors.Trace(err) } if err := addServicePrincipalPasswordCredential( client, servicePrincipal.ObjectID, passwordCredential, ); err != nil { return "", "", errors.Annotate(err, "updating password credentials") } return servicePrincipal.ObjectID, passwordCredential.Value, nil }