Solving problems invented by others...
My journey to automate vCloud Director with PowerShell – part #5  : add and remove storage profiles

My journey to automate vCloud Director with PowerShell – part #5 : add and remove storage profiles

Storage profiles were, for me, a very tricky part to handle. This because I, at first, did not understand the way how the procedure works to add or remove them from an OrgVDC or ProviderVDC.

To save you some time, the procedure is as follows:

  • Create an storage profile “change” object, where you define what you want to change at the OrgVDC or ProviderVDC.
  • Execute the proper method of the VDC object and pass it the “change” object as parameter.

In my vCloud Director design I have a storage profile per customer. So creating an organization and a OrgVDC involves adding a storage profile which is not known till now. At this time I assume that this storage profile already exists in the vSphere environment and simply had to be added to vCloud Director.

Following the procedure I normally would do in the UI I want to refresh the available storage profiles from the vSphere environment and add them to the ProviderVDC.

I found the vCenter refresh method in objects of type VirtualCenter. Since I found no way to just access the already known vCenters in vCloud Director I had to use the Search-Cloud commandlet to get all vCenter servers.

# get all connected virtual centers
$virtualcenters = Search-Cloud -QueryType VirtualCenter

After I got all vCenter server object, I had to loop through it to execute the RefreshStorageProfiles() method.

# loop through all virtual centers
foreach ( $virtualcenter in $virtualcenters )
{

    # load new available storage profiles
    ($virtualcenter | Get-CIView).RefreshStorageProfiles()
}

The pitfall here was that the normal vCenter object does not contain the RefreshStorageProfiles() method. I had to use the Get-CIView commandlet to get a different view of this object which contains the needed method.

After doing a refresh on all found vCenter objects, the next step was to add the new found storage profiles to the ProviderVDC. In my case I used a distinct identifier for all objects of this customer so I could simply search for this string and add all storage profiles containing it.

From the former task I still have a reference to the ProviderVDC saved in the variable $providervdc. Also I have the distinct identifier for the customer in the variable $orgname.

I found the needed method to get storage profiles again in the sub-object ExtensionData. It is called GetAvailableStorageProfiles() and gives me all storage profiles which are not already been added to the ProviderDVC. I simply had to filter them with the Where-Object commandlet for the distinct identifier.

# get all storageprofiles which could be added to the provider VDC
$newstorageprofiles = $providervdc.ExtensionData.GetAvailableStorageProfiles().vmwstorageprofile | Where-Object -FilterScript { $_.Name -like "*$orgname*" }

Now since I have the needed storage profile objects, I want to add them to the ProviderVDC. As explained at the beginning, the proper method (CreateStorageProfile()) need an “change” object which defines the needed changes.

As the Get-Member commandlet shows, the CreateStorageProfile() method wants an updateProviderVdcStorageProfilesParams object.

Get-Member -InputObject ($orgvdc.ExtensionData) -Type Method -Name CreateVdcStorageProfile
 
 
   TypeName: VMware.VimAutomation.Cloud.Views.AdminVdc
 
Name                    MemberType Definition
----                    ---------- ----------
CreateStorageProfile    Method     void CreateStorageProfile(VMware.VimAutomation.Cloud.Views.UpdateProviderVdcStorageProfilesParams updateProviderVdcStorageProfilesParams)

The updateProviderVdcStorageProfilesParams object has an AddStorageProfile Property. There I could simply set the name of the storage profile which I want to add. 

So I loop through all found storage profiles in the array $newstorageprofiles, create an updateProviderVdcStorageProfilesParams object, set the name of the storage profile to be added and execute the CreateStorageProfile() method.

# loop through all new found storageprofiles
foreach ( $newstorageprofile in $newstorageprofiles )
{

    # create new update object for the storage profile to be added. This is only a parameter set for the action to be taken later on the provider vdc
    $storageprofiletobeaddedparams = New-Object VMware.VimAutomation.Cloud.Views.UpdateProviderVdcStorageProfilesParams

    # set the name of the storage profile to be added
    $storageprofiletobeaddedparams.AddStorageProfile = $mystorageprofile.name

    # execute the parameter set and add the storage profile
    $providervdc.ExtensionData.CreateStorageProfile($storageprofiletobeaddedparams)

}

Now the new storage profiles are added to the ProviderVDC. Next step is to add them to the OrgVDC.

Again I use the distinct identifier for the customer to filter for the right storage profiles. The list of storage profiles which could be added to the OrgVDC I could get from the StorageProfiles property of the ProviderVDC object.

# get all storage profiles which are available in the provider vdc and which matches the org name
$orgstorageprofiles = $providervdc.StorageProfiles | Where-Object -FilterScript { $_.Name -like "*$orgname*" }

In the next step I simply wanted to add these storage profiles to the OrgVDC but soon realized that I can’t do this. The reason here is that at this point (adding storage profiles to a OrgVDC), vCloud Director expects some more informations as just the storage profile. vCloud Director needs also the storage limit in MB and if this storage profile should be used as new default in this OrgVDC. I found this while I searched the OrgVDC Object for a method to add storage profiles. The CreateVDCStorageProfile method expects a UpdateVdcStorageProfiles object.

Get-Member -InputObject $orgvdc.ExtensionData -Type Method -Name CreateVDCStorageProfile
 
 
   TypeName: VMware.VimAutomation.Cloud.Views.AdminVdc
 
Name                    MemberType Definition
----                    ---------- ----------
CreateVdcStorageProfile Method     void CreateVdcStorageProfile(VMware.VimAutomation.Cloud.Views.UpdateVdcStorageProfiles updateVdcStorageProfiles)

But the UpdateVdcStorageProfiles objects AddStorageProfile property does not accept simply the name of the storage profile to be added. (As seen when adding storage profiles to the ProviderVDC.) Instead it needs another object of type VdcStorageProfileParams.

$test = New-Object VMware.VimAutomation.Cloud.Views.UpdateVdcStorageProfiles
Get-Member -InputObject $test
 
 
   TypeName: VMware.VimAutomation.Cloud.Views.UpdateVdcStorageProfiles
 
Name                 MemberType Definition
----                 ---------- ----------
Equals               Method     bool Equals(System.Object obj)
GetHashCode          Method     int GetHashCode()
GetType              Method     type GetType()
ToString             Method     string ToString()
AddStorageProfile    Property   VMware.VimAutomation.Cloud.Views.VdcStorageProfileParams[] AddStorageProfile {get;set;}
AnyAttr              Property   VMware.VimAutomation.Cloud.Views.XmlAttributeCollection AnyAttr {get;set;}
Description          Property   string Description {get;set;}
Name                 Property   string Name {get;set;}
RemoveStorageProfile Property   VMware.VimAutomation.Cloud.Views.Reference[] RemoveStorageProfile {get;set;}
VCloudExtension      Property   VMware.VimAutomation.Cloud.Views.VCloudExtension[] VCloudExtension {get;set;}

The VdcStorageProfileParams object finally contains a reference to the storage profile to be added. But additionally some more properties have to be set. (Like limit, units, …)

$test2 = New-Object VMware.VimAutomation.Cloud.Views.VdcStorageProfileParams
Get-Member -InputObject $test2
 
 
   TypeName: VMware.VimAutomation.Cloud.Views.VdcStorageProfileParams
 
Name                      MemberType Definition
----                      ---------- ----------
Equals                    Method     bool Equals(System.Object obj)
GetHashCode               Method     int GetHashCode()
GetType                   Method     type GetType()
ToString                  Method     string ToString()
AnyAttr                   Property   VMware.VimAutomation.Cloud.Views.XmlAttributeCollection AnyAttr {get;set;}
Default                   Property   bool Default {get;set;}
Enabled                   Property   System.Nullable[bool] Enabled {get;set;}
IopsSettings              Property   VMware.VimAutomation.Cloud.Views.VdcStorageProfileIopsSettings IopsSettings {get;set;}
Limit                     Property   long Limit {get;set;}
ProviderVdcStorageProfile Property   VMware.VimAutomation.Cloud.Views.Reference ProviderVdcStorageProfile {get;set;}
Units                     Property   string Units {get;set;}
VCloudExtension           Property   VMware.VimAutomation.Cloud.Views.VCloudExtension[] VCloudExtension {get;set;}

OK, now let’s glue this together:

  • The VdcStorageProfileParams object contains a reference to the storage profile to be added and the limits to be used by the OrgVDC.
  • The correctly set VdcStorageProfileParams object has to be added to the UpdateVdcStoragePolicies object. (This is our “change” object where we define what we want.)
  • Finally I can pass the UpdateVdcStoragePolicies object to the CreateVdcStorageProfile() method of the OrgVDC object to apply the change.
foreach ( $orgstorageprofile in $orgstorageprofiles )
{

    # create new update object for the storage profile to be added
    $storageprofileupdateobject = New-Object VMware.VimAutomation.Cloud.Views.UpdateVdcStorageProfiles

    # create new storageprofile parameter set
    $storageprofileparam = New-Object VMware.VimAutomation.Cloud.Views.VdcStorageProfileParams

    $storageprofileparam.ProviderVdcStorageProfile = $orgstorageprofile.Href
    $storageprofileparam.Limit = $maxgbperstorageprofile * 1024
    $storageprofileparam.Units = "MB"
    $storageprofileparam.Default = $true

    $storageprofileupdateobject.AddStorageProfile = $storageprofileparam

    # execute the parameter set and add the storage profile
    $orgvdc.ExtensionData.CreateVdcStorageProfile($storageprofileupdateobject)
    
}

After the customer specific storage policies are added to the OrgVDC, I want to remove the default storage policies which have been added when creating the OrgVDC. Again I use the distinct identifier as filter to identify non-customer storage policies which had to be removed.

# get storage profiles to be removed
$storageprofiletoberemoveds = $orgvdc.ExtensionData.VdcStorageProfiles.VdcStorageProfile | Where-Object -FilterScript { $_.Name -notlike "*$orgname*" }

I learned the hard way that I could not remove storage profiles which are still enabled. So I had to disable them.

This could simply be achieved by setting the Enabled property to disable.

Similar to adding storage profiles to the ProviderVDC I had to create a “change” object with a reference to the storage profile to be deleted and pass this “change” object to the CreateVdcStorageProfile() method of the OrgVDC.

# loop through all found unnecessary storage profiles
foreach ( $storageprofiletoberemoved in $storageprofiletoberemoveds )
{

    # get the real object
    $storageprofiletoberemovedciview = $storageprofiletoberemoved.GetCIView()

    # disable the storage profile for this orgVDC
    $storageprofiletoberemovedciview.Enabled = $false

    # save changes
    $storageprofiletoberemovedciview.UpdateServerData()

    # create a update objekt for changes on storage profiles in orgVDC
    $storageprofileupdateobject = New-Object VMware.VimAutomation.Cloud.Views.UpdateVdcStorageProfiles

    # add reference to the storage profile to be removed
    $storageprofileupdateobject.RemoveStorageProfile = $storageprofiletoberemoved.Href

    # execute the storage profile update on the orgVDC
    $orgvdc.ExtensionData.CreateVdcStorageProfile($storageprofileupdateobject)

}

Next article in this series:

create an edge gateway

Leave a Reply

Your email address will not be published. Required fields are marked *

thirty six ÷ = twelve