
com.vmware.photon.controller.model.adapters.azure.instance.AzureInstanceContext Maven / Gradle / Ivy
/*
* Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, without warranties or
* conditions of any kind, EITHER EXPRESS OR IMPLIED. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.vmware.photon.controller.model.adapters.azure.instance;
import java.util.List;
import java.util.stream.Collectors;
import com.microsoft.azure.management.compute.implementation.ImageReferenceInner;
import com.microsoft.azure.management.compute.implementation.VirtualMachineInner;
import com.microsoft.azure.management.network.implementation.NetworkInterfaceInner;
import com.microsoft.azure.management.network.implementation.NetworkSecurityGroupInner;
import com.microsoft.azure.management.network.implementation.NetworkSecurityGroupsInner;
import com.microsoft.azure.management.network.implementation.PublicIPAddressInner;
import com.microsoft.azure.management.network.implementation.SubnetInner;
import com.microsoft.azure.management.network.implementation.SubnetsInner;
import com.microsoft.azure.management.resources.implementation.ResourceGroupInner;
import com.microsoft.azure.management.storage.implementation.StorageAccountInner;
import com.vmware.photon.controller.model.adapterapi.ComputeInstanceRequest;
import com.vmware.photon.controller.model.adapters.azure.utils.AzureDeferredResultServiceCallback;
import com.vmware.photon.controller.model.adapters.azure.utils.AzureSdkClients;
import com.vmware.photon.controller.model.adapters.azure.utils.AzureSecurityGroupUtils;
import com.vmware.photon.controller.model.adapters.azure.utils.AzureUtils;
import com.vmware.photon.controller.model.adapters.util.instance.BaseComputeInstanceContext;
import com.vmware.photon.controller.model.resources.DiskService;
import com.vmware.photon.controller.model.resources.ImageService.ImageState;
import com.vmware.photon.controller.model.resources.ImageService.ImageState.DiskConfiguration;
import com.vmware.photon.controller.model.resources.ResourceGroupService.ResourceGroupState;
import com.vmware.photon.controller.model.resources.SecurityGroupService.SecurityGroupState;
import com.vmware.photon.controller.model.resources.StorageDescriptionService.StorageDescription;
import com.vmware.xenon.common.DeferredResult;
import com.vmware.xenon.services.common.AuthCredentialsService.AuthCredentialsServiceState;
/**
* Context object to store relevant information during different stages.
*/
public class AzureInstanceContext extends
BaseComputeInstanceContext
implements AutoCloseable {
/**
* The class encapsulates NIC related data (both Photon Model and Azure model) used during
* provisioning.
*/
public static class AzureNicContext extends BaseComputeInstanceContext.BaseNicContext {
/**
* The Azure subnet this NIC is associated to. It is either looked up from Azure or created
* by this service.
*/
public SubnetInner subnet;
/**
* The actual NIC object in Azure. It is created by this service.
*/
public NetworkInterfaceInner nic;
/**
* The public IP assigned to the NIC. It is created by this service.
*/
public PublicIPAddressInner publicIP;
/**
* The security group this NIC is assigned to. It is created by this service.
*/
public NetworkSecurityGroupInner securityGroup;
/**
* The resource group state the security group is member of. Optional.
*/
public ResourceGroupState securityGroupRGState;
/**
* A shortcut method to {@code this.securityGroupStates.get(0)}.
*
* @return {@code null} is returned if security group is not specified.
*/
public SecurityGroupState securityGroupState() {
return this.securityGroupStates != null && !this.securityGroupStates.isEmpty()
? this.securityGroupStates.get(0)
: null;
}
}
public AzureInstanceStage stage;
public AuthCredentialsServiceState childAuth;
public StorageDescription storageDescription;
public DiskService.DiskStateExpanded bootDiskState;
public List dataDiskStates;
public String vmName;
public String vmId;
/**
* Holds a ref to provisioned Azure VM. Used by post-provisioning stages to update ComputeState
* and related states (such as Disk, NICs, etc).
*/
VirtualMachineInner provisionedVm;
// Azure specific context {{
//
public AzureSdkClients azureSdkClients;
// The RG the VM provisioning lands
public ResourceGroupInner resourceGroup;
public String storageAccountName;
public String storageAccountRGName;
public StorageAccountInner storageAccount;
public ImageSource imageSource;
public ImageReferenceInner imageReference;
// }}
@Override
public void close() {
if (this.azureSdkClients != null) {
this.azureSdkClients.close();
this.azureSdkClients = null;
}
}
public AzureInstanceContext(AzureInstanceService service,
ComputeInstanceRequest computeRequest) {
super(service, computeRequest, AzureNicContext::new);
}
/**
* Hook into parent populate behavior.
*/
@Override
protected DeferredResult getVMDescription(AzureInstanceContext context) {
return super.getVMDescription(context)
// Populate vm name
.thenApply(ctx -> {
ctx.vmName = ctx.child.name != null ? ctx.child.name : ctx.child.id;
return ctx;
});
}
@Override
protected DeferredResult customizeContext(AzureInstanceContext context) {
return DeferredResult.completed(context)
.thenCompose(this::getNicNetworkResourceGroupStates)
.thenApply(log("getNicNetworkResourceGroupStates"))
.thenCompose(this::getNicSecurityGroupResourceGroupStates)
.thenApply(log("getNicSecurityGroupResourceGroupStates"))
.thenCompose(this::getNetworks)
.thenApply(log("getNetworks"))
.thenCompose(this::getSecurityGroups)
.thenApply(log("getSecurityGroups"));
}
/**
* @return type safe reference to the service using this context.
*/
private AzureInstanceService service() {
return (AzureInstanceService) this.service;
}
/**
* For every NIC lookup associated Azure Subnets as specified by
* {@code AzureNicContext.networkState.name} and {@code AzureNicContext.subnetState.name}. If
* any of the subnets is not found leave the {@link AzureNicContext#subnet} as null and proceed
* without an exception.
*/
private DeferredResult getNetworks(AzureInstanceContext context) {
if (context.nics.isEmpty()) {
return DeferredResult.completed(context);
}
SubnetsInner azureClient = service()
.getNetworkManagementClientImpl(context)
.subnets();
List> getSubnetDRs = context.nics
.stream()
// Filter only vNet-Subnet with existing RG state
.filter(nicCtx -> nicCtx.networkRGState != null)
.map(nicCtx -> {
String msg = "Getting Azure Subnet ["
+ nicCtx.networkRGState.name + "/"
+ nicCtx.networkState.name + "/"
+ nicCtx.subnetState.name
+ "] for [" + nicCtx.nicStateWithDesc.name + "] NIC for ["
+ context.vmName
+ "] VM";
AzureDeferredResultServiceCallback handler = new AzureDeferredResultServiceCallback(
service(), msg) {
@Override
protected DeferredResult consumeSuccess(SubnetInner subnet) {
nicCtx.subnet = subnet;
return DeferredResult.completed(subnet);
}
};
azureClient.getAsync(
nicCtx.networkRGState.name,
nicCtx.networkState.name,
nicCtx.subnetState.name,
null /* expand */,
handler);
return handler.toDeferredResult();
})
.collect(Collectors.toList());
return DeferredResult.allOf(getSubnetDRs)
.handle((all, exc) -> {
if (exc != null) {
String msg = String.format(
"Error getting Subnets from Azure for [%s] VM.",
context.child.name);
throw new IllegalStateException(msg, exc);
}
return context;
});
}
/**
* For every NIC lookup associated Azure Security Groups as specified by
* {@code AzureNicContext.securityGroupState.name}. If any of the security groups is not found
* leave the {@code AzureNicContext.securityGroup} as null and proceed without an exception.
*/
private DeferredResult getSecurityGroups(AzureInstanceContext context) {
if (context.nics.isEmpty()) {
return DeferredResult.completed(context);
}
NetworkSecurityGroupsInner azureClient = context.azureSdkClients
.getNetworkManagementClientImpl()
.networkSecurityGroups();
List> getSecurityGroupDRs = context.nics
.stream()
// Filter only SGs with existing RG state
.filter(nicCtx -> nicCtx.securityGroupState() != null
&& nicCtx.securityGroupRGState != null)
.map(nicCtx -> {
String sgName = nicCtx.securityGroupState().name;
String msg = "Getting Azure Security Group ["
+ nicCtx.securityGroupRGState.name + "/" + sgName
+ "] for [" + nicCtx.nicStateWithDesc.name + "] NIC for ["
+ context.vmName
+ "] VM";
return AzureSecurityGroupUtils.getSecurityGroup(service(), azureClient,
nicCtx.securityGroupRGState.name, sgName, msg)
.thenApply(sg -> {
nicCtx.securityGroup = sg;
return sg;
});
})
.collect(Collectors.toList());
return DeferredResult.allOf(getSecurityGroupDRs)
.handle((all, exc) -> {
if (exc != null) {
String msg = String.format(
"Error getting Security Group from Azure for [%s] VM.",
context.child.name);
throw new IllegalStateException(msg, exc);
}
return context;
});
}
/**
* Get {@link ResourceGroupState}s of the {@code NetworkState}s the NICs are assigned to. If any
* of the RGs is not specified or not found leave the {@link AzureNicContext#networkRGState} as
* null and proceed without an exception.
*/
protected DeferredResult getNicNetworkResourceGroupStates(
AzureInstanceContext context) {
if (context.nics.isEmpty()) {
return DeferredResult.completed(context);
}
List> getStatesDR = context.nics.stream()
.filter(nicCtx -> nicCtx.networkState != null
&& nicCtx.networkState.groupLinks != null
&& !nicCtx.networkState.groupLinks.isEmpty())
.map(nicCtx -> AzureUtils.filterRGsByType(service().getHost(),
nicCtx.networkState.groupLinks, context.child.endpointLink,
context.childAuth.tenantLinks)
.thenAccept(rgState -> nicCtx.networkRGState = rgState))
.collect(Collectors.toList());
return DeferredResult.allOf(getStatesDR).handle((all, exc) -> {
if (exc != null) {
String msg = String.format(
"Error getting ResourceGroup states of NIC Network states for [%s] VM",
context.child.name);
throw new IllegalStateException(msg, exc);
}
return context;
});
}
/**
* Get {@link ResourceGroupState}s of the {@link SecurityGroupState}s the NICs are assigned to.
* If any of the RGs is not specified or not found leave the
* {@link AzureNicContext#securityGroupRGState} as null and proceed without an exception.
*/
private DeferredResult getNicSecurityGroupResourceGroupStates(
AzureInstanceContext context) {
if (context.nics.isEmpty()) {
return DeferredResult.completed(context);
}
List> getStatesDR = context.nics.stream()
.filter(nicCtx -> nicCtx.securityGroupState() != null
&& nicCtx.securityGroupState().groupLinks != null
&& !nicCtx.securityGroupState().groupLinks.isEmpty())
.map(nicCtx -> AzureUtils.filterRGsByType(service().getHost(),
nicCtx.securityGroupState().groupLinks, context.child.endpointLink,
context.childAuth.tenantLinks)
.thenAccept(rgState -> nicCtx.securityGroupRGState = rgState))
.collect(Collectors.toList());
return DeferredResult.allOf(getStatesDR).handle((all, exc) -> {
if (exc != null) {
String msg = String.format(
"Error getting ResourceGroup states of NIC Security Group states for [%s] VM.",
context.child.name);
throw new IllegalStateException(msg, exc);
}
return context;
});
}
/**
* Shortcut method to image OS disk configuration:
* {@code this.imageSource.asImage().diskConfigs.get(0)}.
*
* @return might be null
*/
DiskConfiguration imageOsDisk() {
if (this.imageSource == null || this.imageSource.asImageState() == null) {
return null;
}
ImageState image = this.imageSource.asImageState();
if (image.diskConfigs == null || image.diskConfigs.isEmpty()) {
return null;
}
return image.diskConfigs.get(0);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy