Create ESXi root account with vRO [CB10104]


TL;DR If you would like to create ESXi local account using vRO, download this package (in.co.cloudblogger.crudEsxiLocalUser.package) to get started.


  1. Introduction
  2. Classes & Methods
  3. Script for creating a local admin account in ESXi
  4. Demo Video
  5. vRO Package for CRUD operation

Introduction

Many organization uses vRO for Host Provisioning. Various hardware vendors provide vRO Scripting APIs via plugins or REST APIs to manage and provision bare-metal servers. While doing so, there is always a possibility that post-provisioning, you would like to access your ESXi host from an account other than root for several reasons like security restrictions, limited access etc. In that case, the best way is to create a fresh new account using vRO with the kind of access mode or lets call it, role that suits the needs. In this post, we will see how to create an ESXi local user account using vRO Scripting API.

Classes & Methods

As shown below, we have used following classes and methods for retrieval of existing accounts, creation, updating & deletion of accounts as well as change access or Role of those accounts.

Script for creating a local admin account in ESXi

Link to gist here.

/**
 *
 * @version 0.0.0
 *
 * @param {VC:HostSystem} host 
 * @param {string} localUserName 
 * @param {SecureString} localUserPassword 
 * @param {string} accessMode 
 * @param {string} localUserDescription 
 *
 * @outputType void
 *
 */
function createEsxiLocalUser(host, localUserName, localUserPassword, accessMode, localUserDescription) {
	if(!host) throw "host parameter not set";
	if(!localUserName || !localUserPassword) throw "Either username or password parameter not set";
	if(!localUserDescription) localUserDescription = "***Account created using vRO***";
	if(localUserDescription.indexOf(localUserPassword) != -1) throw 'Weak Credentials! Avoid putting password string in description';
	
	// Retrieve all system and custom user accounts
	var arrExistingLocalusers = host.configManager.hostAccessManager.retrieveHostAccessControlEntries();
	var accountSpecs = new VcHostAccountSpec(localUserName,localUserPassword,localUserDescription);
	host.configManager.accountManager.createUser(accountSpecs);
	switch(accessMode){
	    case 'Admin': //Full access rights
	        host.configManager.hostAccessManager.changeAccessMode(localUserName,false,VcHostAccessMode.accessAdmin);
	        break;
	    case 'ReadOnly': //See details of objects, but not make changes
	        host.configManager.hostAccessManager.changeAccessMode(localUserName,false,VcHostAccessMode.accessReadOnly);
	        break;
	    case 'NoAccess': //Used for restricting granted access
	        host.configManager.hostAccessManager.changeAccessMode(localUserName,false,VcHostAccessMode.accessNoAccess);
	        break;
	    default: //No access assigned. Note: Role assigned is accessNone
	        host.configManager.hostAccessManager.changeAccessMode(localUserName,false,VcHostAccessMode.accessNone);
	}
	System.warn("  >>> Local user "+localUserName+" created with accessMode "+accessMode+" on host "+host.name);
	
	
}

Demo Video

In this demo, we can see how the workflow is utilized to create a local account testuser1 through which we logged in to ESXi and check if it has required permissions.

vRO Package for CRUD operation

I have created a vRO Workflow to create and manage your ESXi local accounts directly from the input form itself. Please find the vRO package that contains the master workflow and associated actions.

  • Workflow: CRUD Operation on ESXi Local Users 
  • Actions:
    • getEsxiLocalUser
    • deleteEsxiLocalUser
    • updateEsxiLocalUser
    • createEsxiLocalUser
    • getAllEsxiLocalUsers
    • getAllEsxiLocalUsersWithRoles

Link to vRO package: in.co.cloudblogger.crudEsxiLocalUser.package

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

Inside vRO’s JavaScript Engine – Rhino 1.7R4 [CB10102]

  1. What is Rhino Engine?
  2. Released 10 years ago
  3. Compatibility with JavaScript features
  4. ECMAScript 5.1 Specifications
  5. Rhino on GitHub
  6. Rhino Engine Limitations in vRO
  7. Access to additional Java Classes
    1. Procedure
  8. Javadoc for Rhino 1.7R4
    1. Feature Set when released
  9. Additional Links

vRealize Orchestrator a.k.a. vRO, which is a drag-and-drop automation tool, is quite an old tool developed and released as early as in 2007 by Dunes Technologies, Switzerland. After VMware acquired Dunes, there were 100’s of releases and updates came year after year. Lots and lots of improvements made over time in the UI, backend technologies, security, multi-language support, etc. However, one thing that remains the same is its JavaScript Engine. vRO uses Mozilla Rhino Engine 1.7R4 which was released in 2012.

In this post, My goal is to provide some insights on this Rhino Engine as it is almost extinct from the internet. However, I am still behind the JavaScript Engine which provides IntelliSense support to vRO 8.x. As you might have noticed and probably be wondering how CTRL+SPACE shows options only available to recent versions of JavaScript. I guess it’s for Node.js runtime.

What is Rhino Engine?

Rhino Engine converts JavaScript scripts into classes. It is intended to be used in desktop or server-side applications, hence there is no built-in support for the Web browser objects that are commonly associated with JavaScript which makes it very suitable for vRO. Rhino works in both compiled and interpreted mode. Rhino Engine got its name from the animal on the cover of the O’Reilly book about JavaScript published many years back.

The Rhino project was started at Netscape in the autumn of 1997. At the time, Netscape was planning to produce a version of Navigator written entirely in Java and so it needed an implementation of JavaScript written in Java. When Netscape stopped work on “Javagator,” as it was called, somehow Rhino escaped the axe (rumor had it that the executives “forgot” it existed). For a time, a couple of major companies (including Sun) licensed Rhino for use in their products and paid Netscape to do so, allowing work on Rhino to continue. Now Rhino is part of Mozilla’s open-source repository.

Released 10 years ago

Released in 2012-06-18, Rhino 1.7R4 is almost prehistoric for today’s standards and that’s been always a point of discussion in the vRO Community.

Release Notes of 1.7R4

Compatibility with JavaScript features

While trying to look deep into its compatibility matrix with ES, I found this Kangax’s Compat-table which gives an excellent and detailed view of all the possible features that Rhino 1.7R4 supports. Click the link to know more.

Rhino Compatibility Matrix with JavaScript

ECMAScript 5.1 Specifications

This document will give you a very in-depth knowledge of the ECMAScript 5.1 that vRO leverages to understand the language better. Learn more at https://262.ecma-international.org/5.1.

You can download this document and read about all the fine details by yourself.

Rhino on GitHub

Currently, on GitHub page of Mozilla, version 1.7R4 is not available. However, you may find some very old scripts that were written at the time of 1.7R4 as I can validate using web-achieve. You can explore their GitHub repo here.

Rhino Engine Limitations in vRO

When writing scripts for workflows, you must consider the following limitations of the Mozilla Rhino implementation in Orchestrator.

  • When a workflow runs, the objects that pass from one workflow element to another are not JavaScript objects. What is passed from one element to the next is the serialization of a Java object that has a JavaScript image. As a consequence, you cannot use the whole JavaScript language, but only the classes that are present in the API Explorer. You cannot pass function objects from one workflow element to another.
  • Orchestrator runs the code in scriptable task elements in a context that is not the Rhino root context. Orchestrator transparently wraps scriptable task elements and actions into JavaScript functions, which it then runs. A scriptable task element that contains System.log(this); does not display the global object this in the same way as a standard Rhino implementation does.
  • You can only call actions that return nonserializable objects from scripting, and not from workflows. To call an action that returns a nonserializable object, you must write a scriptable task element that calls the action by using the System.getModuleModuleName.action() method.
  • Workflow validation does not check whether a workflow attribute type is different from an input type of an action or subworkflow. If you change the type of a workflow input parameter, for example from VIM3:VirtualMachine to VC:VirtualMachine, but you do not update any scriptable tasks or actions that use the original input type, the workflow validates but does not run.

Access to additional Java Classes

By default, vRealize Orchestrator restricts JavaScript access to a limited set of Java classes. If you require JavaScript access to a wider range of Java classes, you must set an vRealize Orchestrator system property.

Allowing the JavaScript engine full access to the Java virtual machine (JVM) presents potential security issues. Malformed or malicious scripts might have access to all the system components to which the user who runs the vRealize Orchestrator server has access. Therefore, by default the vRealize Orchestrator JavaScript engine can access only the classes in the java.util.* package.

If you require JavaScript access to classes outside of the java.util.* package, you can list in a configuration file the Java packages to which to allow JavaScript access. You then set the com.vmware.scripting.rhino-class-shutter-file system property to point to this file.

Procedure

  1. Create a text configuration file to store the list of Java packages to which to allow JavaScript access.For example, to allow JavaScript access to all the classes in the java.net package and to the java.lang.Object class, you add the following content to the file.java.net.* java.lang.Object
  2. Enter a name for the configuration file.
  3. Save the configuration file in a subdirectory of /data/vco/usr/lib/vco. The configuration file cannot be saved under another directory.
  4. Log in to Control Center as root.
  5. Click System Properties.
  6. Click New.
  7. In the Key text box, enter com.vmware.scripting.rhino-class-shutter-file.
  8. In the Value text box, enter vco/usr/lib/vco/your_configuration_file_subdirectory.
  9. In the Description text box, enter a description for the system property.
  10. Click Add.
  11. Click Save changes from the pop-up menu.A message indicates that you have saved successfully.
  12. Wait for the vRealize Orchestrator server to restart.

See an implementation example of accessing external Java classes by BlueCat here. Here, the code implements new java.lang.Long(0)

.
.
.
var testConfig = BCNProteusAPI.createAPIEntity(new java.lang.Long(0),configName,"","Configuration" );
var args = new Array( new java.lang.Long(0), testConfig );
configId = new java.lang.Long( BCNProteusAPI.call( profileName,"addEntity",args ));
System.log( "New configuration was created, id=" + configId );
var addTFTPGroupArgs = new Array( configId, "tftpGroupName1", "" );
var tftpGroupId = new java.lang.Long( BCNProteusAPI.call(profileName,"addTFTPGroup", addTFTPGroupArgs ) );
System.log( "New TFTP Group was created, id=" + tftpGroupId );
.
.
.

Javadoc for Rhino 1.7R4

Feature Set when released

Source: https://contest-server.cs.uchicago.edu/ref/JavaScript/developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/1-7.html#New_features_in_JavaScript_1.7

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

  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.

Collection of VMware for Dummies Books

Do you feel like a tech dummy when it comes to VMware technologies? VMware already got your back. VMware has collaborated with For Dummies® for releasing an extensive list of books which can help you or your organization learn about the technology tools that you can use to optimize productivity and performance as ideally Learning shouldn’t have to involve months of courses or training. In this post, I will try to cover all of them . You can find them online and can download from official link by providing few details or you can head to my GitHub and find all the books there. Go to link ➜

List of VMware for Dummies Books