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

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);

Don’t Ignore .gitignore in vRO 8.x

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.

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 creates a lot of hit & trial. 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.

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.

Experiencing GitHub Copilot as a vRO Developer

What is Copilot?

A new AI tool named Copilot by GitHub is on hype these days. As the site suggests, It’s basically an AI-based programming assistant that can help you with writing code more than just auto-complete. It is available to use with Visual Studio Code, Neovim and JetBrains.

Introducing GitHub Copilot: your AI pair programmer | The GitHub Blog

I am totally amazed by this idea and have a feeling that AI will definitely take over some day. Anyway, let’s future decide it’s fate. Now, I am thinking if It can help a vRO Developer like me to write some code in similar way. So, I signed up for Copilot and in few days, I was added to their Technical Preview program. If you want to try it by yourself, you can setup your VSC with Copilot plugin using this tutorial here.


Time to Inspect

I already had Visual Studio Code installed and just downloaded Copilot Plugin for VSC from here.

  • First, I tried to write a code on fetching all the templates from vSphere.
  • then, I tried to fetch all admin Vdcs from pvdcs

I found Copilot quite intuitive. It was not all perfect and required constant guidance by me. This also means that you must know what you’re doing and have at least a rough idea on how to derive the Copilot’s attention to provide the right code. It was just throwing random hints in the beginning. But as I continued writing code, it started to suggest more sensible code which I think is very amazing.


Verdict

vRO uses a proprietary JavaScript which is not readily available online and limits the size of training set required by systems like OpenAI (on which Copilot is based) to provide more & more realistic responses. Currently, Copilot uses GitHub code to train itself as you can see from the suggestions, so if more people share their vRO code on GitHub, Copilot will become more instinctual over-time.

If you ask me, I do my share by publish vRO JS code on my repository here. You may find hundreds of scripts there as well as on gist page here.