This post was inspired by Ryan Kelly's recent post of a similar title in which he revealed how to change the “All Services” icon in the vRA 7.2 Catalog tab. Shortly after seeing that, I noticed that Ricky El-Qasem had also posted on the subject and created a small utility to accomplish the same task.
Great posts both of them. But I wanted to take a slightly different route and accomplish the same task in vRO which, as I'm sure you know, comes bundled with vRA. I must admit that I'm not totally satisfied with the result, maybe about 95%, but I'll explain why later.
Selecting a source image
For my initial testing, I thought I'd use the image on Ryan's post as it clearly worked for him. However, the image in his post is JPEG formatted and contains a border. That would clearly look a bit naff so I converted it to a PNG file, removed the border and the white background.
For guidance, I'd recommend a PNG file for these icons so that if they're not square the image background can set to be transparent, allowing the theme from vRA to show through. It just looks better.
As vRO allows images to be imported and stored within it, I thought I would try this approach. I have previously used such Resource Elements to attach images to HTML emails sent by vRO (as well as to store templates for text / emails, JSON objects and XML).
From that point, it should simply have been a case of converting the image to Base64 text within vRO and executing a REST update to vRA to replace the image. However, the methods available for extracting data from a Resource Element convert the image to a string, which munges it a bit. The resulting Base64 string is therefore corrupt and you end up with a broken image displaying in vRA:
I tried various ways to get around the issue but so far I haven't been able to, hence my minor dissatisfaction. What this means is that like the method that Ryan outlined, you still have to convert the image to Base64 outside of vRO. To finish off the workflow that I wanted to create, I did just that using an online tool and stored the Base64 string in a different resource element in vRO.
In the RAW output for the image shown, only the actual Base64 text is required and can be placed in to a text file and added to vRO:
This changed the process in the workflow slightly. In some ways it simplified it. Let's look at that now…
Looks fairly simple, doesn't it? Actually it is. No messing around with tokens!
// Get the default tenant host var host = vCACCAFEHostManager.getDefaultHostForTenant("vsphere.local", true); // Create a client connection to the icon service var client = host.createCatalogClient().getCatalogIconService(); // Create organization object var org = new vCACCAFECatalogOrganizationReference(); org.setTenantRef(host.tenant); // Construct a new vCACCAFEIcon object var iconObj = new vCACCAFEIcon(); iconObj.setId("cafe_default_icon_genericAllServices"); iconObj.setContentType(iconType); iconObj.setFileName("AllServices"); iconObj.setImage(iconBase64); iconObj.setOrganization(org); // Update the icon var result = client.createOrUpdateIcon(iconObj);
Line 2 – This returns the vCACCAFE:VCACHost connection for the default tenant in vRA (vsphere.local)
Line 4 – Creates a REST connection to the vRA Catalog Icon Service
Lines 7 & 8 – Creates a reference to the default tenant organisation in vRA
Lines 11 to 16 – Constructs a new icon object using the Base64 image data as well as the ID of the image we're replacing
Line 19 – Execute!
In the workflow, I've added three inputs:
- Select a resource element where the base64 image data is stored (using this overrides the field below).
- Paste in the base64 image data yourself.
- Set the MIME type of the image (i.e. PNG or JPG)
Running it against Ryan's icon and the Union flag image from above, I got the change applied across all tenants in vRA as expected:
Want the workflow to try this yourself? I've popped it on to GitHub: