Skip to content

Commit

Permalink
adding singleton pattern in Arm.Core and Proto (#20591)
Browse files Browse the repository at this point in the history
* adding initial singleton base classs and proto code

* PR comment fix.

* Completed singleton VMSS test case.

* Fix merge issue around ArmBuilder removal

* Fix build issue.

* Fixing test failure

* CR comment.

* Flattend the builder to partial classes.

* CR fix
  • Loading branch information
allenjzhang authored May 4, 2021
1 parent 8e09003 commit c7f7289
Show file tree
Hide file tree
Showing 21 changed files with 1,667 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,14 @@ private ArmClient(
TokenCredential credential,
ArmClientOptions options)
{
Pipeline = ManagementPipelineBuilder.Build(credential, baseUri, options);
Credential = credential;
BaseUri = baseUri;
if (credential is null)
throw new ArgumentNullException(nameof(credential));

Credential = credential;
BaseUri = baseUri;
ClientOptions = options?.Clone() ?? new ArmClientOptions();
Pipeline = ManagementPipelineBuilder.Build(Credential, BaseUri, ClientOptions);

DefaultSubscription = string.IsNullOrWhiteSpace(defaultSubscriptionId)
? GetDefaultSubscription()
: GetSubscriptions().TryGet(defaultSubscriptionId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Azure.ResourceManager.Core
{
/// <summary>
/// A class representing the operations that can be performed over a specific resource.
/// </summary>
public abstract class SingletonOperationsBase : OperationsBase
{
/// <summary>
/// Initializes a new instance of the <see cref="SingletonOperationsBase"/> class for mocking.
/// </summary>
protected SingletonOperationsBase()
{
}

/// <summary>
/// Initializes a new instance of the <see cref="SingletonOperationsBase"/> class.
/// </summary>
/// <param name="parent"></param>
internal SingletonOperationsBase(OperationsBase parent)
: base(new ClientContext(parent.ClientOptions, parent.Credential, parent.BaseUri, parent.Pipeline), ResourceIdentifier.RootResourceIdentifier)
{
Parent = parent;
ParentId = parent.Id;
}

/// <summary>
/// Gets the parent resource of this resource.
/// </summary>
protected OperationsBase Parent { get; }

/// <summary>
/// The typed resource identifier for the underlying resource
/// </summary>
public ResourceIdentifier ParentId
{
get;
}
}

/// <summary>
/// Base class representing a singleton operation
/// </summary>
/// <typeparam name="TOperations"> The type of the class containing operations for the underlying resource. </typeparam>
/// <typeparam name="TIdentifier"> The type of the resource identifier. </typeparam>
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "<Pending>")]
public abstract class SingletonOperationsBase<TIdentifier, TOperations> : SingletonOperationsBase
where TOperations : SingletonOperationsBase<TIdentifier, TOperations>
where TIdentifier : ResourceIdentifier
{
/// <summary>
/// Initializes a new instance of the <see cref="SingletonOperationsBase{TIdentifier, TOperations}"/> class for mocking.
/// </summary>
protected SingletonOperationsBase()
{
}

/// <summary>
/// Initializes a new instance of the <see cref="ContainerBase{TOperations, TIdentifier}"/> class.
/// </summary>
/// <param name="parent"> The resource representing the parent resource. </param>
protected SingletonOperationsBase(OperationsBase parent)
: base(parent)
{
ParentId = parent.Id as TIdentifier;
if (string.IsNullOrWhiteSpace(ParentId))
{
throw new InvalidOperationException();
}
}

/// <summary>
/// The typed resource identifier for the underlying resource
/// </summary>
protected new TIdentifier ParentId
{
get;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using Azure.ResourceManager.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using Azure.ResourceManager.Compute.Models;

namespace Proto.Compute
{
/// <summary>
/// A class representing a builder object to help create a virtual machine.
/// </summary>
public partial class VirtualMachineScaleSetBuilder
{
public VirtualMachineScaleSetBuilder WithUseWindowsImage(string computerNamePrefix, string adminUser, string password)
{
_model.VirtualMachineProfile.OsProfile = new VirtualMachineScaleSetOSProfile()
{
ComputerNamePrefix = computerNamePrefix,
AdminUsername = adminUser,
AdminPassword = password,
WindowsConfiguration = new WindowsConfiguration { TimeZone = "Pacific Standard Time", ProvisionVMAgent = true }
};

return this;
}

public VirtualMachineScaleSetBuilder WithUseLinuxImage(string computerNamePrefix, string adminUser, string password)
{
_model.VirtualMachineProfile.OsProfile = new VirtualMachineScaleSetOSProfile()
{
ComputerNamePrefix = computerNamePrefix,
AdminUsername = adminUser,
AdminPassword = password,
LinuxConfiguration = new LinuxConfiguration
{
DisablePasswordAuthentication = false,
ProvisionVMAgent = true
}
};

return this;
}

public VirtualMachineScaleSetBuilder WithRequiredPrimaryNetworkInterface(
string name,
ResourceIdentifier subNetResourceId,
ICollection<ResourceIdentifier> backendAddressPoolResourceIds,
ICollection<ResourceIdentifier> inboundNatPoolResourceIds)
{
var ipconfig = new VirtualMachineScaleSetIPConfiguration($"{name}PrimaryIPConfig")
{
Subnet = new ApiEntityReference() { Id = subNetResourceId },
};
foreach (var id in backendAddressPoolResourceIds)
{
ipconfig.LoadBalancerBackendAddressPools.Add(
new Azure.ResourceManager.Compute.Models.SubResource { Id = id });
}
foreach (var id in inboundNatPoolResourceIds)
{
ipconfig.LoadBalancerInboundNatPools.Add(
new Azure.ResourceManager.Compute.Models.SubResource { Id = id });
}

var nicConfig = new VirtualMachineScaleSetNetworkConfiguration(name)
{
Primary = true,
};
nicConfig.IpConfigurations.Add(ipconfig);

_model.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations.Add(nicConfig);

return this;
}

public VirtualMachineScaleSetBuilder WithRequiredLoadBalancer(ResourceIdentifier asetResourceId)
{
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ public static VirtualMachineContainer GetVirtualMachines(this ResourceGroupOpera
return new VirtualMachineContainer(resourceGroup);
}

/// <summary>
/// Gets an object representing a VirtualMachineScaleSetContainer along with the instance operations that can be performed on it.
/// </summary>
/// <param name="resourceGroup"> The <see cref="ResourceGroupOperations" /> instance the method will execute against. </param>
/// <returns> Returns a <see cref="VirtualMachineScaleSetContainer" /> object. </returns>
public static VirtualMachineScaleSetContainer GetVirtualMachineScaleSet(this ResourceGroupOperations resourceGroup)
{
return new VirtualMachineScaleSetContainer(resourceGroup);
}

/// <summary>
/// Gets an object representing a AvailabilitySetContainer along with the instance operations that can be performed on it.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using Azure.ResourceManager.Compute.Models;
using Azure.ResourceManager.Core;

namespace Proto.Compute
{
/// <summary> The status of the latest virtual machine scale set rolling upgrade. </summary>
public partial class RollingUpgradeStatusInfo : Resource<ResourceGroupResourceIdentifier>
{
/// <summary>
/// Initializes a new instance of the <see cref="rollingUpgradeStatusInfo"/> class.
/// </summary>
public RollingUpgradeStatusInfo(Azure.ResourceManager.Compute.Models.RollingUpgradeStatusInfo rollingUpgradeStatusInfo)
: base(rollingUpgradeStatusInfo.Id, rollingUpgradeStatusInfo.Name, RollingUpgradeOperations.ResourceType)
{
Model = rollingUpgradeStatusInfo;
}

/// <summary>
/// Gets or sets the Model this resource is based of.
///</summary>
public virtual Azure.ResourceManager.Compute.Models.RollingUpgradeStatusInfo Model { get; }

/// <summary>
/// Gets the subnet id.
///</summary>
public override string Name => Model.Name;

/// <summary> The rolling upgrade policies applied for this upgrade. </summary>
public RollingUpgradePolicy Policy => Model.Policy;

/// <summary> Information about the current running state of the overall upgrade. </summary>
public RollingUpgradeRunningStatus RunningStatus => Model.RunningStatus;

/// <summary> Information about the number of virtual machine instances in each upgrade state. </summary>
public RollingUpgradeProgressInfo Progress => Model.Progress;

/// <summary> Error details for this upgrade, if there are any. </summary>
public ApiError Error => Model.Error;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using Azure.ResourceManager.Compute.Models;
using Azure.ResourceManager.Core;
using Azure.ResourceManager.Core.Adapters;
using System.Collections.Generic;

namespace Proto.Compute
{
/// <summary> A class representing the VirtualMachineScaleSet data model. </summary>
public partial class VirtualMachineScaleSetData : TrackedResource<ResourceGroupResourceIdentifier, Azure.ResourceManager.Compute.Models.VirtualMachineScaleSet>
{
/// <summary> Initializes a new instance of VirtualMachineScaleSetData. </summary>
public VirtualMachineScaleSetData(Azure.ResourceManager.Compute.Models.VirtualMachineScaleSet vmScaleSet)
: base(vmScaleSet.Id, vmScaleSet.Location, vmScaleSet)
{
Sku = vmScaleSet.Sku;
Plan = vmScaleSet.Plan;
Identity = vmScaleSet.Identity;
Zones = vmScaleSet.Zones;
UpgradePolicy = vmScaleSet.UpgradePolicy;
AutomaticRepairsPolicy = vmScaleSet.AutomaticRepairsPolicy;
VirtualMachineProfile = vmScaleSet.VirtualMachineProfile;
ProvisioningState = vmScaleSet.ProvisioningState;
Overprovision = vmScaleSet.Overprovision;
DoNotRunExtensionsOnOverprovisionedVMs = vmScaleSet.DoNotRunExtensionsOnOverprovisionedVMs;
UniqueId = vmScaleSet.UniqueId;
SinglePlacementGroup = vmScaleSet.SinglePlacementGroup;
ZoneBalance = vmScaleSet.ZoneBalance;
PlatformFaultDomainCount = vmScaleSet.PlatformFaultDomainCount;
ProximityPlacementGroup = vmScaleSet.ProximityPlacementGroup;
AdditionalCapabilities = vmScaleSet.AdditionalCapabilities;
ScaleInPolicy = vmScaleSet.ScaleInPolicy;
}

/// <summary> The virtual machine scale set sku. </summary>
public Azure.ResourceManager.Compute.Models.Sku Sku { get; set; }
/// <summary> Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use. In the Azure portal, find the marketplace image that you want to use and then click **Want to deploy programmatically, Get Started -&gt;**. Enter any required information and then click **Save**. </summary>
public Azure.ResourceManager.Compute.Models.Plan Plan { get; set; }
/// <summary> The identity of the virtual machine scale set, if configured. </summary>
public VirtualMachineScaleSetIdentity Identity { get; set; }
/// <summary> The virtual machine scale set zones. NOTE: Availability zones can only be set when you create the scale set. </summary>
public IList<string> Zones { get; }
/// <summary> The upgrade policy. </summary>
public UpgradePolicy UpgradePolicy { get; set; }
/// <summary> Policy for automatic repairs. </summary>
public AutomaticRepairsPolicy AutomaticRepairsPolicy { get; set; }
/// <summary> The virtual machine profile. </summary>
public VirtualMachineScaleSetVMProfile VirtualMachineProfile { get; set; }
/// <summary> The provisioning state, which only appears in the response. </summary>
public string ProvisioningState { get; }
/// <summary> Specifies whether the Virtual Machine Scale Set should be overprovisioned. </summary>
public bool? Overprovision { get; set; }
/// <summary> When Overprovision is enabled, extensions are launched only on the requested number of VMs which are finally kept. This property will hence ensure that the extensions do not run on the extra overprovisioned VMs. </summary>
public bool? DoNotRunExtensionsOnOverprovisionedVMs { get; set; }
/// <summary> Specifies the ID which uniquely identifies a Virtual Machine Scale Set. </summary>
public string UniqueId { get; }
/// <summary> When true this limits the scale set to a single placement group, of max size 100 virtual machines. NOTE: If singlePlacementGroup is true, it may be modified to false. However, if singlePlacementGroup is false, it may not be modified to true. </summary>
public bool? SinglePlacementGroup { get; set; }
/// <summary> Whether to force strictly even Virtual Machine distribution cross x-zones in case there is zone outage. </summary>
public bool? ZoneBalance { get; set; }
/// <summary> Fault Domain count for each placement group. </summary>
public int? PlatformFaultDomainCount { get; set; }
/// <summary> Specifies information about the proximity placement group that the virtual machine scale set should be assigned to. &lt;br&gt;&lt;br&gt;Minimum api-version: 2018-04-01. </summary>
public Azure.ResourceManager.Compute.Models.SubResource ProximityPlacementGroup { get; set; }
/// <summary> Specifies information about the dedicated host group that the virtual machine scale set resides in. &lt;br&gt;&lt;br&gt;Minimum api-version: 2020-06-01. </summary>
public Azure.ResourceManager.Compute.Models.SubResource HostGroup { get; set; }
/// <summary> Specifies additional capabilities enabled or disabled on the Virtual Machines in the Virtual Machine Scale Set. For instance: whether the Virtual Machines have the capability to support attaching managed data disks with UltraSSD_LRS storage account type. </summary>
public AdditionalCapabilities AdditionalCapabilities { get; set; }
/// <summary> Specifies the scale-in policy that decides which virtual machines are chosen for removal when a Virtual Machine Scale Set is scaled-in. </summary>
public ScaleInPolicy ScaleInPolicy { get; set; }
}
}
33 changes: 33 additions & 0 deletions sdk/resourcemanager/Proto.Client/compute/RollingUpgrade.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

using System.Threading;
using System.Threading.Tasks;
using Azure.ResourceManager.Core;

#nullable disable

namespace Proto.Compute
{
/// <summary> A Class representing a VirtualMachineScaleSetRollingUpgrade along with the instance operations that can be performed on it. </summary>
public class RollingUpgrade : RollingUpgradeOperations
{
/// <summary>
/// Gets the data representing this VirtualMachine.
/// </summary>
public RollingUpgradeStatusInfo Data { get; private set; }

/// <summary>
/// Initializes a new instance of the <see cref="RollingUpgrade"/> class.
/// </summary>
/// <param name="operations"> The client parameters to use in these operations. </param>
/// <param name="resource"> The resource that is the target of operations. </param>
internal RollingUpgrade(OperationsBase operations, RollingUpgradeStatusInfo resource)
: base(operations)
{
Data = resource;
}
}
}
Loading

0 comments on commit c7f7289

Please sign in to comment.