CloudForms 4.6 brings a lot to the table in terms of automation. Now that we are seeing the arrival of Ansible Modules like manageiq_user and manageiq_provider, the Playbook based service in CloudForms is looking a lot cleaner and easy to use. While this is indeed the future, there have been some improvements to the Automate engine that don't directly involve Ansible in 4.6 as well, and they're pretty useful. In this post we'll discuss two of those.
what we're after
This is a simple post to introduce and discuss two enhancements: Expression Methods and Embedded Methods.
Before 4.6, if you wanted to get a list of something in the VMDB, it would require a little Ruby. Alternatively, you could make the requisite API call to the appliance (with Ruby or a Playbook) if what you were looking for was exposed by the API, but those were your options. In 4.6, a new method type is introduced called an Expression Method. This will allow you to use the familiar regex editor (similar to the advanced search menu) to pull the info you need without writing any code. It's a new method type, so you'll see the option come up when you create a method.
This is particularly useful for dynamic dialogs. In addition to the fact that it's considerably easier to use, it will also improve speed, since it doesn't rely on DRb. While there's a lot more to be said about this, in this case, it's unlikely that we could do a better job than the articulate description that is available here. Highly recommend you give it a read.
This one is pretty exciting. It has a lot of potential and we think it's usefullness is going to become apparent pretty quickly once people start using it.
Until now, if you wanted to use an actual ruby method inside a CloudForms Automate Method, you would need to define that method where you used it. That meant if you had six different methods that were using the same Ruby method, say for an API call, it would need to be defined six times.
In CloudForms 4.6, we're getting something called the embedded method. This allows us to create a base method with all our reusable methods, and let all the Automate Methods that want to use it inherit it. This will greatly reduce the amount of code that you actually have to write and maintain, and when something does change, you'll be changing it in one place instead of six.
Let's take a simple use case. You want to print out your ASCII spirit animal in several places (obviously this is a common use case), but you only want to define it in one place. To achieve this, first we need to define a base method, and fill it with the methods we want.
In this example we define a custom logging method "log", and two ASCII spirit animals. Now we'll need an Automate Method to inherit this. When you create a new Automate Method, you now have an option to "Add Method" under the embedded methods section above the editor:
Once we do this, our test_base method is inheriting all the methods in our base_methods method. The code in our test_base method looks like this:
begin krain_crane() log("this works") unleash_the_tiger() 5.times do awesome_sauce() end unleash_the_tiger() end
As you can see, we're calling 4 methods that aren't defined. 3 of them are defined in base_methods, and we'll talk about the 4th one later. Here are the results when this gets executed.
There's our crane...
and there's our log() method and our tiger.
some other things
One thing to be aware of is that this doesn't appear to support nested inheritance. So if you inherit Method1, and Method1 is inheriting Method2, you'll only get the methods from Method1. You can, however, inherit more than one method, which we actually did in the example above. The 4th method, awesome_sauce (which just prints out the words "Awesome Sauce" and a bunch of asterisks), is not being defined in either test_base or base_method. It's defined in a third method, base2. Since test_base is inheriting both base_method and base2, however, this method gets executed successfully as well.