/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for
* license information.
*/
package com.microsoft.azure.management.keyvault.implementation;
import com.microsoft.azure.CloudException;
import com.microsoft.azure.management.apigeneration.LangDefinition;
import com.microsoft.azure.management.graphrbac.ServicePrincipal;
import com.microsoft.azure.management.graphrbac.User;
import com.microsoft.azure.management.graphrbac.implementation.GraphRbacManager;
import com.microsoft.azure.management.keyvault.AccessPolicy;
import com.microsoft.azure.management.keyvault.AccessPolicyEntry;
import com.microsoft.azure.management.keyvault.Sku;
import com.microsoft.azure.management.keyvault.SkuName;
import com.microsoft.azure.management.keyvault.Vault;
import com.microsoft.azure.management.keyvault.VaultProperties;
import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl;
import com.microsoft.azure.management.resources.fluentcore.utils.SdkContext;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.functions.FuncN;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
/**
* Implementation for Vault and its parent interfaces.
*/
@LangDefinition
class VaultImpl
extends GroupableResourceImpl<
Vault,
VaultInner,
VaultImpl,
KeyVaultManager>
implements
Vault,
Vault.Definition,
Vault.Update {
private GraphRbacManager graphRbacManager;
private List<AccessPolicyImpl> accessPolicies;
VaultImpl(String key, VaultInner innerObject, KeyVaultManager manager, GraphRbacManager graphRbacManager) {
super(key, innerObject, manager);
this.graphRbacManager = graphRbacManager;
this.accessPolicies = new ArrayList<>();
if (innerObject != null && innerObject.properties() != null && innerObject.properties().accessPolicies() != null) {
for (AccessPolicyEntry entry : innerObject.properties().accessPolicies()) {
this.accessPolicies.add(new AccessPolicyImpl(entry, this));
}
}
}
@Override
public String vaultUri() {
if (inner().properties() == null) {
return null;
}
return inner().properties().vaultUri();
}
@Override
public String tenantId() {
if (inner().properties() == null) {
return null;
}
if (inner().properties().tenantId() == null) {
return null;
}
return inner().properties().tenantId().toString();
}
@Override
public Sku sku() {
if (inner().properties() == null) {
return null;
}
return inner().properties().sku();
}
@Override
public List<AccessPolicy> accessPolicies() {
AccessPolicy[] array = new AccessPolicy[accessPolicies.size()];
return Arrays.asList(accessPolicies.toArray(array));
}
@Override
public boolean enabledForDeployment() {
if (inner().properties() == null || inner().properties().enabledForDeployment() == null) {
return false;
}
return inner().properties().enabledForDeployment();
}
@Override
public boolean enabledForDiskEncryption() {
if (inner().properties() == null || inner().properties().enabledForDiskEncryption() == null) {
return false;
}
return inner().properties().enabledForDiskEncryption();
}
@Override
public boolean enabledForTemplateDeployment() {
if (inner().properties() == null || inner().properties().enabledForTemplateDeployment()) {
return false;
}
return inner().properties().enabledForTemplateDeployment();
}
@Override
public VaultImpl withEmptyAccessPolicy() {
this.accessPolicies = new ArrayList<>();
return this;
}
@Override
public VaultImpl withoutAccessPolicy(String objectId) {
for (AccessPolicyImpl entry : this.accessPolicies) {
if (entry.objectId().equals(objectId)) {
accessPolicies.remove(entry);
break;
}
}
return this;
}
@Override
public VaultImpl withAccessPolicy(AccessPolicy accessPolicy) {
accessPolicies.add((AccessPolicyImpl) accessPolicy);
return this;
}
@Override
public AccessPolicyImpl defineAccessPolicy() {
return new AccessPolicyImpl(new AccessPolicyEntry(), this);
}
@Override
public AccessPolicyImpl updateAccessPolicy(String objectId) {
for (AccessPolicyImpl entry : this.accessPolicies) {
if (entry.objectId().equals(objectId)) {
return entry;
}
}
throw new NoSuchElementException(String.format("Identity %s not found in the access policies.", objectId));
}
@Override
public VaultImpl withDeploymentEnabled() {
inner().properties().withEnabledForDeployment(true);
return this;
}
@Override
public VaultImpl withDiskEncryptionEnabled() {
inner().properties().withEnabledForDiskEncryption(true);
return this;
}
@Override
public VaultImpl withTemplateDeploymentEnabled() {
inner().properties().withEnabledForTemplateDeployment(true);
return this;
}
@Override
public VaultImpl withDeploymentDisabled() {
inner().properties().withEnabledForDeployment(false);
return this;
}
@Override
public VaultImpl withDiskEncryptionDisabled() {
inner().properties().withEnabledForDiskEncryption(false);
return this;
}
@Override
public VaultImpl withTemplateDeploymentDisabled() {
inner().properties().withEnabledForTemplateDeployment(false);
return this;
}
@Override
public VaultImpl withSku(SkuName skuName) {
if (inner().properties() == null) {
inner().withProperties(new VaultProperties());
}
inner().properties().withSku(new Sku().withName(skuName));
return this;
}
private Observable<List<AccessPolicy>> populateAccessPolicies() {
List<Observable<?>>observables = new ArrayList<>();
for (final AccessPolicyImpl accessPolicy : accessPolicies) {
if (accessPolicy.objectId() == null) {
if (accessPolicy.userPrincipalName() != null) {
observables.add(graphRbacManager.users().getByUserPrincipalNameAsync(accessPolicy.userPrincipalName())
.subscribeOn(SdkContext.getRxScheduler())
.doOnNext(new Action1<User>() {
@Override
public void call(User user) {
if (user == null) {
throw new CloudException(String.format("User principal name %s is not found in tenant %s",
accessPolicy.userPrincipalName(), graphRbacManager.tenantId()), null);
}
accessPolicy.forObjectId(user.objectId());
}
}));
} else if (accessPolicy.servicePrincipalName() != null) {
observables.add(graphRbacManager.servicePrincipals().getByServicePrincipalNameAsync(accessPolicy.servicePrincipalName())
.subscribeOn(SdkContext.getRxScheduler())
.doOnNext(new Action1<ServicePrincipal>() {
@Override
public void call(ServicePrincipal sp) {
if (sp == null) {
throw new CloudException(String.format("User principal name %s is not found in tenant %s",
accessPolicy.userPrincipalName(), graphRbacManager.tenantId()), null);
}
accessPolicy.forObjectId(sp.objectId());
}
}));
} else {
throw new IllegalArgumentException("Access policy must specify object ID.");
}
}
}
if (observables.isEmpty()) {
return Observable.just(accessPolicies());
} else {
return Observable.zip(observables, new FuncN<List<AccessPolicy>>() {
@Override
public List<AccessPolicy> call(Object... args) {
return accessPolicies();
}
});
}
}
@Override
public Observable<Vault> createResourceAsync() {
final VaultsInner client = this.manager().inner().vaults();
return populateAccessPolicies()
.flatMap(new Func1<Object, Observable<VaultInner>>() {
@Override
public Observable<VaultInner> call(Object o) {
VaultCreateOrUpdateParametersInner parameters = new VaultCreateOrUpdateParametersInner();
parameters.withLocation(regionName());
parameters.withProperties(inner().properties());
parameters.withTags(inner().getTags());
parameters.properties().withAccessPolicies(new ArrayList<AccessPolicyEntry>());
for (AccessPolicy accessPolicy : accessPolicies) {
parameters.properties().accessPolicies().add(accessPolicy.inner());
}
return client.createOrUpdateAsync(resourceGroupName(), name(), parameters);
}
})
.map(innerToFluentMap(this));
}
@Override
protected Observable<VaultInner> getInnerAsync() {
return this.manager().inner().vaults().getByResourceGroupAsync(resourceGroupName(), name());
}
}