Merge "[Murano Docs] Remove old versions of articles"
This commit is contained in:
commit
b1f427302e
@ -1,241 +0,0 @@
|
||||
..
|
||||
Copyright 2014 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _DynamicUISpec:
|
||||
|
||||
===================================
|
||||
Dynamic UI definition specification
|
||||
===================================
|
||||
|
||||
The main purpose of Dynamic UI is to generate application creation
|
||||
forms "on-the-fly". Murano dashboard doesn't know anything about what
|
||||
applications can be deployed and which web form are needed to create
|
||||
application instance. So all application definitions should contain a
|
||||
yaml file which tells dashboard how to create an application and what
|
||||
validations are to be applied. This document will help you to compose
|
||||
a valid UI definition for your application.
|
||||
|
||||
Structure
|
||||
=========
|
||||
|
||||
UI definition should be a valid yaml file and should contain the following sections (for version 2):
|
||||
|
||||
* **Version** - points out to which syntax version is used, optional
|
||||
* **Templates** - optional, auxiliary section, used together with an Application section, optional
|
||||
* **Application** - object model description which will be used for application deployment, required
|
||||
* **Forms** - web form definitions, required
|
||||
|
||||
Version
|
||||
=======
|
||||
|
||||
Version of supported dynamic UI syntax. The latest version is 2.
|
||||
This is optional section, default version is set to 1.
|
||||
Version mapping:
|
||||
Murano 0.4 - version 1
|
||||
Murano 0.5 - version 2
|
||||
|
||||
Application and Templates
|
||||
=========================
|
||||
In the Application section an *application object model* is
|
||||
described. This model will be translated into json and according to
|
||||
that json application will be deployed. Application section should
|
||||
contain all necessary keys that are required by murano-engine to
|
||||
deploy an application. Note that under *?* section goes system part
|
||||
of the model. You can pick parameters you got from the user (they
|
||||
should be described in the Forms section) and pick the right place
|
||||
where they should be set. To do this `YAQL
|
||||
<https://github.com/ativelkov/yaql/blob/master/README.md>`_ is
|
||||
used. All lines are going to be checked for a yaql
|
||||
expressions. Currently, 2 yaql functions are provided for object model
|
||||
generation:
|
||||
|
||||
* **generateHostname** is used for machine hostname generation; it accepts 2 arguments: name pattern (string) and index (integer). If '#' symbol is present in name pattern, it will be replaced with the index provided. If pattern is not given, a random name will be generated.
|
||||
* **repeat** is used to produce a list of data snippets, given the template snippet (first argument) and number of times it should be reproduced (second argument). Inside that template snippet current step can be referenced as *$index*.
|
||||
|
||||
Note that while evaluating YAQL expressions referenced from
|
||||
**Application** section (as well as almost all attributes inside
|
||||
**Forms** section, see later) *$* root object is set to the list of
|
||||
dictionaries with cleaned forms' data. So to obtain cleaned value of
|
||||
e.g. field *name* of form *appConfiguration* , you should reference it
|
||||
as *$.appConfiguration.name*. This context will be called as
|
||||
**standard context** throughout the text.
|
||||
|
||||
*Example:*
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Templates:
|
||||
primaryController:
|
||||
?:
|
||||
type: io.murano.windows.activeDirectory.PrimaryController
|
||||
host:
|
||||
?:
|
||||
type: io.murano.windows.Host
|
||||
adminPassword: $.serviceConfiguration.adminPassword
|
||||
name: generateHostname($.serviceConfiguration.unitNamingPattern, 1)
|
||||
flavor: $.instanceConfiguration.flavor
|
||||
image: $.instanceConfiguration.osImage
|
||||
|
||||
secondaryController:
|
||||
?:
|
||||
type: io.murano.windows.activeDirectory.SecondaryController
|
||||
host:
|
||||
?:
|
||||
type: io.murano.windows.Host
|
||||
adminPassword: $.serviceConfiguration.adminPassword
|
||||
name: generateHostname($.serviceConfiguration.unitNamingPattern, $index + 1)
|
||||
flavor: $.instanceConfiguration.flavor
|
||||
image: $.instanceConfiguration.osImage
|
||||
|
||||
Application:
|
||||
?:
|
||||
type: io.murano.windows.activeDirectory.ActiveDirectory
|
||||
name: $.serviceConfiguration.name
|
||||
primaryController: $primaryController
|
||||
secondaryControllers: repeat($secondaryController, $.serviceConfiguration.dcInstances - 1)
|
||||
|
||||
|
||||
Forms
|
||||
=====
|
||||
|
||||
This section describes markup elements for defining forms (which are currently rendered and validated with Django). Each form has name, field definitions (mandatory) and validator definitions (optionally). Note that each form is split into 2 parts - input area (left side, where all the controls are located) and description area (right side, where descriptions of the controls are located).
|
||||
|
||||
Each field should contain:
|
||||
|
||||
* **name** - system field name, could be any
|
||||
* **type** - system field type
|
||||
|
||||
Currently supported options for **type** attribute are:
|
||||
|
||||
* string - text field (no inherent validations) with one-line text input
|
||||
* boolean - boolean field, rendered as a checkbox
|
||||
* text - same as string, but with a multi-line input
|
||||
* integer - integer field with an appropriate validation, one-line text input
|
||||
* password - text field with validation for strong password, rendered as two masked text inputs (second one is for password confirmation)
|
||||
* clusterip - specific text field, used for entering cluster IP address (validations for valid IP address syntax and for that IP to belong to a fixed subnet)
|
||||
* floatingip - specific boolean field, used for specifying whether or not an instance should have floating IP; *DEPRECATED FIELD* - use boolean field instead
|
||||
* domain - specific field, used for selecting Active Directory domain from a list (or creating a new Active Directory application); *DEPRECATED FIELD* - use io.murano.windows.ActiveDirectory instead
|
||||
* databaselist - Specific field, a list of databases (comma-separated list of databases' names, where each name has the following syntax first symbol should be latin letter or underscore; subsequent symbols can be latin letter, numeric, underscore, at the sign, number sign or dollar sign), rendered as one-line text input
|
||||
* flavor - specific field, used for selection instance flavor from a list
|
||||
* keypair - specific field, used for selecting keypair from a list
|
||||
* image- specific field, used for selecting instance image from a list
|
||||
* azone - specific field, used for selecting instance availability zone from a list
|
||||
* any other value is considered to be a fully qualified name for some Application package and is rendered as a pair of controls: one for selecting already existing Applications of that type in an Environment, second - for creating a new Application of that type and selecting it
|
||||
|
||||
Other arguments (and whether they are required or not) depends on
|
||||
field's type and other attributes values. Among the most common
|
||||
attributes are:
|
||||
|
||||
* **label** - name, that will be displayed in the form; defaults to **name** being capitalized.
|
||||
* **description** - description, that will be displayed in the description area.
|
||||
Use yaml line folding character >- to keep the correct formatting during data transferring.
|
||||
* **descriptionTitle** - title of the description, defaults to **label**; displayed in the description area
|
||||
* **hidden** whether field should be visible or not in the input area.
|
||||
Note that hidden field's description will still be visible in the descriptions area (if given).
|
||||
Hidden fields are used storing some data to be used by other, visible fields.
|
||||
* **minLength**, **maxLength** (for string fields) and **minValue**, **maxValue** (for integer fields) are transparently translated into django validation properties.
|
||||
* **validators** is a list of dictionaries, each dictionary should at least have *expr* key, under that key either some `YAQL <https://github.com/stackforge/yaql/blob/master/README.rst>`_ expression is stored, either one-element dictionary with *regexpValidator* key (and some regexp string as value). Another possible key of a validator dictionary is *message*, and although it is not required, it is highly desirable to specify it - otherwise, when validator fails (i.e. regexp doesn't match or YAQL expression evaluates to false) no message will be shown. Note that field-level validators use YAQL context different from all other attributes and section: here *$* root object is set to the value of field being validated (to make expressions shorter).
|
||||
* **widgetMedia** sets some custom *CSS* and *JavaScript* used for the field's widget rendering. Note, that files should be placed to Django static folder in advance.
|
||||
Mostly they are used to do some client-side field enabling/disabling, hiding/unhiding etc.
|
||||
This is a temporary field which will be dropped once Version 3 of Dynamic UI is implemented (since it will transparently translate YAQL expressions into the appropriate *JavaScript*).
|
||||
* **requirements** is used only with flavor field and prevents user to pick unstable for a deployment flavor.
|
||||
It allows to set minimum ram (in MBs), disk space (in GBs) or virtual CPU quantity.
|
||||
|
||||
Example that shows how to hide items, smaller than regular 'small' flavor in flavor select field:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: flavor
|
||||
type: flavor
|
||||
label: Instance flavor
|
||||
requirements:
|
||||
min_disk: 20
|
||||
min_vcpus: 2
|
||||
min_memory_mb: 2048
|
||||
|
||||
Besides field-level validators form-level validators also exist. They
|
||||
use **standard context** for YAQL evaluation and are required when
|
||||
there is need to validate some form's constraint across several
|
||||
fields.
|
||||
|
||||
*Example*
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Forms:
|
||||
- serviceConfiguration:
|
||||
fields:
|
||||
- name: name
|
||||
type: string
|
||||
label: Service Name
|
||||
description: >-
|
||||
To identify your service in logs please specify a service name
|
||||
- name: dcInstances
|
||||
type: integer
|
||||
hidden: true
|
||||
initial: 1
|
||||
required: false
|
||||
maxLength: 15
|
||||
helpText: Optional field for a machine hostname template
|
||||
- name: unitNamingPattern
|
||||
type: string
|
||||
label: Hostname template
|
||||
description: >-
|
||||
For your convenience all instance hostnames can be named
|
||||
in the same way. Enter a name and use # character for incrementation.
|
||||
For example, host# turns into host1, host2, etc. Please follow Windows
|
||||
hostname restrictions.
|
||||
required: false
|
||||
regexpValidator: '^(([a-zA-Z0-9#][a-zA-Z0-9-#]*[a-zA-Z0-9#])\.)*([A-Za-z0-9#]|[A-Za-z0-9#][A-Za-z0-9-#]*[A-Za-z0-9#])$'
|
||||
# FIXME: does not work for # turning into 2-digit numbers
|
||||
maxLength: 15
|
||||
helpText: Optional field for a machine hostname template
|
||||
# temporaryHack
|
||||
widgetMedia:
|
||||
js: ['muranodashboard/js/support_placeholder.js']
|
||||
css: {all: ['muranodashboard/css/support_placeholder.css']}
|
||||
validators:
|
||||
# if unitNamingPattern is given and dcInstances > 1, then '#' should occur in unitNamingPattern
|
||||
- expr: $.serviceConfiguration.dcInstances < 2 or not $.serviceConfiguration.unitNamingPattern.bool() or '#' in$.serviceConfiguration.unitNamingPattern
|
||||
message: Incrementation symbol "#" is required in the Hostname template
|
||||
- instanceConfiguration:
|
||||
fields:
|
||||
- name: title
|
||||
type: string
|
||||
required: false
|
||||
hidden: true
|
||||
descriptionTitle: Instance Configuration
|
||||
description: Specify some instance parameters on which service would be created.
|
||||
- name: flavor
|
||||
type: flavor
|
||||
label: Instance flavor
|
||||
description: >-
|
||||
Select registered in OpenStack flavor. Consider that service performance
|
||||
depends on this parameter.
|
||||
required: false
|
||||
- name: osImage
|
||||
type: image
|
||||
imageType: windows
|
||||
label: Instance image
|
||||
description: >-
|
||||
Select valid image for a service. Image should already be prepared and
|
||||
registered in glance.
|
||||
- name: availabilityZone
|
||||
type: azone
|
||||
label: Availability zone
|
||||
description: Select availability zone where service would be installed.
|
||||
required: false
|
||||
|
||||
Full example with Active Directory application form definitions is available here :ref:`UI Definition Of AD App <adUI>`
|
@ -1,63 +0,0 @@
|
||||
..
|
||||
Copyright 2015 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http//www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _repository:
|
||||
|
||||
=========================
|
||||
Murano package repository
|
||||
=========================
|
||||
|
||||
Murano client and dashboard are both capable of installing packages and
|
||||
bundles of packages from murano repository. To do so you should set
|
||||
``MURANO_REPO_URL`` settings in murano dashboard or ``MURANO_REPO_URL`` env
|
||||
variable for the CLI client and use the respective command for package import.
|
||||
These commands would then automatically import all the prerequisites for the
|
||||
app being installed along with any images, mentioned in said apps.
|
||||
|
||||
For more info about importing from repository see :ref:`client`.
|
||||
|
||||
Setting up your own repository
|
||||
==============================
|
||||
|
||||
It's fairly easy to set up your own murano package repository.
|
||||
To do so you need a web server, that would serve 3 directories:
|
||||
* /apps/
|
||||
* /bundles/
|
||||
* /images/
|
||||
|
||||
When importing an app by name client would append any version info, if present
|
||||
to the app name, ``.zip`` file extension and search for that file in the
|
||||
``apps`` directory.
|
||||
|
||||
When importing a bundle by name client would append ``.bundle`` file
|
||||
extension to the bundle name and search it in the ``bundles`` directory.
|
||||
Bundle file is a json or a yaml file with the following structure:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{"Packages":
|
||||
[
|
||||
{"Name": "io.murano.apps.ApacheHttpServer"},
|
||||
{"Version": "", "Name": "io.murano.apps.Nginx"},
|
||||
{"Version": "0.0.1", "Name": "io.murano.apps.Lighttpd"}
|
||||
]
|
||||
}
|
||||
|
||||
Glance images can be auto-imported by client, when mentioned in ``images.lst``
|
||||
inside the package. Please see :ref:`app_pkg` for more info about package
|
||||
composition.
|
||||
When importing images from ``image.lst`` file client simply searches for a
|
||||
file with the same name as the ``Name`` attribute of the image in the
|
||||
``images`` directory of the repository.
|
@ -89,8 +89,6 @@ Developing Applications
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
murano_pl/murano_pl_index
|
||||
articles/dynamic_ui
|
||||
articles/workflow
|
||||
articles/policy_enf_index
|
||||
|
||||
@ -112,13 +110,6 @@ Developing Applications
|
||||
|
||||
articles/client
|
||||
|
||||
**Repository**
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
articles/repository
|
||||
|
||||
**Guidelines**
|
||||
|
||||
.. toctree::
|
||||
|
@ -1,35 +0,0 @@
|
||||
..
|
||||
Copyright 2014 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
|
||||
==================
|
||||
Built-In functions
|
||||
==================
|
||||
|
||||
Murano has built-in functions which allows to do basic operations
|
||||
with Murano PL objects.
|
||||
|
||||
List operations
|
||||
====================
|
||||
|
||||
**list.skip(count)**
|
||||
|
||||
This function returns a sliced subset of initial list. It is equal
|
||||
to Python a[count:] function.
|
||||
|
||||
**list.take(count)**
|
||||
|
||||
Returns first "count" elements of a list. IT is equal to a[:count]
|
||||
operation in Python.
|
@ -1,644 +0,0 @@
|
||||
..
|
||||
Copyright 2014 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _core_library:
|
||||
|
||||
=====================
|
||||
MuranoPL Core Library
|
||||
=====================
|
||||
|
||||
Some objects and actions could be used in several application deployments. All common parts are grouped into MuranoPL libraries.
|
||||
Murano core library is a set of classes needed in every deployment. Class names from core library could be used in the application definitions.
|
||||
This library is located under the `meta <http://git.openstack.org/cgit/openstack/murano/tree/meta/io.murano/>`_ directory.
|
||||
The following classes are included into the Murano core library:
|
||||
|
||||
**io.murano:**
|
||||
|
||||
- :ref:`Object`
|
||||
- :ref:`Application`
|
||||
- :ref:`SecurityGroupManager`
|
||||
- :ref:`Environment`
|
||||
|
||||
**io.murano.resources:**
|
||||
|
||||
- :ref:`Instance`
|
||||
|
||||
:ref:`Resources <Instance_resources>`:
|
||||
|
||||
- Agent-v1.template
|
||||
- Agent-v2.template
|
||||
- linux-init.sh
|
||||
- windows-init.sh
|
||||
- :ref:`Network`
|
||||
|
||||
**io.murano.lib.networks.neutron:**
|
||||
|
||||
- :ref:`NewNetwork`
|
||||
|
||||
.. _Object:
|
||||
|
||||
Class: Object
|
||||
=============
|
||||
|
||||
Parent class for all MuranoPL classes, which implements initialize method, and setAttr and getAttr methods, which are defined in the pythonic part of the Object class.
|
||||
All MuranoPL classes are implicitly inherited from this class.
|
||||
|
||||
.. _Application:
|
||||
|
||||
Class: Application
|
||||
==================
|
||||
|
||||
Defines application itself. All custom applications should be derived from this class.
|
||||
Has two properties:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Namespaces:
|
||||
=: io.murano
|
||||
|
||||
Name: Application
|
||||
|
||||
Workflow:
|
||||
reportDeployed:
|
||||
Arguments:
|
||||
- title:
|
||||
Contract: $.string()
|
||||
Default: null
|
||||
- unitCount:
|
||||
Contract: $.int()
|
||||
Default: null
|
||||
Body:
|
||||
- $this.find(Environment).instanceNotifier.trackApplication($this, $title, $unitCount)
|
||||
|
||||
reportDestroyed:
|
||||
Body:
|
||||
- $this.find(Environment).instanceNotifier.untrackApplication($this)
|
||||
|
||||
|
||||
.. _SecurityGroupManager:
|
||||
|
||||
Class: SecurityGroupManager
|
||||
===========================
|
||||
|
||||
Manages security groups during application deployment.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Namespaces:
|
||||
=: io.murano.system
|
||||
std: io.murano
|
||||
|
||||
Name: SecurityGroupManager
|
||||
|
||||
Properties:
|
||||
environment:
|
||||
Contract: $.class(std:Environment).notNull()
|
||||
|
||||
defaultGroupName:
|
||||
Contract: $.string()
|
||||
Usage: Runtime
|
||||
Default: format('MuranoSecurityGroup-{0}', $.environment.name)
|
||||
|
||||
Workflow:
|
||||
addGroupIngress:
|
||||
Arguments:
|
||||
- rules:
|
||||
Contract:
|
||||
- FromPort: $.int().notNull()
|
||||
ToPort: $.int().notNull()
|
||||
IpProtocol: $.string().notNull()
|
||||
External: $.bool().notNull()
|
||||
- groupName:
|
||||
Contract: $.string().notNull()
|
||||
Default: $this.defaultGroupName
|
||||
Body:
|
||||
- $ext_keys:
|
||||
true:
|
||||
ext_key: remote_ip_prefix
|
||||
ext_val: '0.0.0.0/0'
|
||||
false:
|
||||
ext_key: remote_mode
|
||||
ext_val: remote_group_id
|
||||
|
||||
- $stack: $.environment.stack
|
||||
- $template:
|
||||
Resources:
|
||||
$groupName:
|
||||
Type: 'OS::Neutron::SecurityGroup'
|
||||
Properties:
|
||||
description: format('Composite security group of Murano environment {0}', $.environment.name)
|
||||
rules:
|
||||
- port_range_min: null
|
||||
port_range_max: null
|
||||
protocol: icmp
|
||||
remote_ip_prefix: '0.0.0.0/0'
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
|
||||
- $ingress: $rules.select(dict(
|
||||
port_range_min => $.FromPort,
|
||||
port_range_max => $.ToPort,
|
||||
protocol => $.IpProtocol,
|
||||
$ext_keys.get($.External).ext_key => $ext_keys.get($.External).ext_val
|
||||
))
|
||||
|
||||
- $template:
|
||||
Resources:
|
||||
$groupName:
|
||||
Type: 'OS::Neutron::SecurityGroup'
|
||||
Properties:
|
||||
rules: $ingress
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
|
||||
|
||||
.. _Environment:
|
||||
|
||||
Class: Environment
|
||||
==================
|
||||
|
||||
Defines an Environment in terms of deployments process. Groups all the Applications and their related infrastructure, able to deploy them at once.
|
||||
Environments is intent to group applications to manage them easily.
|
||||
|
||||
- *name* - an environment name
|
||||
- *applications* - list of applications belonging to an environment
|
||||
- *agentListener* - property containing a ' :ref:`io.murano.system.AgentListener` object, which may be used to interact with Murano Agent
|
||||
- *stack* - a property containing a HeatStack object which may be used to interact with the Heat Service
|
||||
- *instanceNotifier* - a property containing a :ref:`io.murano.system.InstanceNotifier` which may be used to keep track of the amount of deployed instances
|
||||
- *defaultNetworks* - a property containing user-defined Networks (:ref:`io.murano.resources.Network <Network>`), which may be used as the default networks for the Instances in this environment
|
||||
- *securityGroupManager*- a property containing a :ref:`SecurityGroupManager <SecurityGroupManager>` object, which may be used to construct a security group associated with this environment
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Namespaces:
|
||||
=: io.murano
|
||||
res: io.murano.resources
|
||||
sys: io.murano.system
|
||||
|
||||
Name: Environment
|
||||
|
||||
Properties:
|
||||
name:
|
||||
Contract: $.string().notNull()
|
||||
|
||||
applications:
|
||||
Contract: [$.class(Application).owned().notNull()]
|
||||
|
||||
agentListener:
|
||||
Contract: $.class(sys:AgentListener)
|
||||
Usage: Runtime
|
||||
|
||||
stack:
|
||||
Contract: $.class(sys:HeatStack)
|
||||
Usage: Runtime
|
||||
|
||||
instanceNotifier:
|
||||
Contract: $.class(sys:InstanceNotifier)
|
||||
Usage: Runtime
|
||||
|
||||
defaultNetworks:
|
||||
Contract:
|
||||
environment: $.class(res:Network)
|
||||
flat: $.class(res:Network)
|
||||
Usage: In
|
||||
|
||||
securityGroupManager:
|
||||
Contract: $.class(sys:SecurityGroupManager)
|
||||
Usage: Runtime
|
||||
|
||||
Workflow:
|
||||
initialize:
|
||||
Body:
|
||||
- $this.agentListener: new(sys:AgentListener, name => $.name)
|
||||
- $this.stack: new(sys:HeatStack, name => $.name)
|
||||
- $this.instanceNotifier: new(sys:InstanceNotifier, environment => $this)
|
||||
- $this.reporter: new(sys:StatusReporter, environment => $this)
|
||||
- $this.securityGroupManager: new(sys:SecurityGroupManager, environment => $this)
|
||||
|
||||
|
||||
deploy:
|
||||
Body:
|
||||
- $.agentListener.start()
|
||||
- If: len($.applications) = 0
|
||||
Then:
|
||||
- $.stack.delete()
|
||||
Else:
|
||||
- $.applications.pselect($.deploy())
|
||||
- $.agentListener.stop()
|
||||
|
||||
.. _Instance:
|
||||
|
||||
Class: Instance
|
||||
===============
|
||||
|
||||
Defines virtual machine parameters and manage instance lifecycle: spawning, deploying, joining to the network, applying security group and destroying.
|
||||
|
||||
- *name* - instance name
|
||||
- *flavor* - instance flavor, defining virtual machine 'hardware' parameters
|
||||
- *image* - instance image, defining operation system
|
||||
- *keyname* - key pair name, used to make connect easily to the instance; optional
|
||||
- *agent* - configures interaction with Murano Agent using :ref:`MuranoPL system class <io.murano.system.Agent>`
|
||||
- *ipAddresses* - list of all IP addresses, assigned to an instance
|
||||
- *networks* - configures type of networks, to which instance will be joined.
|
||||
Custom networks, that extends :ref:`Network class <Network>` could be specified and an instance will be connected to them
|
||||
and for a default environment network or flat network if corresponding values are set to true;
|
||||
without additional configurations, instance will be joined to the default network that are set in the current environment.
|
||||
- *assignFloatingIp* - determines, if floating IP need to be assigned to an instance, default is false
|
||||
- *floatingIpAddress* - IP addresses, assigned to an instance after an application deployment
|
||||
- *securityGroupName* - security group, to which instance will be joined, could be set; optional
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Namespaces:
|
||||
=: io.murano.resources
|
||||
std: io.murano
|
||||
sys: io.murano.system
|
||||
|
||||
Name: Instance
|
||||
|
||||
Properties:
|
||||
name:
|
||||
Contract: $.string().notNull()
|
||||
flavor:
|
||||
Contract: $.string().notNull()
|
||||
image:
|
||||
Contract: $.string().notNull()
|
||||
keyname:
|
||||
Contract: $.string()
|
||||
Default: null
|
||||
|
||||
agent:
|
||||
Contract: $.class(sys:Agent)
|
||||
Usage: Runtime
|
||||
ipAddresses:
|
||||
Contract: [$.string()]
|
||||
Usage: Out
|
||||
networks:
|
||||
Contract:
|
||||
useEnvironmentNetwork: $.bool().notNull()
|
||||
useFlatNetwork: $.bool().notNull()
|
||||
customNetworks: [$.class(Network).notNull()]
|
||||
Default:
|
||||
useEnvironmentNetwork: true
|
||||
useFlatNetwork: false
|
||||
customNetworks: []
|
||||
assignFloatingIp:
|
||||
Contract: $.bool().notNull()
|
||||
Default: false
|
||||
floatingIpAddress:
|
||||
Contract: $.string()
|
||||
Usage: Out
|
||||
securityGroupName:
|
||||
Contract: $.string()
|
||||
Default: null
|
||||
|
||||
Workflow:
|
||||
initialize:
|
||||
Body:
|
||||
- $.environment: $.find(std:Environment).require()
|
||||
- $.agent: new(sys:Agent, host => $)
|
||||
- $.resources: new(sys:Resources)
|
||||
|
||||
deploy:
|
||||
Body:
|
||||
- $securityGroupName: coalesce(
|
||||
$.securityGroupName,
|
||||
$.environment.securityGroupManager.defaultGroupName
|
||||
)
|
||||
- $.createDefaultInstanceSecurityGroupRules($securityGroupName)
|
||||
|
||||
- If: $.networks.useEnvironmentNetwork
|
||||
Then:
|
||||
$.joinNet($.environment.defaultNetworks.environment, $securityGroupName)
|
||||
- If: $.networks.useFlatNetwork
|
||||
Then:
|
||||
$.joinNet($.environment.defaultNetworks.flat, $securityGroupName)
|
||||
- $.networks.customNetworks.select($this.joinNet($, $securityGroupName))
|
||||
|
||||
- $userData: $.prepareUserData()
|
||||
|
||||
- $template:
|
||||
Resources:
|
||||
$.name:
|
||||
Type: 'AWS::EC2::Instance'
|
||||
Properties:
|
||||
InstanceType: $.flavor
|
||||
ImageId: $.image
|
||||
UserData: $userData
|
||||
KeyName: $.keyname
|
||||
|
||||
Outputs:
|
||||
format('{0}-PublicIp', $.name):
|
||||
Value:
|
||||
- Fn::GetAtt: [$.name, PublicIp]
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
- $.environment.stack.push()
|
||||
- $outputs: $.environment.stack.output()
|
||||
- $.ipAddresses: $outputs.get(format('{0}-PublicIp', $this.name))
|
||||
- $.floatingIpAddress: $outputs.get(format('{0}-FloatingIPaddress', $this.name))
|
||||
- $.environment.instanceNotifier.trackApplication($this)
|
||||
|
||||
joinNet:
|
||||
Arguments:
|
||||
- net:
|
||||
Contract: $.class(Network)
|
||||
- securityGroupName:
|
||||
Contract: $.string()
|
||||
Body:
|
||||
- If: $net != null
|
||||
Then:
|
||||
- If: $.assignFloatingIp and (not bool($.getAttr(fipAssigned)))
|
||||
Then:
|
||||
- $assignFip: true
|
||||
- $.setAttr(fipAssigned, true)
|
||||
Else:
|
||||
- $assignFip: false
|
||||
- $net.addHostToNetwork($, $assignFip, $securityGroupName)
|
||||
|
||||
destroy:
|
||||
Body:
|
||||
- $template: $.environment.stack.current()
|
||||
- $patchBlock:
|
||||
op: remove
|
||||
path: format('/Resources/{0}', $.name)
|
||||
- $template: patch($template, $patchBlock)
|
||||
- $.environment.stack.setTemplate($template)
|
||||
- $.environment.stack.push()
|
||||
- $.environment.instanceNotifier.untrackApplication($this)
|
||||
|
||||
createDefaultInstanceSecurityGroupRules:
|
||||
Arguments:
|
||||
- groupName:
|
||||
Contract: $.string().notNull()
|
||||
Body:
|
||||
|
||||
- If: !yaql "'w' in toLower($.image)"
|
||||
Then:
|
||||
- $rules:
|
||||
- ToPort: 3389
|
||||
IpProtocol: tcp
|
||||
FromPort: 3389
|
||||
External: true
|
||||
Else:
|
||||
- $rules:
|
||||
- ToPort: 22
|
||||
IpProtocol: tcp
|
||||
FromPort: 22
|
||||
External: true
|
||||
- $.environment.securityGroupManager.addGroupIngress(
|
||||
rules => $rules, groupName => $groupName)
|
||||
|
||||
getDefaultSecurityRules:
|
||||
prepareUserData:
|
||||
Body:
|
||||
- If: !yaql "'w' in toLower($.image)"
|
||||
Then:
|
||||
- $configFile: $.resources.string('Agent-v1.template')
|
||||
- $initScript: $.resources.string('windows-init.ps1')
|
||||
Else:
|
||||
- $configFile: $.resources.string('Agent-v2.template')
|
||||
- $initScript: $.resources.string('linux-init.sh')
|
||||
|
||||
- $configReplacements:
|
||||
"%RABBITMQ_HOST%": config(rabbitmq, host)
|
||||
"%RABBITMQ_PORT%": config(rabbitmq, port)
|
||||
"%RABBITMQ_USER%": config(rabbitmq, login)
|
||||
"%RABBITMQ_PASSWORD%": config(rabbitmq, password)
|
||||
"%RABBITMQ_VHOST%": config(rabbitmq, virtual_host)
|
||||
"%RABBITMQ_SSL%": str(config(rabbitmq, ssl)).toLower()
|
||||
"%RABBITMQ_INPUT_QUEUE%": $.agent.queueName()
|
||||
"%RESULT_QUEUE%": $.environment.agentListener.queueName()
|
||||
|
||||
- $scriptReplacements:
|
||||
"%AGENT_CONFIG_BASE64%": base64encode($configFile.replace($configReplacements))
|
||||
"%INTERNAL_HOSTNAME%": $.name
|
||||
"%MURANO_SERVER_ADDRESS%": coalesce(config(file_server), config(rabbitmq, host))
|
||||
"%CA_ROOT_CERT_BASE64%": ""
|
||||
|
||||
- Return: $initScript.replace($scriptReplacements)
|
||||
|
||||
.. _Instance_resources:
|
||||
|
||||
Instance class uses the following resources:
|
||||
|
||||
- *Agent-v2.template* - Python Murano Agent template (This agent is unified and lately, Windows Agent will be included into it)
|
||||
- *linux-init.sh* - Python Murano Agent initialization script, which sets up an agent with valid information, containing in updated agent template.
|
||||
- *Agent-v1.template* - Windows Murano Agent template
|
||||
- *windows-init.sh* - Windows Murano Agent initialization script
|
||||
|
||||
.. _Network:
|
||||
|
||||
Class: Network
|
||||
==============
|
||||
|
||||
Base abstract class for all MuranoPL classes, representing networks.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Namespaces:
|
||||
=: io.murano.resources
|
||||
|
||||
Name: Network
|
||||
|
||||
Workflow:
|
||||
addHostToNetwork:
|
||||
Arguments:
|
||||
- instance:
|
||||
Contract: $.class(Instance).notNull()
|
||||
- assignFloatingIp:
|
||||
Contract: $.bool().notNull()
|
||||
Default: false
|
||||
- securityGroupName:
|
||||
Contract: $.string()
|
||||
Default: null
|
||||
|
||||
.. _NewNetwork:
|
||||
|
||||
Class: NewNetwork
|
||||
=================
|
||||
|
||||
Defining network type, using in Neutron.
|
||||
|
||||
- *name* - network name
|
||||
- *autoUplink* - defines auto uplink network parameter; optional, turned on by default
|
||||
- *autogenerateSubnet* - defines auto subnet generation; optional, turned on by default
|
||||
- *subnetCidr* - CIDR, defining network subnet, optional
|
||||
- *dnsNameserver* - DNS server name, optional
|
||||
- *useDefaultDns* - defines ether set default DNS or not, optional, turned on by default
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Namespaces:
|
||||
=: io.murano.lib.networks.neutron
|
||||
res: io.murano.resources
|
||||
std: io.murano
|
||||
sys: io.murano.system
|
||||
|
||||
Name: NewNetwork
|
||||
|
||||
Extends: res:Network
|
||||
|
||||
Properties:
|
||||
name:
|
||||
Contract: $.string().notNull()
|
||||
|
||||
externalRouterId:
|
||||
Contract: $.string()
|
||||
Usage: InOut
|
||||
|
||||
autoUplink:
|
||||
Contract: $.bool().notNull()
|
||||
Default: true
|
||||
|
||||
autogenerateSubnet:
|
||||
Contract: $.bool().notNull()
|
||||
Default: true
|
||||
|
||||
subnetCidr:
|
||||
Contract: $.string()
|
||||
Usage: InOut
|
||||
|
||||
dnsNameserver:
|
||||
Contract: $.string()
|
||||
Usage: InOut
|
||||
|
||||
useDefaultDns:
|
||||
Contract: $.bool().notNull()
|
||||
Default: true
|
||||
|
||||
Workflow:
|
||||
initialize:
|
||||
Body:
|
||||
- $.environment: $.find(std:Environment).require()
|
||||
- $.netExplorer: new(sys:NetworkExplorer)
|
||||
|
||||
deploy:
|
||||
Body:
|
||||
- $.ensureNetworkConfigured()
|
||||
- $.environment.instanceNotifier.untrackApplication($this)
|
||||
|
||||
addHostToNetwork:
|
||||
Arguments:
|
||||
- instance:
|
||||
Contract: $.class(res:Instance).notNull()
|
||||
- assignFloatingIp:
|
||||
Contract: $.bool().notNull()
|
||||
Default: false
|
||||
- securityGroupName:
|
||||
Contract: $.string()
|
||||
Default: null
|
||||
Body:
|
||||
- $.ensureNetworkConfigured()
|
||||
- $portname: $instance.name + '-port-to-' + $.id()
|
||||
- $template:
|
||||
Resources:
|
||||
$portname:
|
||||
Type: 'OS::Neutron::Port'
|
||||
Properties:
|
||||
network_id: {Ref: $.net_res_name}
|
||||
fixed_ips: [{subnet_id: {Ref: $.subnet_res_name}}]
|
||||
security_groups:
|
||||
- Ref: $securityGroupName
|
||||
$instance.name:
|
||||
Properties:
|
||||
NetworkInterfaces:
|
||||
- Ref: $portname
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
|
||||
- If: $assignFloatingIp
|
||||
Then:
|
||||
- $extNetId: $.netExplorer.getExternalNetworkIdForRouter($.externalRouterId)
|
||||
- If: $extNetId != null
|
||||
Then:
|
||||
- $fip_name: $instance.name + '-FloatingIP-' + $.id()
|
||||
- $template:
|
||||
Resources:
|
||||
$fip_name:
|
||||
Type: 'OS::Neutron::FloatingIP'
|
||||
Properties:
|
||||
floating_network_id: $extNetId
|
||||
$instance.name + '-FloatingIpAssoc-' + $.id():
|
||||
Type: 'OS::Neutron::FloatingIPAssociation'
|
||||
Properties:
|
||||
floatingip_id:
|
||||
Ref: $fip_name
|
||||
port_id:
|
||||
Ref: $portname
|
||||
Outputs:
|
||||
$instance.name + '-FloatingIPaddress':
|
||||
Value:
|
||||
Fn::GetAtt:
|
||||
- $fip_name
|
||||
- floating_ip_address
|
||||
Description: Floating IP assigned
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
|
||||
ensureNetworkConfigured:
|
||||
Body:
|
||||
- If: !yaql "not bool($.getAttr(networkConfigured))"
|
||||
Then:
|
||||
- If: $.useDefaultDns and (not bool($.dnsNameserver))
|
||||
Then:
|
||||
- $.dnsNameserver: $.netExplorer.getDefaultDns()
|
||||
|
||||
- $.net_res_name: $.name + '-net-' + $.id()
|
||||
- $.subnet_res_name: $.name + '-subnet-' + $.id()
|
||||
- $.createNetwork()
|
||||
- If: $.autoUplink and (not bool($.externalRouterId))
|
||||
Then:
|
||||
- $.externalRouterId: $.netExplorer.getDefaultRouter()
|
||||
- If: $.autogenerateSubnet and (not bool($.subnetCidr))
|
||||
Then:
|
||||
- $.subnetCidr: $.netExplorer.getAvailableCidr($.externalRouterId, $.id())
|
||||
- $.createSubnet()
|
||||
- If: !yaql "bool($.externalRouterId)"
|
||||
Then:
|
||||
- $.createRouterInterface()
|
||||
|
||||
- $.environment.stack.push()
|
||||
- $.setAttr(networkConfigured, true)
|
||||
|
||||
|
||||
createNetwork:
|
||||
Body:
|
||||
- $template:
|
||||
Resources:
|
||||
$.net_res_name:
|
||||
Type: 'OS::Neutron::Net'
|
||||
Properties:
|
||||
name: $.name
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
|
||||
createSubnet:
|
||||
Body:
|
||||
- $template:
|
||||
Resources:
|
||||
$.subnet_res_name:
|
||||
Type: 'OS::Neutron::Subnet'
|
||||
Properties:
|
||||
network_id: {Ref: $.net_res_name}
|
||||
ip_version: 4
|
||||
dns_nameservers: [$.dnsNameserver]
|
||||
cidr: $.subnetCidr
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
|
||||
createRouterInterface:
|
||||
Body:
|
||||
- $template:
|
||||
Resources:
|
||||
$.name + '-ri-' + $.id():
|
||||
Type: 'OS::Neutron::RouterInterface'
|
||||
Properties:
|
||||
router_id: $.externalRouterId
|
||||
subnet_id: {Ref: $.subnet_res_name}
|
||||
- $.environment.stack.updateTemplate($template)
|
@ -1,385 +0,0 @@
|
||||
..
|
||||
Copyright 2014 2014 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http//www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
YAML
|
||||
====
|
||||
|
||||
YAML is human-readable data serialization format that is a superset of JSON. Unlike JSON YAML was designed to be read and written by humans and relies on visual indentation to denote nesting of data structures. This is similar to how Python uses indentation for block structures instead of curly brackets in most C-like languages. Also YAML can contain more data types comparing to JSON. See http://yaml.org/ for detailed description of YAML.
|
||||
|
||||
MuranoPL was designed to be representable in YAML so that MuranoPL code could remain readable and structured. Thus usually MuranoPL files are YAML encoded documents. But MuranoPL engine itself doesn't deal directly with YAML documents and it is up to hosting application to locate and deserialize definitions of particular classes. This gives hosting application ability to control where those definitions can be found (file system, database, remote repository etc) and possibly use some other serialization formats instead of YAML.
|
||||
|
||||
MuranoPL engine relies on host deserialization code to automatically detect YAQL expressions in source definition and to provide them as instances of YaqlExpression class rather than plain strings. Usually YAQL expressions can be distinguished by presence of $ (dollar sign) and operators but in YAML developer can always explicitly state the type by using YAML tags. So
|
||||
::
|
||||
|
||||
Some text - a string,
|
||||
$.something() - YAQL
|
||||
"$.something()" - string (because of quote marks)
|
||||
!!str $ - a string (because of YAML tag)
|
||||
!yaql "text" - YAQL (because of YAML tag)
|
||||
|
||||
|
||||
YAQL
|
||||
====
|
||||
|
||||
YAQL (Yet Another Query Language) is a query language that was also designed as part of Murano project. MuranoPL makes an extensive use of YAQL. YAQL description can be found here: https://github.com/ativelkov/yaql
|
||||
|
||||
In simple words YAQL is a language for expression evaluation. ``2 + 2, foo() > bar(), true != false`` are all valid YAQL expressions. The interesting thing in YAQL is that it has no built in list of functions. Everything YAQL can access is customizable. YAQL cannot call any function that was not explicitly registered to be accessible by YAQL. The same is true for operators. So the result of expression 2 * foo(3, 4) is completely depended on explicitly provided implementations of "foo" and "operator_*".
|
||||
YAQL uses dollar sign ($) to access external variables (that are also explicitly provided by host application) and function arguments. ``$variable`` is a syntax to get the value of variable "$variable",
|
||||
$1, $2 etc are the names for function arguments. "$" is a name for current object - data on which the expression is evaluated or a name of a single argument. Thus $ in the beginning of expression and $ in middle of it can refer to different things.
|
||||
|
||||
YAQL has a lot of functions out of the box that can be registered in YAQL context. For example
|
||||
|
||||
``$.where($.myObj.myScalar > 5 and $.myObj.myArray.len() > 0 and $.myObj.myArray.any($ = 4)).select($.myObj.myArray[0])`` can be executed on ``$ = array`` of objects and has a result of another array that is a filtration and projection of a source data. This is very similar to how SQL works but uses more Python-like syntax.
|
||||
|
||||
Note that there is no assignment operator in YAQL and '=' means comparision operator that is what '==' means in Python.
|
||||
|
||||
Because YAQL has no access to underlying operating system resources and 100% controllable by the host it is secure to execute YAQL expressions without establishing a trust to executed code. Also because of the functions are not predefined different functions may be accessible in different contexts. So the YAQL expressions that are used to specify property contracts are not necessarily valid in workflow definitions.
|
||||
|
||||
Common class structure
|
||||
======================
|
||||
|
||||
Here is a common template for class declarations. In sections below I'm going to explain what each section means. Note that it is in YAML format.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Name: class name
|
||||
Namespaces: namespaces specification
|
||||
Extends: [list of parent classes]
|
||||
Properties: properties declaration
|
||||
Workflow:
|
||||
methodName:
|
||||
Arguments:
|
||||
- list
|
||||
- of
|
||||
- arguments
|
||||
Body:
|
||||
- list
|
||||
- of
|
||||
- instructions
|
||||
|
||||
Thus MuranoPL class is a YAML dictionary with predefined key names. All keys except for Name are optional and can be omitted (but must be valid if present)
|
||||
|
||||
Class name
|
||||
----------
|
||||
|
||||
Class names are alphanumeric names of the classes. By tradition all class names begin with upper-case letter and written in PascalCasing.
|
||||
|
||||
In Murano all class names are globally unique. This achieved by means of namespaces. Class name may have explicit namespace specification (like ns:MyName) or implicit (just MyName which would be equal to =:MyName if = was a valid in name specification)
|
||||
|
||||
Namespaces
|
||||
----------
|
||||
|
||||
Namespaces declaration specifies prefixes that can be used in class body to make long class names shorter.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Namespaces:
|
||||
=: io.murano.services.windows
|
||||
srv: io.murano.services
|
||||
std: io.murano
|
||||
|
||||
In example above class name srv:Something would be automatically translated to "io.murano.services.Something".
|
||||
|
||||
"=" means "current namespace" so that "MyClass" would mean "io.murano.services.windows.MyClass" in example above.
|
||||
|
||||
If class name contains period sign (.) in its name then it is assumed to be already fully namespace-qualified and is not expanded. Thus ns.Myclass would remain as is.
|
||||
|
||||
To make class names globally unique it is recommended to have developer's domain name as part of namespace (as in example, similar to Java)
|
||||
|
||||
Extends
|
||||
-------
|
||||
|
||||
MuranoPL supports multiple inheritance. If present, Extends section lists base classes that are extended. If the list consists of single entry then it may be written as a scalar string instead of array. If no parents specified (or a key is omitted) then "io.murano.Object" is assumed making it the root class for all class hierarchies.
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
Properties are class attributes that together with methods form public class interface. Usually (but not always) properties are the values and references to other objects that are required to be entered in environment designer prior to workflow invocation.
|
||||
|
||||
Properties have the following declaration format:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
propertyName:
|
||||
Contract: property contract
|
||||
Usage: property usage
|
||||
Default: property default
|
||||
|
||||
Contract
|
||||
^^^^^^^^
|
||||
|
||||
Contracts are YAQL expressions that say what type of value is expected for the property as well as additional constraints imposed on the property.
|
||||
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| Operation | Definition |
|
||||
+===========================================================+=================================================================================================+
|
||||
| $.int() | integer value (may be null). String values that consist of digits would be converted to integer|
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| $.int().notNull() | mandatory integer |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| | $.string() | the same for strings. If the supplied value is not a string it will be converted to string |
|
||||
| | $.string().notNull() | |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| | $.bool() | bools are true and false. 0 is converted to false, other integers to true |
|
||||
| | $.bool().notNull() | |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| | $.class(ns:ClassName) | value must be a reference to an instance of specified class name |
|
||||
| | $.class(ns:ClassName).notNull() | |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| $.class(ns:ClassName, ns:DefaultClassName) | create instance of ns:DefaultClassName class if no instance provided |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| $.class(ns:Name).check($.p = 12) | value must be of type ns:Name and have a property 'p' equal to 12 |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| | [$.int()] | array of integers. Similar for other types |
|
||||
| | [$.int().notNull()] | |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| [$.int().check($ > 0)] | array of positive integers (thus not null) |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| [$.int(), $.string()] | array that has at least two elements, first is int and others are strings |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| | [$.int(), 2] | | array of ints with at least 2 items |
|
||||
| | [$.int(), 2, 5] | | ... and maximum of 5 items |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| { A: $.int(), B: [$.string()] } | dictionary with 'A' key of type int and 'B' - array of strings |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| | $ | any scalar or data structure as is |
|
||||
| | [] | any array |
|
||||
| | {} | any dictionary |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| { $.string().notNull(): $.int().notNull() } | dictionary string -> int |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| | A: StringMap | dictionary with 'A' key that must be equal to 'StringMap' and other keys be any scalar or data |
|
||||
| | $.string().notNull(): $ | structure |
|
||||
+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
|
||||
Usage
|
||||
^^^^^
|
||||
|
||||
Usage states purpose of the property. This implies who and how can access it. The following usages are available:
|
||||
|
||||
=========== ==================================================================================================================================================
|
||||
Property Explanation
|
||||
=========== ==================================================================================================================================================
|
||||
``In`` Input property. Values of such properties are obtained from user and cannot be modified in MuranoPL workflows. This is default value for Usage key
|
||||
``Out`` The value is obtained from executing MuranoPL workflow and cannot be modified by the user
|
||||
``InOut`` Value can be edited by both user and workflow
|
||||
``Const`` The same as In but once workflow is executed the property cannot be changed neither by user not the workflow
|
||||
``Runtime`` Property is visible only from within workflows. It neither read from input neither serialized to workflow output
|
||||
=========== ==================================================================================================================================================
|
||||
|
||||
Usage attribute is optional and can be omitted (which implies In).
|
||||
|
||||
If the workflow tries to write to a property that is not declared with one of the types above it is considered to be private and accessible only to that class (and not serialized to output and thus would be lost upon next deployment). Attempt to read property that wasn't initialized causes exception to be thrown.
|
||||
|
||||
Default
|
||||
^^^^^^^
|
||||
|
||||
Default is a value that would be used if the property value wasn't mentioned in input object model (but not when it is provided as null). Default (if specified) must conform to declared property contract. If Default is not specified then null is the default.
|
||||
|
||||
For properties that are references to other classes Default can modify default values for referenced value. For example
|
||||
::
|
||||
|
||||
p:
|
||||
Contract: $.class(MyClass)
|
||||
Default: {a: 12}
|
||||
|
||||
would override default for 'a' property of MyClass for instance of MyClass that is created for this property.
|
||||
|
||||
Workflow
|
||||
--------
|
||||
|
||||
Workflows are the methods that together describe how the entities that are represented by MuranoPL classes are deployed.
|
||||
|
||||
In typical scenario root object in input data model is of type io.murano.Environment and has a "deploy" method. Invoking this method causes a series of infrastructure activities (typically by modifying Heat stack) and VM agents commands that cause execution of deployment scripts. Workflow role is to map data from input object model (or result of previously executed actions) to parameters of those activities and to initiate those activities in correct order.
|
||||
Methods have input parameters and can return value to the caller.
|
||||
Methods defined in Workflow section of the class using the following template:
|
||||
|
||||
::
|
||||
|
||||
methodName:
|
||||
Arguments:
|
||||
- list
|
||||
- of
|
||||
- arguments
|
||||
Body:
|
||||
- list
|
||||
- of
|
||||
- instructions
|
||||
|
||||
Arguments are optional and (if specified) declared using the same syntax as class properties except for Usage attribute that is meaningless for method parameters. E.g. arguments also have a contract and optional default.
|
||||
|
||||
Method body is an array of instructions that got executed sequentially. There are 3 types of instructions that can be found in workflow body: expressions, assignment and block constructs.
|
||||
|
||||
Expressions
|
||||
^^^^^^^^^^^
|
||||
|
||||
Expressions are YAQL expressions that are executed for their side effect. All accessible object methods can be called in expression using $obj.methodName(arguments) syntax.
|
||||
|
||||
+-------------------------------------------+----------------------------------------------------------------+
|
||||
| Expression | Explanation |
|
||||
+===========================================+================================================================+
|
||||
| | ``$.methodName()`` | invoke method 'methodName' on this (self) object |
|
||||
| | ``$this.methodName()`` | |
|
||||
+-------------------------------------------+----------------------------------------------------------------+
|
||||
| | ``$.property.methodName()`` | invocation of method on object that is in 'property' property |
|
||||
| | ``$this.property.methodName()`` | |
|
||||
+-------------------------------------------+----------------------------------------------------------------+
|
||||
| ``$.method(1, 2, 3)`` | methods can have arguments |
|
||||
+-------------------------------------------+----------------------------------------------------------------+
|
||||
| ``$.method(1, 2, thirdParameter => 3)`` | named parameters also supported |
|
||||
+-------------------------------------------+----------------------------------------------------------------+
|
||||
| ``list($.foo().bar($this.property), $p)`` | complex expressions can be constructed |
|
||||
+-------------------------------------------+----------------------------------------------------------------+
|
||||
|
||||
|
||||
Assignment
|
||||
^^^^^^^^^^
|
||||
|
||||
Assignments are single-key dictionaries with YAQL expression as key and arbitrary structure as a value. Such construct evaluated as assignment.
|
||||
|
||||
+--------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| Assignment | Explanation |
|
||||
+================================+=================================================================================================+
|
||||
| ``$x: value`` | assigns ‘value’ to local variable $x |
|
||||
+--------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| ``$.x: value`` | assign value to object’s property |
|
||||
| ``$this.x: value`` | |
|
||||
+--------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| ``$.x: $.y`` | copy value of property 'y' to property 'x' |
|
||||
+--------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| ``$x: [$a, $b]`` | sets $x to array of 2 values $a and $b |
|
||||
+--------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| | ``$x:`` | structures of any level of complexity can be evaluated |
|
||||
| | ``SomeKey:`` | |
|
||||
| | ``NestedKey: $variable`` | |
|
||||
+--------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| ``$.x[0]: value``` | assign value to a first array entry of property x |
|
||||
+--------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| ``$.x.append(): value`` | append value to array in property x |
|
||||
+--------------------------------+------------------------------+------------------------------------------------------------------+
|
||||
| ``$.x.insert(1): value`` | insert value into position 1 |
|
||||
+--------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
| | ``$.x.key.subKey: value`` | deep dictionary modification |
|
||||
| | ``$.x[key][subKey]: value`` | |
|
||||
+--------------------------------+-------------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
Block constructs
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Block constructs control program flow. Block constructs are dictionaries that have strings as all its keys.
|
||||
The following block constructs are available:
|
||||
|
||||
+---------------------------------+----------------------------------------------------------------------------------------+
|
||||
| Assignment | Explanation |
|
||||
+=================================+========================================================================================+
|
||||
| ``Return: value`` | return value from a method |
|
||||
+---------------------------------+----------------------------------------------------------------------------------------+
|
||||
| | ``If: predicate()`` | predicate() is YAQL expressions that must be evaluated to true or false. |
|
||||
| | ``Then:`` | |
|
||||
| | ``- code`` | else part is optional |
|
||||
| | ``- block`` | |
|
||||
| | ``Else:`` | one-line code blocks can be written as a scalars rather than array. |
|
||||
| | ``- code`` | |
|
||||
| | ``- block`` | |
|
||||
+---------------------------------+----------------------------------------------------------------------------------------+
|
||||
| | ``While: predicate()`` | predicate() must be evaluated to true or false |
|
||||
| | ``Do:`` | |
|
||||
| | ``- code`` | |
|
||||
| | ``- block`` | |
|
||||
+---------------------------------+----------------------------------------------------------------------------------------+
|
||||
| | ``For: variableName`` | collection must be YAQL expression returning iterable collection or |
|
||||
| | ``In: collection`` | evaluatable array as in assignment instructions (like [1, 2, $x]) |
|
||||
| | ``Do:`` | |
|
||||
| | ``- code`` | inside code block loop variable is accessible as $variableName |
|
||||
| | ``- block`` | |
|
||||
+---------------------------------+----------------------------------------------------------------------------------------+
|
||||
| | ``Repeat:`` | repeat code block specified number of times |
|
||||
| | ``Do:`` | |
|
||||
| | ``- code`` | |
|
||||
| | ``- block`` | |
|
||||
+---------------------------------+----------------------------------------------------------------------------------------+
|
||||
| Break: | breaks from loop |
|
||||
+---------------------------------+----------------------------------------------------------------------------------------+
|
||||
| | ``Match:`` | matches result of $valueExpression() against set of possible values (cases). |
|
||||
| | ``case1:`` | the code block of first matched cased is executed. |
|
||||
| | ``- code`` | |
|
||||
| | ``- block`` | if not case matched and Default key is present (it is optional) |
|
||||
| | ``case2:`` | than Default code block get executed. |
|
||||
| | ``- code`` | case values are constant values (not expressions) |
|
||||
| | ``- block`` | |
|
||||
| | ``Value: $valueExpression()`` | |
|
||||
| | ``Default:`` | |
|
||||
| | ``- code`` | |
|
||||
| | ``- block`` | |
|
||||
+---------------------------------+----------------------------------------------------------------------------------------+
|
||||
| | ``Switch:`` | all code blocks that have their predicate evaluated to true are executed but the order |
|
||||
| | ``$predicate1() :`` | of predicate evaluation is not fixed |
|
||||
| | ``- code`` | |
|
||||
| | ``- block`` | |
|
||||
| | ``$predicate2() :`` | |
|
||||
| | ``- code`` | |
|
||||
| | ``- block`` | |
|
||||
| | ``Default:`` | default key is optional. |
|
||||
| | ``- code`` | |
|
||||
| | ``- block`` | if no predicate evaluated to true than Default code block get executed. |
|
||||
+---------------------------------+----------------------------------------------------------------------------------------+
|
||||
| | ``Parallel:`` | executes all instructions in code block in separate green threads in parallel |
|
||||
| | ``- code`` | |
|
||||
| | ``- block`` | |
|
||||
| | ``Limit: 5`` | limit is optional and means the maximum number of concurrent green threads. |
|
||||
+---------------------------------+----------------------------------------------------------------------------------------+
|
||||
|
||||
Object model
|
||||
------------
|
||||
|
||||
Object model is JSON-serialized representation of objects and their properties. Everything user does in environment builder (dashboard) is reflected in object model. Object model is sent to App Catalog engine upon user decides to deploy built environment. On engine side MuranoPL objects are constructed and initialized from received Object model and predefined method is executed on a root object.
|
||||
|
||||
|
||||
Objects serialized to JSON using the following template:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{
|
||||
"?": {
|
||||
"id": "globally unique object ID (UUID)",
|
||||
"type": "fully namespace-qualified class name",
|
||||
|
||||
"optional designer-related entries can be placed here": {
|
||||
"key": "value"
|
||||
}
|
||||
},
|
||||
|
||||
"classProperty1": "propertyValue",
|
||||
"classProperty2": 123,
|
||||
"classProperty3": ["value1", "value2"],
|
||||
|
||||
"reference1": {
|
||||
"?": {
|
||||
"id": "object id",
|
||||
"type": "object type"
|
||||
},
|
||||
|
||||
"property": "value"
|
||||
},
|
||||
|
||||
"reference2": "referenced object id"
|
||||
}
|
||||
|
||||
Objects can be identified as dictionaries that contain "?" entry. All system fields are hidden in that entry.
|
||||
|
||||
There are 2 ways to specify references. The first method ("reference1" in example above) allow inline definition of object. When instance of referenced object is created outer object becomes its parent (owner) that is responsible for the object. The object itself may require that its parent (direct or indirect) be of specified type (like all application require to have Environment somewhere in parent chain).
|
||||
|
||||
Second way to reference object is by specifying other object id. That object must be defined somewhere else in object tree. Object references distinguished from strings having the same value by evaluating property contracts. The former case would have $.class(Name) while the later $.string() contract.
|
@ -1,27 +0,0 @@
|
||||
..
|
||||
Copyright 2014 2014 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http//www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _MuranoPL Spec:
|
||||
|
||||
=====================================
|
||||
MuranoPL: Murano Programming Language
|
||||
=====================================
|
||||
|
||||
Content
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
|
||||
murano_pl
|
@ -1,114 +0,0 @@
|
||||
..
|
||||
Copyright 2014 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _class_definitions:
|
||||
|
||||
==================================
|
||||
Murano PL System Class Definitions
|
||||
==================================
|
||||
|
||||
Murano program language has system classes, which make deploying process as convenient as it could be.
|
||||
System classes are used in user class definitions for a custom applications. This article is going to help users to operate with Murano PL classes without any issues.
|
||||
All classes are located in the murano-engine component and don`t require particular import.
|
||||
|
||||
- :ref:`io.murano.system.Resources`
|
||||
- :ref:`io.murano.system.Agent`
|
||||
- :ref:`io.murano.system.AgentListener`
|
||||
- :ref:`io.murano.system.HeatStack`
|
||||
- :ref:`io.murano.system.InstanceNotifier`
|
||||
- :ref:`io.murano.system.NetworkExplorer`
|
||||
- :ref:`io.murano.system.StatusReporter`
|
||||
|
||||
.. _io.murano.system.Resources:
|
||||
|
||||
io.murano.system.Resources
|
||||
==========================
|
||||
Used to provide API to all files, located in the Resource directory of application package. Those Resources usually used in an application deployment and needed to be specified in a workflow definition.
|
||||
Available methods:
|
||||
|
||||
- *yaml* return resource file in yaml format
|
||||
- *string* return resource file as string
|
||||
- *json* return resource in json format
|
||||
|
||||
.. _io.murano.system.Agent:
|
||||
|
||||
io.murano.system.Agent
|
||||
======================
|
||||
Defines Murano Agent and ways of interacting with it.
|
||||
Available methods:
|
||||
|
||||
- *call(template, resources)* - send an execution plan template and resource object, and wait for an operation to complete
|
||||
- *send(template, resources)* - send execution plan template and resource class instance and continue execution without waiting for an end of the execution
|
||||
- *callRaw(plan)* - send ready-to-perform murano agent execution plan and wait for an operation to complete
|
||||
- *sendRaw(plan)* - send ready-to-perform murano agent execution plan and continue workflow execution
|
||||
- *queueName()* - returns name of the queue with which Agent is working
|
||||
|
||||
.. _io.murano.system.AgentListener:
|
||||
|
||||
io.murano.system.AgentListener
|
||||
==============================
|
||||
Used for monitoring Murano Agent.
|
||||
|
||||
- *start()* - start to monitor Murano Agent activity
|
||||
- *stop()* - stop to monitor Murano Agent activity
|
||||
- *subscribe(message_id, event)* - subscribe to the specified Agent event
|
||||
- *queueName()* - returns name of the queue with which Agent is working
|
||||
|
||||
.. _io.murano.system.HeatStack:
|
||||
|
||||
io.murano.system.HeatStack
|
||||
==========================
|
||||
Manage Heat stack operations.
|
||||
|
||||
- *current()* - returns current heat template
|
||||
- *parameters()* - returns heat template parameters
|
||||
- *reload()* - reload heat template
|
||||
- *setTemplate(template)* - load heat template
|
||||
- *updateTemplate(template)* - update current template with the specified part of heat stack
|
||||
- *output()* - result of heat template execution
|
||||
- *push()* - commit changes (requires after setTemplate and updateTemplate operations)
|
||||
- *delete()* - delete current heat stack
|
||||
|
||||
.. _io.murano.system.InstanceNotifier:
|
||||
|
||||
io.murano.system.InstanceNotifier
|
||||
=================================
|
||||
Monitor application and instance statistics to provide billing feature.
|
||||
|
||||
- *trackApplication(instance,* ``title``, ``unitCount``) - start to monitor an application activity; title, unitCount - are optional
|
||||
- *untrackApplication(instance)* - stop to monitor an application activity
|
||||
- *trackCloudInstance(instance)* - start to monitor an instance activity
|
||||
- *untrackCloudInstance(instance)* - stop to monitor an instance activity
|
||||
|
||||
.. _io.murano.system.NetworkExplorer:
|
||||
|
||||
io.murano.system.NetworkExplorer
|
||||
================================
|
||||
Determines and configures network topology.
|
||||
|
||||
- *getDefaultRouter()* - determine default router
|
||||
- *getAvailableCidr(routerId, netId)* - searching for non-allocated CIDR
|
||||
- *getDefaultDns()* - get dns from config file
|
||||
- *getExternalNetworkIdForRouter(routerId)* - Check for router connected to the external network
|
||||
- *getExternalNetworkIdForNetwork(networkId)* - For each router this network is connected to check whether the router has external_gateway set
|
||||
|
||||
.. _io.murano.system.StatusReporter:
|
||||
|
||||
io.murano.system.StatusReporter
|
||||
===============================
|
||||
Provides feedback feature. To follow the deployment process in the UI, all status changes should be included in the application configuration.
|
||||
|
||||
- *report(instance, msg)* - Send message about an application deployment process
|
||||
- *report_error(instance, msg)* - Report an error during an application deployment process
|
Loading…
Reference in New Issue
Block a user