RoleAssignmentImpl.java
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.resourcemanager.authorization.implementation;
import com.azure.core.management.exception.ManagementException;
import com.azure.core.util.logging.ClientLogger;
import com.azure.resourcemanager.authorization.AuthorizationManager;
import com.azure.resourcemanager.authorization.models.ActiveDirectoryGroup;
import com.azure.resourcemanager.authorization.models.ActiveDirectoryUser;
import com.azure.resourcemanager.authorization.models.BuiltInRole;
import com.azure.resourcemanager.authorization.models.RoleAssignment;
import com.azure.resourcemanager.authorization.models.RoleAssignmentCreateParameters;
import com.azure.resourcemanager.authorization.models.ServicePrincipal;
import com.azure.resourcemanager.authorization.fluent.models.RoleAssignmentInner;
import com.azure.resourcemanager.resources.models.ResourceGroup;
import com.azure.resourcemanager.resources.fluentcore.arm.models.Resource;
import com.azure.resourcemanager.resources.fluentcore.model.implementation.CreatableImpl;
import com.azure.resourcemanager.resources.fluentcore.utils.ResourceManagerUtils;
import reactor.core.Exceptions;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.util.retry.Retry;
import java.time.Duration;
import java.util.Locale;
/** Implementation for ServicePrincipal and its parent interfaces. */
class RoleAssignmentImpl extends CreatableImpl<RoleAssignment, RoleAssignmentInner, RoleAssignmentImpl>
implements RoleAssignment, RoleAssignment.Definition {
private AuthorizationManager manager;
// Active Directory identify info
private String objectId;
private String userName;
private String servicePrincipalName;
// role info
private String roleDefinitionId;
private String roleName;
private final ClientLogger logger = new ClientLogger(RoleAssignmentImpl.class);
RoleAssignmentImpl(String name, RoleAssignmentInner innerObject, AuthorizationManager manager) {
super(name, innerObject);
this.manager = manager;
}
@Override
public boolean isInCreateMode() {
return innerModel().id() == null;
}
@Override
public Mono<RoleAssignment> createResourceAsync() {
Mono<String> objectIdObservable;
if (objectId != null) {
objectIdObservable = Mono.just(objectId);
} else if (userName != null) {
objectIdObservable = manager.users().getByNameAsync(userName).map(user -> user.id());
} else if (servicePrincipalName != null) {
objectIdObservable = manager.servicePrincipals().getByNameAsync(servicePrincipalName).map(sp -> sp.id());
} else {
throw logger.logExceptionAsError(new IllegalArgumentException(
"Please pass a non-null value for either object Id, user, group, or service principal"));
}
Mono<String> roleDefinitionIdObservable;
if (roleDefinitionId != null) {
roleDefinitionIdObservable = Mono.just(roleDefinitionId);
} else if (roleName != null) {
roleDefinitionIdObservable =
manager()
.roleDefinitions()
.getByScopeAndRoleNameAsync(scope(), roleName)
.map(roleDefinition -> roleDefinition.id());
} else {
throw logger.logExceptionAsError(new IllegalArgumentException(
"Please pass a non-null value for either role name or role definition ID"));
}
return Mono
.zip(
objectIdObservable,
roleDefinitionIdObservable,
(objectId, roleDefinitionId) ->
new RoleAssignmentCreateParameters()
.withPrincipalId(objectId)
.withRoleDefinitionId(roleDefinitionId))
.flatMap(
roleAssignmentPropertiesInner ->
manager()
.roleServiceClient()
.getRoleAssignments()
.createAsync(scope(), name(), roleAssignmentPropertiesInner)
.retryWhen(Retry.withThrowable(
throwableFlux ->
throwableFlux
.zipWith(
Flux.range(1, 30),
(throwable, integer) -> {
if (throwable instanceof ManagementException) {
ManagementException managementException =
(ManagementException) throwable;
String exceptionMessage =
managementException.getMessage().toLowerCase(Locale.ROOT);
if (exceptionMessage.contains("principalnotfound")
|| exceptionMessage.contains("does not exist in the directory")) {
/*
* ref:
* https://github.com/Azure/azure-cli/blob/dev/src/command_modules/azure-cli-role/azure/cli/command_modules/role/custom.py#L1048-L1065
*/
return integer;
} else {
throw logger.logExceptionAsError(Exceptions.propagate(throwable));
}
} else {
throw logger.logExceptionAsError(Exceptions.propagate(throwable));
}
})
.flatMap(i -> Mono.delay(ResourceManagerUtils.InternalRuntimeContext
.getDelayDuration(Duration.ofSeconds(i)))))))
.map(innerToFluentMap(this));
}
@Override
protected Mono<RoleAssignmentInner> getInnerAsync() {
return manager.roleServiceClient().getRoleAssignments().getAsync(scope(), name());
}
@Override
public String scope() {
return innerModel().scope();
}
@Override
public String roleDefinitionId() {
return innerModel().roleDefinitionId();
}
@Override
public String principalId() {
return innerModel().principalId();
}
@Override
public RoleAssignmentImpl forObjectId(String objectId) {
this.objectId = objectId;
return this;
}
@Override
public RoleAssignmentImpl forUser(ActiveDirectoryUser user) {
this.objectId = user.id();
return this;
}
@Override
public RoleAssignmentImpl forUser(String name) {
this.userName = name;
return this;
}
@Override
public RoleAssignmentImpl forGroup(ActiveDirectoryGroup activeDirectoryGroup) {
this.objectId = activeDirectoryGroup.id();
return this;
}
@Override
public RoleAssignmentImpl forServicePrincipal(ServicePrincipal servicePrincipal) {
this.objectId = servicePrincipal.id();
return this;
}
@Override
public RoleAssignmentImpl forServicePrincipal(String servicePrincipalName) {
this.servicePrincipalName = servicePrincipalName;
return this;
}
@Override
public RoleAssignmentImpl withBuiltInRole(BuiltInRole role) {
this.roleName = role.toString();
return this;
}
@Override
public RoleAssignmentImpl withRoleDefinition(String roleDefinitionId) {
this.roleDefinitionId = roleDefinitionId;
return this;
}
@Override
public RoleAssignmentImpl withScope(String scope) {
this.innerModel().withScope(scope);
return this;
}
@Override
public RoleAssignmentImpl withResourceGroupScope(ResourceGroup resourceGroup) {
return withScope(resourceGroup.id());
}
@Override
public RoleAssignmentImpl withResourceScope(Resource resource) {
return withScope(resource.id());
}
@Override
public RoleAssignmentImpl withSubscriptionScope(String subscriptionId) {
return withScope("subscriptions/" + subscriptionId);
}
@Override
public String id() {
return innerModel().id();
}
@Override
public AuthorizationManager manager() {
return this.manager;
}
}