Differences between VMware Aria Automation Orchestrator Forms and VMware Aria Automation Service Broker Forms

Starting with vRealize Automation 8.2, Service Broker is capable of displaying input forms designed in vRealize Orchestrator with the custom forms display engine. However, there are some differences in the forms display engines.

Orchestrator and Service Broker forms

Amongst the differences, the following features supported in vRealize Orchestrator are not yet supported in Service Broker:

  • The inputs presentations developed with the vRealize Orchestrator Legacy Client used in vRealize Orchestrator 7.6 and earlier, are not compatible. vRealize Orchestrator uses a built-in legacy input presentation conversion that is not available from Service Broker yet.
  • The inputs presentation in vRealize Orchestrator has access to all the workflow elements in the workflow. The custom forms have access to the elements exposed to vRealize Automation Service Broker through the VRO-Gateway service, which is a subset of what is available on vRealize Orchestrator.
    • Custom forms can bind workflow inputs to action parameters used to set values in other inputs.
    • Custom forms cannot bind workflows variables to action parameters used to set values in other inputs.

It is possible to work around vRealize Automation not having access to workflow variables by one of the following options :

  • Using a custom action returning the variable content.
  • Binding to an input parameter set to not visible instead of a variable.
  • Enabling custom forms and using constants.

The widgets available in vRealize Orchestrator and in vRealize Automation vary for certain types. The following table describes what is supported.

vRAvRO
Input Data TypePossible Form Display TypesAction return type for Default ValueAction return type for Value OptionsPossible Form Display TypesAction return type for Default ValueAction return type for Value Options
StringText, TextField, Text AreaDropdown, Radio GroupStringArray of StringPropertiesArray of Properties (value, label)Text, TextFIeld, Text AreaDropdown, Radio GroupStringArray of String
Array of StringArray Input (vRA 8.2), Dual List, Multi SelectArray of StringPropertiesArray of PropertiesArray of StringDatagrid, Multi Value PickerArray of StringPropertiesArray of PropertiesArray of String
IntegerIntegerNumberArray of NumberNot supportedNot supportedNot supported
Array of IntegerArray Input (vRA 8.2), Datagrid (vRA 8.1)Array of NumberArray of NumberNot supportedNot supportedNot supported
NumberDecimalNumberArray of NumberDecimalNumberArray of Number
Array/NumberArray Input (vRA 8.2), Datagrid (vRA 8.1)Array of NumberArray of NumberDatagridArray of NumberArray of Number
BooleanCheckboxBooleanNot supportedCheckboxBoolean
DateDate TimeDateArray of DateDate TimeDateArray of Date
Array of DateArray Input (vRA 8.2), Datagrid (vRA 8.1)Array of DateArray of DateDatagridArray of DateArray of Date
Composite/ComplexDatagrid, Object Field (vRA 8.3)Composite, Properties, Array/Composite, Array/PropertiesArray of CompositeDatagridComposite(columns…)Array/PropertiesArray of Composite
Array of CompositeDatagrid, Multi Value PickerComposite, Properties, Array/Composite, Array/PropertiesArray of CompositeDatagrid, Multi Value PickerArray/Composite(columns…)Array/PropertiesArray of Composite
Reference / vRO SDK Object typeValue PickerSDK ObjectArray of SDK Object (vRA 8.2)Value PickerSDK ObjectArray of SDK Object
Array of ReferenceMulti Value Picker (vRA 8.3)Array of SDK ObjectArray of SDK Object (vRA 8.3)DatagridArray of SDK ObjectArray of SDK Object
Secure StringPasswordStringNot supportedPasswordStringNot supported
FileNot supportedNot supportedNot supportedFile UploadNot supportedNot supported

For use cases where the widget specified in vRealize Orchestrator is not available from Service Broker, a compatible widget is used.

Because the data being passed to and from the widget might expect different types, formats, and values in the case they are unset, the best practice to develop workflows targeting Service Broker is to:

  1. Develop the vRealize Orchestrator workflow. This can include both the initial development of the workflow or changes of inputs.
  2. Version the workflow manually.
  3. In Cloud Assembly, navigate to Infrastructure > Connections > Integrations and select your vRealize Orchestrator integration.
  4. Start the data collection for the vRealize Orchestrator integration. This step, along with versioning up your workflow, ensure that the VRO-Gateway service used by vRealize Automation has the latest version of the workflow.
  5. Import content into Service Broker. This step generates a new default custom form.
  6. In addition to the input forms designed in vRealize Orchestrator, you can, if needed, develop workflow input forms with the custom forms editor.
  7. If these forms call actions, develop or run these from the vRealize Orchestrator workflow editor.
  8. Test the inputs presentation in Service Broker.
  9. Repeat from step 5 as many times as needed.
  10. Repeat from step 1, in case workflows inputs or forms need to be changed.

Either distribute and maintain the custom forms or alternatively, design vRealize Orchestrator inputs by using the same options or actions as in the custom forms (the above step 1), and then repeat the steps 2 to 8 to validate that the process works.

Using this last option means that:

  • Running the workflow from vRealize Orchestrator can lead to the input presentation not working as expected when started in vRealize Orchestrator.
  • For some cases, you must modify the return type of the actions used for default value or value options so these values can be set from the vRealize Orchestrator workflow editor and, when the workflow is saved, revert the action return types.

Designing the form in the workflow has the following advantages:

  • Form is packaged and delivered as part of the workflow included in a package.
  • Form can be tested in vRealize Orchestrator as long as the compatible widgets are applied.
  • The form can optionally be versioned and synchronized to a Git repository with the workflow.

Designing the custom forms separately has the following advantages:

  • Being able to customize the form without changing the workflow.
  • Being able to import and export the form as a file and reusing it for different workflows.

For example, a common use case is to have a string based drop-down menu.

Returning a Properties type can be used in both the vRealize Orchestrator input form presentation and vRealize Automation custom forms presentation. With the Property type you can display a list of values in the drop-down menu. After being select by the user, these values pass an ID to the parameter (to the workflow and the other input fields that would bind to this parameter). This is very practical to list objects when there is no dedicated plug-in for them as this avoids you having to select object names and having to find object IDs by name.

Returning an array of Properties types has the same goal as returning Properties but does give control on the ordering of the element. It is done by setting for each property in the array the label and value keys. For example, it is possible to sort ascending or descending properties by label or by keys within the action.

All the workflows included in the “drop down” folder of the sample package include drop down menus created with actions that have array of Properties set as the return type.

Find Object Types in vRealize Orchestrator

Find Object Types in vRealize Orchestrator [CB10100]

Sometimes, we want to know exactly what type of vRO object we are working on. It could be something that is returning from an action of type Any or a method returning various types of objects or simply about switch cases. In this quick post, we will see what are the options that vRO provides and where to use them.

  1. typeof
    1. Code Examples
    2. Using new operator
    3. use of Parenthesis
  2. System.getObjectType()
    1. Code Examples
  3. System.getObjectClassName()
    1. Code Examples
  4. instanceof
    1. Syntax
    2. Code Examples

typeof

The typeof operator returns a string indicating the type of the operand’s value where the operand is an object or of primitive type.

TypeResult
Undefined"undefined"
Null"object" (reason)
Boolean"boolean"
Number"number"
String"string"
Function"function"
Array"object"
Date"object"
vRO Object types"object"
vRO Object types with new operator"function"

Code Examples

var var1 = new VcCustomizationSpec(); 
System.debug(typeof var1); //function
var var2 = new Object();
System.debug(typeof var2); //object
var var3 = "a";
System.debug(typeof var3); //string
var var4 = 2;
System.debug(typeof var4); //number
var var4 = new Array(1, 2, 3);
System.debug(typeof var4); //object
System.debug(typeof []); //object
System.debug(typeof function () {}); //function
System.debug(typeof /regex/); //object
System.debug(typeof new Date()); //object
System.debug(typeof null); //object
System.debug(typeof undefinedVarible); //undefined

Using new operator

In this example, typeof operator is showing different results when used with new operator for class VC:CustomizationSpecManager. That’s because the new operator is used for creating a user-defined object type instance of one of the built-in object types that has a constructor function. So basically it calls the constructor function of that object type, hence typeof prints function. However, something to note here is that when new operator is used with primitive object type Number, typeof recognizes that as an object.

var num1 = 2;
System.debug(typeof num1); //number

var num2 = Number("123");;
System.debug(typeof (1 + num2)); //number

var num3 = new Number("123");;
System.debug(typeof (num3)); //object

var num4 = new Number("123");;
System.debug(typeof (1 + num4)); //number

use of Parenthesis

// Parentheses can be used for determining the data type of expressions.
const someData = 99;
typeof someData + "cloudblogger"; // "number cloudblogger"
typeof (someData + " cloudblogger"); // "string"

System.getObjectType()

The System.getObjectType() method returns the VS-O ‘type’ for the given operand. This method is more advanced than typeof and is able to detect more complex yet intrinsic object types like Date, Array etc. But, it still cannot figure out the plugin object types like VC:SDKConnection, etc.

TypeResult
Array"Array"
Number"number"
String"string"
vRO Plugin Object Types (with or without new)"null"
Date"Date"
Composite Types"Properties"
SecureString"string"
undefined VariableReference Error

Code Examples


var var1 = new VcCustomizationSpec(); 
System.debug(System.getObjectType(var1)); //null

var var2 = new Object();
System.debug(System.getObjectType(var2)); //Properties

var var3 = "a";
System.debug(System.getObjectType(var3)); //string

var var4 = 2;
System.debug(System.getObjectType(var4)); //number

var var4 = new Array(1, 2, 3);
System.debug(System.getObjectType(var4)); //Array

System.debug(System.getObjectType([])); //Array

System.debug(System.getObjectType(function () {})); //null

System.debug(System.getObjectType(new Date())); //Date

System.debug(System.getObjectType(undefinedVarible)); //FAIL ReferenceError: "undefinedVarible" is not defined.

System.getObjectClassName()

The System.getObjectClassName() method returns the class name of any vRO scripting object that typeof(obj) returns “object”. This works the best with complex vRO object types and surpasses System.getObjectType() in terms of its capability to identify object types.

TypeResult
Array"Array"
Number"Number"
String"String"
vRO Plugin Object Types (eg: VC:SdkConnection)Class Name (eg: VcSdkConnection)
Date"Date"
Composite Types"Properties"
SecureString"String"
undefined VariableReference Error
null objectsError: Cannot get class name from null object

Code Examples

System.debug(System.getObjectClassName(input));  //String

var var1 = new VcCustomizationSpec(); 
System.debug(System.getObjectClassName(var1)); //VcCustomizationSpec

var var2 = new Object();
System.debug(System.getObjectClassName(var2)); //Object

var var3 = "a";
System.debug(System.getObjectClassName(var3)); //String

var var4 = 2;
System.debug(System.getObjectClassName(var4)); //Double

var var4 = new Array(1, 2, 3);
System.debug(System.getObjectClassName(var4)); //Array

System.debug(System.getObjectClassName([])); //Array

System.debug(System.getObjectClassName(function () {})); //Function

System.debug(System.getObjectClassName(new Date())); //Date

instanceof

The instanceof operator tests to see if the prototype property of a constructor appears anywhere in the prototype chain of an object. The return value is a boolean value. This means that instanceof checks if RHS matches the constructor of a class. That’s why it doesn’t work with primitive types like number, string, etc. However, works with variety of complex types available in vRO.

Syntax

object instanceof constructor

Code Examples

var var1 = new VcCustomizationSpec(); 
System.debug(var1 instanceof VcCustomizationSpec); //true

var var1 = new VcCustomizationSpec(); 
System.debug(var1 instanceof Object); //true

var var2 = new Object();
System.debug(var2 instanceof Object); //true

var var3 = "a";
System.debug(var3 instanceof String); //false

var var3 = new String("a");
System.debug(var3 instanceof String); //true

var var3 = "a";
System.debug(var3 instanceof String); //false

var var4 = 2;
System.debug(var4 instanceof Number); //false

var var4 = new Array(1, 2, 3);
System.debug(var4 instanceof Array); //true

System.debug([] instanceof Array); //true

System.debug(function () {} instanceof Function); //true

System.debug(new Date() instanceof Date); //true

System.debug({} instanceof Object); //true

That’s all in this port. I hope you will have a better understanding on how to check vRO Object types. Let me know in the comment if you have any doubt or question. Feel free to share this article. Thank you.

Advanced JavaScript Snippets in vRO [CB10099]

  1. Introduction
  2. Snippets
    1. External Modules
    2. First-class Functions
    3. Ways to add properties to Objects
    4. Custom Class
    5. Private variable
    6. Label
    7. with keyword
    8. Function binding
  3. Recommended Reading

Introduction

vRO JS code is generally plain and basic just enough to get the job done. But I was wondering, how to fancy it? So, I picked some slightly modern JS code (ES5.1+) and tried running it on my vRO 8.3. I found some interesting things which I would like to share in this article.

Snippets

Here are some JS concepts that you can use writing vRO JavaScript code to make it more compelling and beautiful.

External Modules

To utilize modern features, you can use modules like lodash.js for features such as map or filter etc. Other popular module is moment.js for complex Date and Time handling in vRO.

var _ = System.getModule("fr.numaneo.library").lodashLibrary();
var myarr = [1,2,3];
var myarr2 = [4,5,6];
var concatarr = _.concat(myarr, myarr2);
System.log(concatarr); // [1,2,3,4,5,6];

Find more information on how to leverage Lodash.js in vRO here.

First-class Functions

First-class functions are functions that are treated like any other variable. For example, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable.

// we send in the function as an argument to be
// executed from inside the calling function
function performOperation(a, b, cb) {
    var c = a + b;
    cb(c);
}

performOperation(2, 3, function(result) {
    // prints out 5
    System.log("The result of the operation is " + result);
})

Ways to add properties to Objects

There are 4 ways to add a property to an object in vRO.

// supported since ES3
// the dot notation
instance.key = "A key's value";

// the square brackets notation
instance["key"] = "A key's value";

// supported since ES5
// setting a single property using Object.defineProperty
Object.defineProperty(instance, "key", {
    value: "A key's value",
    writable: true,
    enumerable: true,
    configurable: true
});

// setting multiple properties using Object.defineProperties
Object.defineProperties(instance, {
    "firstKey": {
        value: "First key's value",
        writable: true
    },
    "secondKey": {
        value: "Second key's value",
        writable: false
    }
});

Custom Class

You can create your own custom classes in vRO using the function keyword and extend that function’s prototype.

// we define a constructor for Person objects
function Person(name, age, isDeveloper) {
    this.name = name;
    this.age = age;
    this.isDeveloper = isDeveloper || false;
}

// we extend the function's prototype
Person.prototype.writesCode = function() {
    System.log(this.isDeveloper? "This person does write code" : "This person does not write code");
}

// creates a Person instance with properties name: Bob, age: 38, isDeveloper: true and a method writesCode
var person1 = new Person("Bob", 38, true);
// creates a Person instance with properties name: Alice, age: 32, isDeveloper: false and a method writesCode
var person2 = new Person("Alice", 32);

// prints out: This person does write code
person1.writesCode();
// prints out: this person does not write code
person2.writesCode();

Both instances of the Person constructor can access a shared instance of the writesCode() method.

Private variable

A private variable is only visible to the current class. It is not accessible in the global scope or to any of its subclasses. For example, we can do this in Java (and most other programming languages) by using the private keyword when we declare a variable

// we  used an immediately invoked function expression
// to create a private variable, counter
var counterIncrementer = (function() {
    var counter = 0;

    return function() {
        return ++counter;
    };
})();

// prints out 1
System.log(counterIncrementer());
// prints out 2
System.log(counterIncrementer());
// prints out 3
System.log(counterIncrementer());

Label

Labels can be used with break or continue statements. It is prefixing a statement with an identifier which you can refer to.

var str = '';

loop1:
for (var i = 0; i < 5; i++) {
  if (i === 1) {
    continue loop1;
  }
  str = str + i;
}

System.log(str);
// expected output: "0234"

with keyword

The with statement extends the scope chain for a statement. Check the example for better understanding.

var box = {"dimensions": {"width": 2, "height": 3, "length": 4}};
with(box.dimensions){
  var volume = width * height * length;
}
System.log(volume); //24

// vs

var box = {"dimensions": {"width": 2, "height": 3, "length": 4}};
var boxDimensions = box.dimensions;
var volume2 = boxDimensions.width * boxDimensions.height * boxDimensions.length;
System.log(volume2); //24

Function binding

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

const module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};

const unboundGetX = module.getX;
System.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined

const boundGetX = unboundGetX.bind(module);
System.log(boundGetX());
// expected output: 42

official-vmware-guides-for-vro-and-vra-8.x

Official VMware Guides for vRO and vRA 8.x

  1. Introduction
  2. Guides for vRA
    1. Architecture
    2. Cloud Assembly
    3. Code Stream
    4. Service Broker
    5. Transition Guide
    6. Migration
    7. Cloud Transition
    8. Integration with ServiceNow
    9. Load Balancing
  3. Guides for vRO
    1. Installation
    2. User Interface
    3. Developer’s Guide
    4. Migration
    5. Plug-in Development
    6. Plug-in Guide

Introduction

This blogpost is simply about giving a consolidated view on all the official guides that VMware provides for vRealize Automation and vRealize Orchestrator. These guides can help Automation Engineers & Developers, Solution Architects, vRealize Admins, etc and can be used as a reference for developing vRO Code, vRA Templates and various other tasks. You can download them from the provided links for offline access.

Guides for vRA

Architecture

Cloud Assembly

Code Stream

Service Broker

Transition Guide

Migration

Cloud Transition

Download: https://docs.vmware.com/en/vRealize-Automation/services/vrealize-automation-cloud-transition-guide.pdf

Integration with ServiceNow

Load Balancing

Guides for vRO

Installation

User Interface

Download: https://docs.vmware.com/en/vRealize-Orchestrator/8.8/vrealize-orchestrator-88-using-client-guide.pdf

Developer’s Guide

Migration

Plug-in Development

Plug-in Guide

I will try to update this list over time. Hope this list of guides will help you in understanding things a little better. Feel free to share.

Advertisements

Free vRealize Automation 8.3 Enterprise Course by VMware

Disclaimer Turned out that this course is not freely available for everyone. I would suggest you give it a try and see if you’re lucky enough.

If you are looking for a course on vRealize Automation (vRA) and vRealize Orchestrator (vRO) which is officially developed by VMware, is enterprise-level, not just the basic one and most importantly FREE, then you should go for this course. It has 41 lessons, more than 70,000 views and is a ELS (Enterprise) course and talks on vRA architecture, installation, Cloud templates, integration with NSX-T, Kubernetes, Public Clouds, SaltStack, vRO Workflows and extensibility and a lot more. I personally went through this course after I completed the Udemy’s Getting started with VMware vRealize Automation 8.1 and while Udemy’s push start your journey in vRA 8.x, this VMware course will take it to another level. Recommended for someone who is in VMware Automation, coming from vRA 7.x, Looking for migrating from 7.x to 8.x, deployment of vRA etc. In this post, I have shared some basic steps on how to get to that course and get yourself started.

Bonus Tip

VMware will accept this course as prerequisite for Cloud Management and Automation 2022 (VCP-CMA 2022) certification.

How to enroll?

  • Scroll down and search for vrealize automation.
  • Open the course, enroll yourself and get started.
  • Once you start the course, Bharath N will take over as your course instructor.

Course Content

Let’s see what you will find in the course content.

Feel free to share this article to your team members and connections.

vRO JavaScript Style Guide [CB10096]

  1. Introduction
  2. JavaScript Language Rules
    1. var
    2. Constants
    3. Semicolons
    4. Nested functions
    5. Function Declarations Within Blocks
    6. Exceptions
    7. Custom exceptions
    8. Standards features
    9. Wrapper objects for primitive types
    10. delete
    11. JSON.parse()
    12. with() {}
    13. this
    14. for-in loop
    15. Multiline string literals
    16. Array and Object literals
    17. Modifying prototypes of built-in objects
  3. JavaScript Style Rules
    1. Naming
    2. Deferred initialization
    3. Code formatting
    4. Parentheses
    5. Strings
    6. Comments
    7. Tips and Tricks
  4. vRO Element Naming Rules
    1. Actions
    2. Workflows
    3. Action Modules
    4. Resource Elements and Configuration Elements
    5. Attributes inside Configuration Elements

Introduction

If you are new to vRealize Orchestrator and want to look for some code style references, this post can help you with some basic guidelines to write the perfect JavaScript code in your vRO Workflows and Actions. These are industry standards are preferred by almost every industry. Keep in mind that this guide won’t help you with writing your first vRO code, instead can be used as style reference while writing your vRO JavaScript code. In short, helps you to achieve 7 things:

  1. Code that’s easier to read
  2. Provide clear guidelines when writing code
  3. Predictable variable and function names
  4. Improve team’s efficiency to collaborate
  5. Saves time and makes communication between teams more efficient
  6. Reduces redundant work
  7. Enables each team member to share the same clear messaging with potential customers

vRealize Orchestrator uses JavaScript 1.7 as its classic language of choice for all the automation tasks that gets executed inside Mozilla Rhino 1.7R4 Engine along with some limitations listed here. This style guide is a list of dos and don’ts for JavaScript programs that you write inside your vRO. Let’s have a look.

JavaScript Language Rules

var

Always declare variables with var, unless it’s a const.

Constants

  • Use NAMES_LIKE_THIS for constant values, that start with const keyword.

Semicolons

Always use semicolons.

Why?

JavaScript requires statements to end with a semicolon, except when it thinks it can safely infer their existence. In each of these examples, a function declaration or object or array literal is used inside a statement. The closing brackets are not enough to signal the end of the statement. JavaScript never ends a statement if the next token is an infix or bracket operator.

This has really surprised people, so make sure your assignments end with semicolons.

Clarification: Semicolons and functions

Semicolons should be included at the end of function expressions, but not at the end of function declarations. The distinction is best illustrated with an example:

var foo = function() {
  return true;
};  // semicolon here.

function foo() {
  return true;
}  // no semicolon here.

Nested functions

Yes

Nested functions can be very useful, for example in the creation of continuations and for the task of hiding helper functions. Feel free to use them.

Function Declarations Within Blocks

No

Do not do this:

if (x) {
  function foo() {}
}

ECMAScript only allows for Function Declarations in the root statement list of a script or function. Instead use a variable initialized with a Function Expression to define a function within a block:

if (x) {
  var foo = function() {};
}

Exceptions

Yes

You basically can’t avoid exceptions. Go for it.

Custom exceptions

Yes

Sometimes, It becomes really hard to troubleshoot inside vRealize Orchestrator. But, custom exceptions can certainly help you there. Feel free to use custom exceptions when appropriate and throw them using System.error() for soft errors or throw "" for hard errors.

Standards features

Always preferred over non-standards features

For maximum portability and compatibility, always prefer standards features over non-standards features (e.g., string.charAt(3) over string[3].

Wrapper objects for primitive types

No

There’s no reason to use wrapper objects for primitive types, plus they’re dangerous:

var x = new Boolean(false);
if (x) {
  alert('hi');  // Shows 'hi'.
}

Don’t do it!

However type casting is fine.

var x = Boolean(0);
if (x) {
  alert('hi');  // This will never be alerted.
}
typeof Boolean(0) == 'boolean';
typeof new Boolean(0) == 'object';

This is very useful for casting things to numberstring and boolean.

delete

Prefer this.foo = null.

var dispose = function() {
  this.property_ = null;
};

Instead of:

var dispose = function() {
  delete this.property_;
};

Changing the number of properties on an object is much slower than reassigning the values. The delete keyword should be avoided except when it is necessary to remove a property from an object’s iterated list of keys, or to change the result of if (key in obj).

JSON.parse()

You can always use JSON and read the result using JSON.parse().

var userInfo = JSON.parse(feed);
var email = userInfo['email'];

With JSON.parse, invalid JSON will cause an exception to be thrown.

with() {}

No

Using with clouds the semantics of your program. Because the object of the with can have properties that collide with local variables, it can drastically change the meaning of your program. For example, what does this do?

with (foo) {
  var x = 3;
  return x;
}

Answer: anything. The local variable x could be clobbered by a property of foo and perhaps it even has a setter, in which case assigning 3 could cause lots of other code to execute. Don’t use with.

this

Only in object constructors, methods, and in setting up closures

The semantics of this can be tricky. At times it refers to the global object (in most places), the scope of the caller (in eval), a newly created object (in a constructor), or some other object (if function was call()ed or apply()ed).

Because this is so easy to get wrong, limit its use to those places where it is required:

  • in constructors
  • in methods of objects (including in the creation of closures)

for-in loop

Only for iterating over keys in an object/map/hash

for-in loops are often incorrectly used to loop over the elements in an Array. This is however very error prone because it does not loop from 0 to length - 1 but over all the present keys in the object and its prototype chain. Here are a few cases where it fails:

function printArray(arr) {
  for (var key in arr) {
    print(arr[key]);
  }
}

printArray([0,1,2,3]);  // This works.

var a = new Array(10);
printArray(a);  // This is wrong.

a = [0,1,2,3];
a.buhu = 'wine';
printArray(a);  // This is wrong again.

a = new Array;
a[3] = 3;
printArray(a);  // This is wrong again.

Always use normal for loops when using arrays.

function printArray(arr) {
  var l = arr.length;
  for (var i = 0; i < l; i++) {
    print(arr[i]);
  }
}

Multiline string literals

No

Do not do this:

var myString = 'A rather long string of English text, an error message \
                actually that just keeps going and going -- an error \
                message to make the Energizer bunny blush (right through \
                those Schwarzenegger shades)! Where was I? Oh yes, \
                you\'ve got an error and all the extraneous whitespace is \
                just gravy.  Have a nice day.';

The whitespace at the beginning of each line can’t be safely stripped at compile time; whitespace after the slash will result in tricky errors.

Use string concatenation instead:

var myString = 'A rather long string of English text, an error message ' +
    'actually that just keeps going and going -- an error ' +
    'message to make the Energizer bunny blush (right through ' +
    'those Schwarzenegger shades)! Where was I? Oh yes, ' +
    'you\'ve got an error and all the extraneous whitespace is ' +
    'just gravy.  Have a nice day.';

Array and Object literals

Yes

Use Array and Object literals instead of Array and Object constructors.

Array constructors are error-prone due to their arguments.

// Length is 3.
var a1 = new Array(x1, x2, x3);

// Length is 2.
var a2 = new Array(x1, x2);

// If x1 is a number and it is a natural number the length will be x1.
// If x1 is a number but not a natural number this will throw an exception.
// Otherwise the array will have one element with x1 as its value.
var a3 = new Array(x1);

// Length is 0.
var a4 = new Array();

Because of this, if someone changes the code to pass 1 argument instead of 2 arguments, the array might not have the expected length.

To avoid these kinds of weird cases, always use the more readable array literal.

var a = [x1, x2, x3];
var a2 = [x1, x2];
var a3 = [x1];
var a4 = [];

Object constructors don’t have the same problems, but for readability and consistency object literals should be used.

var o = new Object();

var o2 = new Object();
o2.a = 0;
o2.b = 1;
o2.c = 2;
o2['strange key'] = 3;

Should be written as:

var o = {};

var o2 = {
  a: 0,
  b: 1,
  c: 2,
  'strange key': 3
};

Modifying prototypes of built-in objects

Modifying builtins like Object.prototype and Array.prototype are strictly forbidden in vRO. Doing so will result in an error.

JavaScript Style Rules

Naming

In general, use functionNamesLikeThisvariableNamesLikeThisEnumNamesLikeThisCONSTANT_VALUES_LIKE_THIS.

Method and function parameter

Optional function arguments start with opt_.

Getters and Setters

EcmaScript 5 getters and setters for properties are discouraged. However, if they are used, then getters must not change observable state.

/**
 * WRONG -- Do NOT do this.
 */
var foo = { get next() { return this.nextId++; } };

Accessor functions

Getters and setters methods for properties are not required. However, if they are used, then getters must be named getFoo() and setters must be named setFoo(value). (For boolean getters, isFoo() is also acceptable, and often sounds more natural.)

Deferred initialization

OK

It isn’t always possible to initialize variables at the point of declaration, so deferred initialization is fine.

Code formatting

Curly Braces

Because of implicit semicolon insertion, always start your curly braces on the same line as whatever they’re opening. For example:

if (something) {
  // ...
} else {
  // ...
}

Array and Object Initializers

Single-line array and object initializers are allowed when they fit on a line:

var arr = [1, 2, 3];  // No space after [ or before ].
var obj = {a: 1, b: 2, c: 3};  // No space after { or before }.

Multiline array initializers and object initializers are indented 2 spaces, with the braces on their own line, just like blocks.

Indenting wrapped lines

Except for array literals, object literals, and anonymous functions, all wrapped lines should be indented either left-aligned to a sibling expression above, or four spaces (not two spaces) deeper than a parent expression (where “sibling” and “parent” refer to parenthesis nesting level).

someWonderfulHtml = '' +
                    getEvenMoreHtml(someReallyInterestingValues, moreValues,
                                    evenMoreParams, 'a duck', true, 72,
                                    slightlyMoreMonkeys(0xfff)) +
                    '';

thisIsAVeryLongVariableName =
    hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine();

thisIsAVeryLongVariableName = siblingOne + siblingTwo + siblingThree +
    siblingFour + siblingFive + siblingSix + siblingSeven +
    moreSiblingExpressions + allAtTheSameIndentationLevel;

thisIsAVeryLongVariableName = operandOne + operandTwo + operandThree +
    operandFour + operandFive * (
        aNestedChildExpression + shouldBeIndentedMore);

someValue = this.foo(
    shortArg,
    'Some really long string arg - this is a pretty common case, actually.',
    shorty2,
    this.bar());

if (searchableCollection(allYourStuff).contains(theStuffYouWant) &&
    !ambientNotification.isActive() && (client.isAmbientSupported() ||
                                        client.alwaysTryAmbientAnyways())) {
  ambientNotification.activate();
}

Blank lines

Use newlines to group logically related pieces of code. For example:

doSomethingTo(x);
doSomethingElseTo(x);
andThen(x);

nowDoSomethingWith(y);

andNowWith(z);

Binary and Ternary Operators

Always put the operator on the preceding line. Otherwise, line breaks and indentation follow the same rules as in other Google style guides. This operator placement was initially agreed upon out of concerns about automatic semicolon insertion. In fact, semicolon insertion cannot happen before a binary operator, but new code should stick to this style for consistency.

var x = a ? b : c;  // All on one line if it will fit.

// Indentation +4 is OK.
var y = a ?
    longButSimpleOperandB : longButSimpleOperandC;

// Indenting to the line position of the first operand is also OK.
var z = a ?
        moreComplicatedB :
        moreComplicatedC;

This includes the dot operator.

var x = foo.bar().
    doSomething().
    doSomethingElse();

Parentheses

Only where required

Use sparingly and in general only where required by the syntax and semantics.

Never use parentheses for unary operators such as deletetypeof and void or after keywords such as returnthrow as well as others (casein or new).

Strings

For consistency single-quotes (‘) are preferred to double-quotes (“). This is helpful when creating strings that include HTML:

var msg = 'This is some message';

Comments

Use JSDoc if you want.

Tips and Tricks

JavaScript tidbits

True and False Boolean Expressions

The following are all false in boolean expressions:

  • null
  • undefined
  • '' the empty string
  • 0 the number

But be careful, because these are all true:

  • '0' the string
  • [] the empty array
  • {} the empty object

This means that instead of this:

while (x != null) {

you can write this shorter code (as long as you don’t expect x to be 0, or the empty string, or false):

while (x) {

And if you want to check a string to see if it is null or empty, you could do this:

if (y != null && y != '') {

But this is shorter and nicer:

if (y) {

Caution: There are many unintuitive things about boolean expressions. Here are some of them:

  • Boolean('0') == true
    '0' != true
  • 0 != null
    0 == []
    0 == false
  • Boolean(null) == false
    null != true
    null != false
  • Boolean(undefined) == false
    undefined != true
    undefined != false
  • Boolean([]) == true
    [] != true
    [] == false
  • Boolean({}) == true
    {} != true
    {} != false

Conditional (Ternary) Operator (?:)

Instead of this:

if (val) {
  return foo();
} else {
  return bar();
}

you can write this:

return val ? foo() : bar();

&& and ||

These binary boolean operators are short-circuited, and evaluate to the last evaluated term.

“||” has been called the ‘default’ operator, because instead of writing this:

function foo(opt_win) {
  var win;
  if (opt_win) {
    win = opt_win;
  } else {
    win = window;
  }
  // ...
}

you can write this:

function foo(opt_win) {
  var win = opt_win || window;
  // ...
}

“&&” is also useful for shortening code. For instance, instead of this:

if (node) {
  if (node.kids) {
    if (node.kids[index]) {
      foo(node.kids[index]);
    }
  }
}

you could do this:

if (node && node.kids && node.kids[index]) {
  foo(node.kids[index]);
}

or this:

var kid = node && node.kids && node.kids[index];
if (kid) {
  foo(kid);
}

vRO Element Naming Rules

Actions

should be named like actionNameLikeThis and must start with a verb like get, create, set, delete, fetch, put, call, and so forth. Then, describe what the action is doing.

Workflows

should be a short statement which briefly tells what the Workflow is doing.

Action Modules

naming should be similar to com.[company].library.[component].[interface].[parent group].[child group]

Where

[company] = company name as a single word

library – Optional

[component] = Examples are: NSX, vCAC, Infoblox, Activedirectory, Zerto.

[interface] – Optional – Examples are: REST, SOAP, PS. Omit this if you are using the vcenter or vcac plugins.

[parent group] – Optional – Parent group i.e. Edges, Entities, Networks, vm.

[child group] – Optional – A group containing collections of child actions that relate to the parent group.

Resource Elements and Configuration Elements

Resource element’s name is actually the filename at time of uploading. It should be clear enough.

Configuration Elements are used for various purposes like Password Containers (Credential store), Environment specific variables, location information, or can be a used as global variables get\set by various workflows. Hence, the name should define its purpose.

Attributes inside Configuration Elements

attribute’s name should have some suffix like DC_ or CONF_. when mapped with variable inside workflow, we should keep that variable’s name same as well. While using it in scripts, pass its value to another variable.

In this example, a attribute DC_EAST_LOCATION inside a Configuration element (named Location Variables) is mapped to a variable DC_EAST_LOCATION in a workflow and this variable is being used in a scriptable task.

//CORRECT WAY
var location = DC_EAST_LOCATION; //pass value to a local variable
System.log("Current location: " + location);

//WRONG WAY
System.log("Current location: " + DC_EAST_LOCATION);

Code Obfuscation in vRO [CB10095]

This will be a very quick post. While reading about code security, I came through a concept called “Security through obscurity” and when I dig in, I realized code obfuscation is great way to do it. But then, I thought how vRO handles obfuscated code. And so I tried and let me give you a quick demo on that.

What is Code Obfuscation?

Before going to vRO, let’s briefly understand what exactly code obfuscation is. Obfuscation is the act of creating code that is difficult for humans to understand. It may use needlessly roundabout expressions to compose statements. Programmers may deliberately obfuscate code to conceal its purpose or its logic or implicit values embedded in it, primarily, in order to prevent tampering, or even to create a challenge for someone reading the source code.

Example of an small obfuscated piece of code

Let’s try inside vRO

We have a vRO action which decodes vSphere license details using vRO Scripting APIs.

/**
* @version 0.0.0
* @description Decodes the 'Product Name' and 'Product Version' from a vSphere license string
*
* @param {VC:SdkConnection} vCenterConnection
* @param {string} licenseKey
*
* @outputType string
*
*/
//validate that we have a license key that is 5, 5 character strings delimited by a '-'
var licenseParts = licenseKey.split('-');
if (licenseParts.length != 5) {
throw("license key is not complete");
}
for (var part in licenseParts) {
if (licenseParts[part].length < 5) {
throw("license key is invalid. Section: '"+licenseParts[part]+"' of '"+licenseKey+"' is too short");
}
if (licenseParts[part].length > 5) {
throw("license key is invalid. Section: '"+licenseParts[part]+"' of '"+licenseKey+"' is too long");
}
}
var licenseInfo = vCenterConnection.licenseManager.decodeLicense(licenseKey);
System.log("License Name: "+licenseInfo.name);
var licenseProps = licenseInfo.properties;
for (var lp in licenseProps) {
if (licenseProps[lp].key === "ProductName") {
System.log("Product Name: "+licenseProps[lp].value);
} else if (licenseProps[lp].key === "ProductVersion") {
System.log("Product Version: "+licenseProps[lp].value);
}
}
/* Example Output
License Name: vSphere 7 Enterprise Plus
Product Name: VMware ESX Server
Product Version: 7.0
*/

It takes 2 inputs. Select vCenter and provide a licenseKey in this format XXXXQ-YYTYA-ZZ1G8-0N8K2-05D6J)

vRO Input form

Let’s run it. The output will be similar to

vRO log

Run Obfuscated code

To obfuscate my JavaScript code, I used this tool available at https://obfuscator.io/

Source: https://obfuscator.io/

After conversion, I copied the code.

Converted with https://obfuscator.io/

And it look like this

var _0x30dc97=_0x4adc;function _0x48f4(){var _0x282c41=['key','3166SRMjmj','70317gluhjb','\x27\x20is\x20too\x20short','Product\x20Version:\x20','length','decodeLicense','4140NJYHMY','log','94BxAcqD','license\x20key\x20is\x20not\x20complete','ProductVersion','properties','\x27\x20of\x20\x27','licenseManager','split','name','4670613YLePgL','license\x20key\x20is\x20invalid.\x20\x20Section:\x20\x27','6764730tJimsy','6487908mPAsSG','ProductName','value','License\x20Name:\x20','Product\x20Name:\x20','56MtIDBs','1323441OmRImv','4038660gdcllK','\x27\x20is\x20too\x20long'];_0x48f4=function(){return _0x282c41;};return _0x48f4();}(function(_0x38b91a,_0x218a87){var _0x202c0f=_0x4adc,_0x3b562e=_0x38b91a();while(!![]){try{var _0x3f0cce=parseInt(_0x202c0f(0x85))/0x1*(parseInt(_0x202c0f(0x70))/0x2)+-parseInt(_0x202c0f(0x78))/0x3+-parseInt(_0x202c0f(0x7b))/0x4+-parseInt(_0x202c0f(0x7a))/0x5+parseInt(_0x202c0f(0x82))/0x6+-parseInt(_0x202c0f(0x81))/0x7*(-parseInt(_0x202c0f(0x80))/0x8)+parseInt(_0x202c0f(0x86))/0x9*(parseInt(_0x202c0f(0x6e))/0xa);if(_0x3f0cce===_0x218a87)break;else _0x3b562e['push'](_0x3b562e['shift']());}catch(_0x2ca51c){_0x3b562e['push'](_0x3b562e['shift']());}}}(_0x48f4,0xcf10d));var licenseParts=licenseKey[_0x30dc97(0x76)]('-');if(licenseParts['length']!=0x5)throw _0x30dc97(0x71);for(var part in licenseParts){if(licenseParts[part]['length']<0x5)throw _0x30dc97(0x79)+licenseParts[part]+_0x30dc97(0x74)+licenseKey+_0x30dc97(0x87);if(licenseParts[part][_0x30dc97(0x89)]>0x5)throw _0x30dc97(0x79)+licenseParts[part]+_0x30dc97(0x74)+licenseKey+_0x30dc97(0x83);}var licenseInfo=vCenterConnection[_0x30dc97(0x75)][_0x30dc97(0x8a)](licenseKey);System[_0x30dc97(0x6f)](_0x30dc97(0x7e)+licenseInfo[_0x30dc97(0x77)]);function _0x4adc(_0x4d2f0a,_0x40aefd){var _0x48f4ef=_0x48f4();return _0x4adc=function(_0x4adcaf,_0x1f587e){_0x4adcaf=_0x4adcaf-0x6e;var _0x2861fc=_0x48f4ef[_0x4adcaf];return _0x2861fc;},_0x4adc(_0x4d2f0a,_0x40aefd);}var licenseProps=licenseInfo[_0x30dc97(0x73)];for(var lp in licenseProps){if(licenseProps[lp]['key']===_0x30dc97(0x7c))System['log'](_0x30dc97(0x7f)+licenseProps[lp][_0x30dc97(0x7d)]);else licenseProps[lp][_0x30dc97(0x84)]===_0x30dc97(0x72)&&System[_0x30dc97(0x6f)](_0x30dc97(0x88)+licenseProps[lp]['value']);}

This script is available at https://gist.github.com/imtrinity94/e172c126ee13f7c9804acd0bc886f5bf

And I ran it in vRO by just copy-pasting it to action with same input variables and it worked. I know that obfuscated code is also just the plain JavaScript but I still never tried it and wanted to get a feel of it inside vRO.

vRO Action with obfuscated code

That’s it in this post. Thanks for reading.

Valid JavaScript Variable names in vRO

  1. Introduction
  2. Reserved words
  3. Non-reserved words that act like reserved words
  4. Valid identifier names
  5. Examples inside vRO
  6. Can you use them in between scripts?
  7. JavaScript variable name validator

Introduction

Did you know var π = Math.PI; is syntactically valid JavaScript code in vRealize Orchestrator? If the answer is “No” then probably this article maybe of some interest to you.

Let’s see what all Unicode glyphs are allowed in as JavaScript variable names, or identifiers as the ECMAScript specification calls them. This is more of a fun activity but can give you some insight on selecting the best (or may I say worst LOL! – will talk about this later) variable name in your vRO scripts.

Reserved words

The ECMAScript 5.1 spec says:

An Identifier is an IdentifierName that is not a ReservedWord.

The spec describes four groups of reserved words: keywords, future reserved words, null literals and boolean literals.

Keywords are tokens that have special meaning in JavaScript:

break, case, catch, continue, debugger, default, delete, do, else, finally, for, function, if, in, instanceof, new, return, switch, this, throw, try, typeof, var, void, while, and with.

Future reserved words are tokens that may become keywords in a future revision of ECMAScript:  classconstenumexportextendsimport, and super. Some future reserved words only apply in strict mode: implementsinterfaceletpackageprivateprotectedpublicstatic, and yield.

The null literal is, simply, null.

There are two boolean literalstrue and false. None of the above are allowed as variable names.

Non-reserved words that act like reserved words

The NaNInfinity, and undefined properties of the global object are immutable or read-only properties in ES5.1. So even though var NaN = 42; in the global scope wouldn’t throw an error, it wouldn’t actually do anything. To avoid confusion, I’d suggest avoiding the use of these variable names.

// In the global scope:
var NaN = 42;
console.log(NaN); // NaN// 

…but elsewhere:
(function() {	
var NaN = 42;	
console.log(NaN); // 42
}());

In strict mode, eval and arguments are disallowed as variable names too. (They kind of act like keywords in that case.) The old ES3 spec defines some reserved words that aren’t reserved words in ES5 anymore: 

int, byte, char, goto, long, final, float, short, double, native, throws, boolean, abstract, volatile, transient, and synchronized. 

It’s probably a good idea to avoid these as well, for optimal backwards compatibility.

Valid identifier names

As mentioned before, the spec differentiates between identifier names and identifiers. Identifiers form a subset of identifier names, since identifiers have the extra restriction that no reserved words are allowed. For example, var is a valid identifier name, but it’s an invalid identifier.

So, what is allowed in an identifier name?

An identifier must start with $_, or any character in the Unicode categories “Uppercase letter (Lu)”“Lowercase letter (Ll)”“Titlecase letter (Lt)”“Modifier letter (Lm)”“Other letter (Lo)”, or “Letter number (Nl)”.

Unicode escape sequences are also permitted in an IdentifierName, where they contribute a single character. […] A UnicodeEscapeSequence cannot be used to put a character into an IdentifierName that would otherwise be illegal.

This means that you can use var \u0061 and var a interchangeably. Similarly, since var 1 is invalid, so is var \u0031.

Two IdentifierNames that are canonically equivalent according to the Unicode standard are not equal unless they are represented by the exact same sequence of code units.

So, ma\u00F1ana and man\u0303ana are two different variable names, even though they’re equivalent after Unicode normalization.

Examples inside vRO

The following are all examples of valid JavaScript variable names that will work in vRO

System.log(λ);

// How convenient!
var π = Math.PI;
System.log("Value of PI: "+π);

// Sometimes, you just have to use the Bad Parts of JavaScript:
var ಠ_ಠ = "Angry";
System.log(ಠ_ಠ);

// Code, Y U NO WORK?!
var ლ_ಠ益ಠ_ლ = 42;
System.log(ლ_ಠ益ಠ_ლ );

// Obfuscate boring variable names for great justice
var \u006C\u006F\u006C\u0077\u0061\u0074 = 'heh';

// Did you know about the [.] syntax?
var ᱹ = 1;
System.log([1, 2, 3][ᱹ] === 2);

// While perfectly valid, this doesn’t work in most browsers:
var foo\u200Cbar = 42;

// This is *not* a bitwise left shift (`<<`):
var 〱〱 = 2;
System.log(〱〱 << 〱〱); // This is though


// Fun with Roman numerals
var Ⅳ = 4;
var Ⅴ = 5;
System.log(Ⅳ + Ⅴ); // 9

// OK, it's gone too far now

var Hͫ̆̒̐ͣ̊̄ͯ͗͏̵̗̻̰̠̬͝ͅE̴̷̬͎̱̘͇͍̾ͦ͊͒͊̓̓̐_̫̠̱̩̭̤͈̑̎̋ͮͩ̒͑̾͋͘Ç̳͕̯̭̱̲̣̠̜͋̍O̴̦̗̯̹̼ͭ̐ͨ̊̈͘͠M̶̝̠̭̭̤̻͓͑̓̊ͣͤ̎͟͠E̢̞̮̹͍̞̳̣ͣͪ͐̈T̡̯̳̭̜̠͕͌̈́̽̿ͤ̿̅̑Ḧ̱̱̺̰̳̹̘̰́̏ͪ̂̽͂̀͠ = 'Zalgo';


System.log("Hͫ̆̒̐ͣ̊̄ͯ͗͏̵̗̻̰̠̬͝ͅE̴̷̬͎̱̘͇͍̾ͦ͊͒͊̓̓̐_̫̠̱̩̭̤͈̑̎̋ͮͩ̒͑̾͋͘Ç̳͕̯̭̱̲̣̠̜͋̍O̴̦̗̯̹̼ͭ̐ͨ̊̈͘͠M̶̝̠̭̭̤̻͓͑̓̊ͣͤ̎͟͠E̢̞̮̹͍̞̳̣ͣͪ͐̈T̡̯̳̭̜̠͕͌̈́̽̿ͤ̿̅̑Ḧ̱̱̺̰̳̹̘̰́̏ͪ̂̽͂̀͠ "+ Hͫ̆̒̐ͣ̊̄ͯ͗͏̵̗̻̰̠̬͝ͅE̴̷̬͎̱̘͇͍̾ͦ͊͒͊̓̓̐_̫̠̱̩̭̤͈̑̎̋ͮͩ̒͑̾͋͘Ç̳͕̯̭̱̲̣̠̜͋̍O̴̦̗̯̹̼ͭ̐ͨ̊̈͘͠M̶̝̠̭̭̤̻͓͑̓̊ͣͤ̎͟͠E̢̞̮̹͍̞̳̣ͣͪ͐̈T̡̯̳̭̜̠͕͌̈́̽̿ͤ̿̅̑Ḧ̱̱̺̰̳̹̘̰́̏ͪ̂̽͂̀͠);

Can you use them in between scripts?

Interestingly, we can also use this variable names not only in the scripts but also, out of them i.e. as inputs, outputs and attributes. See this action’s input:

As we see, vRO raises an alarm here saying that Parameter name can contain only letters, numbers, and the symbols "_" and "$". Parameter name cannot start or end with ".".

However, when I run this action, it runs perfectly normal.

I think it is quite amusing. If used dexterously, it could give another dimension to your code. 👽

JavaScript variable name validator

Even if you’d learn these rules by heart, it would be virtually impossible to memorize every character in the different Unicode categories that are allowed. If you were to summarize all these rules in a single ASCII-only regular expression for JavaScript, it would be 11,236 characters long.

For that reason, you can go to mothereff.in/js-variables, a webtool and check if a given string is a valid variable name in JavaScript or not.

That’s it in this post. If you want to know more about the JavaScript implementation in vRO, check out my other posts.

Advertisements

List of PowerShell Modules in vRO 8.x

Here is the list of all the PowerShell Modules that comes preinstalled in vRO 8.x. In later versions of vRO, we have 2 PowerShell environments 6.x and 7.x. There is a slight difference in the modules as you can notice below in both the versions.

Advertisements
For Powershell 7.xFor Powershell 6.x
PowerNSXPowerNSX
PowervRAPowervRA
VMware.CloudServicesVMware.DeployAutomation
VMware.DeployAutomationVMware.ImageBuilder
VMware.ImageBuilderVMware.PowerCLI
VMware.PowerCLIVMware.Vim
VMware.VimVMware.VimAutomation.Cis.Core
VMware.VimAutomation.Cis.CoreVMware.VimAutomation.Cloud
VMware.VimAutomation.CloudVMware.VimAutomation.Common
VMware.VimAutomation.CommonVMware.VimAutomation.Core
VMware.VimAutomation.CoreVMware.VimAutomation.Hcx
VMware.VimAutomation.HcxVMware.VimAutomation.HorizonView
VMware.VimAutomation.HorizonViewVMware.VimAutomation.License
VMware.VimAutomation.LicenseVMware.VimAutomation.Nsxt
VMware.VimAutomation.NsxtVMware.VimAutomation.Sdk
VMware.VimAutomation.SdkVMware.VimAutomation.Security
VMware.VimAutomation.SecurityVMware.VimAutomation.Srm
VMware.VimAutomation.SrmVMware.VimAutomation.Storage
VMware.VimAutomation.StorageVMware.VimAutomation.StorageUtility
VMware.VimAutomation.StorageUtilityVMware.VimAutomation.Vds
VMware.VimAutomation.VdsVMware.VimAutomation.Vmc
VMware.VimAutomation.VmcVMware.VimAutomation.vROps
VMware.VimAutomation.vROpsVMware.VumAutomation
VMware.VimAutomation.WorkloadManagementMicrosoft.PowerShell.Host
VMware.VumAutomationMicrosoft.PowerShell.Management
Microsoft.PowerShell.HostMicrosoft.PowerShell.Security
Microsoft.PowerShell.ManagementMicrosoft.PowerShell.Utility
Microsoft.PowerShell.SecurityPackageManagement
Microsoft.PowerShell.UtilityPowerShellGet
PackageManagementPSDesiredStateConfiguration
PowerShellGetPSReadLine
PSReadLinePSReadLine

As you might have noticed, in 7.x, we have two additional modules i.e. VMware.CloudServices & VMware.VimAutomation.WorkloadManagement, but misses out PSDesiredStateConfiguration that is only available in 6.x.

Check out other list of modules here:

for Python: https://cloudblogger.co.in/2022/03/08/list-of-all-available-python-modules-in-vro/

for NodeJs: https://cloudblogger.co.in/2022/03/15/list-of-available-node-js-modules-in-vro/

Advertisements

Change your OAuth 2.0 token strategy using Scripting API

Introduction

Adding a REST Host in vRO is quite easy. Just run a workflow Add a REST Host and provide some details and select an Authentication type (viz. None, Basic, OAuth, OAuth 2.0, Digest, NTLM or Kerberos) or maybe you can create transient REST hosts using Scripting API. However, if you are using OAuth 2.0 for authenticating your REST hosts in vRO, you should shift your attention a little here.

With vRO 8.7, you now have an option to select a strategy on how to send the OAuth 2.0 bearer access token to your authorized request — oauth_token query parameter & Authorization header. The newly introduced and recommended strategy is to use the Authorization header to send the token when making request to the host.

Flow of OAuth 2.0 authorization. Source: authlib.org

Concern

The main reason to make this change is that Authorization header is more secure as it doesn’t expose the server logs in the incoming requests as with query parameter. Also, the query parameter will be deprecated soon in the future releases of vRO. So, it is probably the time to change/update your OAuth 2.0 authorized REST hosts. One way is to simply run Update a REST Host library workflow, but we will go with the other way i.e. updating it using the Scripting API.

Process

Create an action and copy-paste this script which has 2 inputs RESTHost and token and run it.

/**
 * @function changeOauth2Strategy
 * @version 1.0.0
 * @param {REST:RESTHost} host
 * @param {string} token 
 * @returns {REST:RESTHost}
 */
function changeOauth2Strategy(host, token) {
    var oldAuth = host.authentication
    var ouath20type = "OAuth 2.0"
    if (oldAuth.type !== ouath20type) {
        System.log("REST host isn't using" + ouath20type);
        result = host;
    } else {
        var oldStrategy = oldAuth.rawAuthProperties[1]; // or use oldAuth.getRawAuthProperty(1)
        if (oldStrategy === "Query parameter") {
            var newStrategy = "Authorization header";
        } else {
            var newStrategy = "Query parameter"
        }
        var newAuth = RESTAuthenticationManager.createAuthentication("OAuth 2.0", [token, newStrategy]);
        host.authentication = newAuth;
        return RESTHostManager.updateHost(host);
    }
};

You can verify what token sending strategy your REST host uses by navigating to Inventory > REST-Host, selecting your host, and checking the Authorization entry.

Middle Way

There is more to this story. The old scripting approach of creating an OAuth 2.0 authentication by passing only the token parameter without a token sending strategy still works, and for backwards compatibility preserves the past behavior of using the query parameter strategy. This means that the the below code will work for both type of strategies (in case you have both type of REST Hosts in your inventory).

host.authentication = RESTAuthenticationManager.createAuthentication("OAuth 2.0", ["<token>"]);

Subscription received!

Please check your email to confirm your newsletter subscription.

Free VMware Badges in 2022

If you are looking for some free VMware badges to upskill and boost your resume, feel free to pursue the following VMware courses.

VMware Skyline Advisor Pro Technologist badge

The badge holder helps organizations use VMware Skyline Advisor Pro to proactively avoid issues before they occur, increase network reliability and security, ensure peak performance, and reduce time-to-resolution for service requests.

Link: https://learning.customerconnect.vmware.com/site/program.do?dispatch=showCourseSession&id=379269e0-5bfb-11ec-b5a6-0cc47a352292


IT Academy: Software Defined Storage Concepts

The badge holder is an entry level professional that has the basic understanding of storage virtualization, the Software-Defined Data Center and basics of vSAN architecture. This badge holder can identify types of software-defined storage, the layers of a software-defined storage model, and components of a Hyper-Converged Storage vSAN.

Link: https://portal.netdevgroup.com/learn/sds-concepts


IT Academy: Network Virtualization Concepts

The badge holder is an entry level professional that has the basic understanding of network virtualization, the Software-Defined Data Center, and basics of NSX architecture. This badge holder can understand how to bridge physical with virtual networks, identify vSphere virtual networking components, and identify key components in the NSX architecture.

Link: https://portal.netdevgroup.com/learn/net-virt-concepts


IT Academy: Cloud and Virtualization Concepts

The badge holder will be aware of the basics of virtualization and the data center. Cloud concepts will be introduced along with virtualization solutions. The Cloud and Virtualization badge holder is an entry level individual that understands the basics of cloud computing and virtualization. The badge holder can set up and manage a virtual machine.

Link: https://portal.netdevgroup.com/learn/cloud-virt-concepts

I have already completed all of them. You can check my credentials here on Credly.com

https://www.credly.com/users/mayankgoyal1994

Advertisements

Don’t Ignore .gitignore in vRO 8.x

  1. Introduction
  2. Advantages
  3. Procedure
  4. Limitations
  5. Flush Git from vRO
  6. Available on gitignore.io

Introduction

I am sure everyone is using the git feature of vRO 8.x and you probably be pushing & pulling your vRO content across your DEV, STAGING, UAT & PROD environments. The question is, “Are you using .gitignore while pushing code from vRO? and why do you need it?”. This question was asked in vRO community (link here), and since the comment that I made answered the query, I thought I should write about it. Let’s see how .gitignore can ease your life during code promotions and gives you fluidity to have environment specific values safe as well as keeps the gibberish away from PROD vRO etc. and keeps your assembly vRO’s codebase clean and compact.


Note If you are looking to setup git in vRealize Orchestrator, follow this official link https://blogs.vmware.com/management/2022/05/git-repository-integration-in-vrealize-orchestrator.html.


Advantages

I will not go in details on how .gitignore works. You can learn more about .gitignore online. Fundamentally, .gitignore allows you to exclude specific files or directories from being pushed to the remote repository. Hence, using .gitignore can drastically improve the performance of your CI\CD pipelines. For vRealize Orchestrator, I have come across mainly following types of files that I want to exclude:

  • Test actions & workflows: Development generally relies on hits & trials. This leaves a lot of post-development debris.
  • Environment specific assets like Configuration elements: This may include passwords or API keys.
  • Packages: Since you have git-power, you don’t really need packages to move your code and hence, if you are using them, it’s probably something not as critical.
  • Default Library content: Why would you copy something which is already there at first place.
  • Multi Node Workflows: These dummy workflows doesn’t need to push across (starts with VCO@).

Question? Can you think of any other type of file that should be ignored? Comment down your answer.


You can use literal file names, wildcard symbols, etc to get them listed. Also, you can use negating patterns. A negating pattern is a pattern that starts with an exclamation mark (!) negates (re-include) any file that is ignored by the previous pattern. The exception to this rule is to re-include a file if its parent directory is excluded.

Procedure

In the vRO, Go to repository which is already setup under Administration -> Git Repositories.

In our case, it will be github.com/imtrinity94/cloudblogger.co.in.

Simply, just create a .gitignore file in the root of your repo branch and list down all the files you want to ignore like

# Default Resource Elements
Resources/Library/*

# Library Workflows
Workflows/Library

# Environment Specific variables
Configurations/Vault/API Keys

# Negating pattern to explicitly include tenant specific information
!Configurations/Tenants/*

# Multi-Node Workflows
Workflows/VCO@*

# Packages
**/Packages/

# Test actions
Actions/org/mayank/test

The other way round is to ignore everything and use negating pattern to include very specific things.

# All packages, JavaScript actions,  resources, configurations, policies, Polyglot action bundles (.py, .ps1 & node.js) and Workflows
**/Packages/
**/Actions/
**/Resources/
**/Configurations/
**/ActionBundles/
**/Workflows/
**/Policy Templates/

This will avoid all the packages, resources and configurations to be committed to the corresponding repo. 

This should be enough. If you want to be more precise, The .gitignore tutorial is here https://www.atlassian.com/git/tutorials/saving-changes/gitignore

Limitations

  • If you add .gitignore after pushing everything even once, the .gitignore will work for new files but will still track those existing files.
  • The .gitignore file will become part of vRO.
  • You may lose version control on ignored objects.

Flush Git from vRO

In case, you have already set up git in your vRO and want to do a fresh start due to unwanted tracking of files or being stuck in an undesirable git state, you can locally remove the git config from your vRO by deleting the below file. Use it with caution though.

/data/vco/usr/lib/vco/app-server/data/git/__SYSTEM.git

Available on gitignore.io

As we all know https://gitignore.io is the largest collection of .gitignore files, I thought why shouldn’t I add vRO to their list as well. That’s why I created a pull request here at https://github.com/toptal/gitignore/pull/460 & it got approved. Now, if you got there and search for vRealizeOrchestrator, you will get the .gitignore file ready to be consumed in your projects.

Source: https://www.toptal.com/developers/gitignore/api/vrealizeorchestrator

That’s it in this post. Let me know what you think about it in the comments.