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 }