The Atomia Automation Server configuration consists of creating and modifying the following parts:
Service Description - describes services the Atomia Automation Server can work with, relations between them and their limitations.
Resource Description - describes resources the Atomia Automation Server knows about, binding a resource with a specific module.
Package Description - describes service limitations.
NOTE : The package description and the service description are located in the same file - the Provisioning Description
The package description file is XML file that describes available packages in the system. File:
<packageDescription> <packageList> <package name="PackageName"> <serviceList> <service name="ServiceName"/> </serviceList> <serviceLimitationList/> <propertySettings/> </package> </packageList> <packageExtensionList/> </packageDescription>
packageDescription
is the root element of the file and has no attributes.
packageDescription
has two elements:
packageList
- list of packages available in system
packageExtensionList
- for each package, extensions could be defined.
packageList
is an element with no attributes and contains one or more package elements.
<packageList> <package name="PackageName"> <serviceList> <service name="ServiceName"/> </serviceList> <serviceLimitationList/> <propertySettings/> </package> </packageList>
package
defines the package itself. Attributes of this element are:
name
defines the package name. Is required.
friendlyName
defines a friendly package name. Is optional.
The value of the element is of type complex:
packageType
which is defined as:
<serviceList> <service name="ServiceName"/> </serviceList> <serviceLimitationList/> <propertySettings/>
serviceList
has not attributes. It could contain one or more service elements.
<service name="ServiceName" />
service
has an attribute name which is required.
serviceLimitationList
could contain zero or more
limitation
or
globalLimitation
elements.
<serviceLimitationList> <limitation serviceNamePath="/path/to/service" maxCount="50"> <globalLimitation> <group maxCount="0"> <service name="FirstService" /> </group> <group maxCount="5"> <service name="SecondService" /> </group> </globalLimitation> </serviceLimitationList>
For the
limitation
element two attributes are defined. A value is not allowed for this element. Attributes are:
serviceNamePath
- required attribute,
maxCount
- required attribute.
For
globalLimitation
element has no attributes.
globalLimitation
element can contain one or more
group
elements.
<globalLimitation> <group maxCount="0"> <service name="FirstService" /> </group> <group maxCount="5"> <service name="SecondService" /> </group> </globalLimitation>
group
element has one attribute:
maxCount
- required attribute
group
element contains one on more
service
elements(described above).
The propertySettings
element can contain zero or more
set
elements.
<propertySettings> <set servicePath="ServicePath" propertyName="" propertyValue ="" /> <propertySettings>
For the set element three attributes are defined. A value is not allowed for this element. Attributes are:
servicePath
- required attribute,
propertyName
- required attribute,
propertyValue
- required attribute.
packageExtensionList
has no attributes and contains a list of zero or more
packageExtension
elements.
<packageExtensionList> <packageExtension> <serviceList> <service name="ServiceName"/> </serviceList> <serviceLimitationList/> <propertySettings/> <extendsList> <extends name="extendsName"> </extendsList> </packageExtension> </packageExtensionList>
The packageExtension
element value is of type
packageType
described above.
extendsList
is a list of zero or more
extends
elements.
<extends name="extendsName" />
extends has an attribute name and no value could be assigned.
<packageDescription> <packageList> <package name="BasicWebHosting"> <serviceList> <service name="Hosting"/> </serviceList> <serviceLimitationList/> <propertySettings/> </package> </packageList> <packageExtensionList /> </packageDescription>
The resource description describes resources Atomia Automation Server knows about, where it will configure simple services and binds a resource with a specific module.
resourceDescription
is the root element and it has no attributes. It contains one or more
resourcesAndPolicies
elements.
<resourceDescription> <resourcesAndPolicies> <!-- ... --> </resourcesAndPolicies> </resourceDescription>
resourcesAndPolicies
has no attributes and contains a list of one or more services and their policies and related resources.
<resourcesAndPolicies> <serviceAndPolicyList> <!-- ... --> </serviceAndPolicyList> <resourceList> <!-- ... --> </resourceList> </resourcesAndPolicies>
serviceAndPolicyList
has no attributes and contains a list of one or more
service
elements. The
service
element defines a service name and the associated resource assignment policy.
<service name="IIS" resourceAsignmentPolicy="RoundRobin" />
service
element attributes are:
name
- service name. Required attribute.
resourceAsignmentPolicy
- defines which policy is used for the service.
Required attribute.
The resourceList
element has not attributes and contains a list of one or more resource elements.
<resource name="IISWebServer1"> <property name="IPAddress">212.200.163.10</property> <property name="ServerName">s10.troxo.com</property> </resource>
resource
element has the following attributes:
name
- defines a resource name and is a
required
attribute.
resource
also has one or more
property
elements that define resource properties.
<property name="IPAddress">212.200.163.10</property> <property name="ServerName">s10.troxo.com</property>
property
elements have a
name
attribute to identify a property. The body of this element defines a property value.
Note | |
---|---|
Changes made to resource description file won't be visible until the Provisioning service is restarted. |
Example of a resource description is:
<resourceDescription> <resourcesAndPolicies> <serviceAndPolicyList> <service name="IIS" resourceAsignmentPolicy="RoundRobin"/> </serviceAndPolicyList> <resourceList> <resource name="IISWebServer1"> <property name="IPAddress">212.200.163.10</property> <property name="ServerName">s10.troxo.com</property> </resource> <resource name="IISWebServer2"> <property name="IPAddress">212.200.163.11</property> <property name="ServerName">s11.troxo.com</property> </resource> <resource name="IISWebServer3"> <property name="IPAddress">212.200.163.12</property> <property name="ServerName">s12.troxo.com</property> </resource> </resourceList> </resourcesAndPolicies> <resourcesAndPolicies> <serviceAndPolicyList> <service name="Dns" resourceAsignmentPolicy="SpecificResource"/> </serviceAndPolicyList> <resourceList> <resource name="PrimaryDNS"> <property name="IPAddress">212.200.163.2</property> <property name="ServerName">ns1.troxo.com</property> </resource> <resource name="SecondaryDNS"> <property name="IPAddress">212.200.163.4</property> <property name="ServerName">ns2.troxo.com</property> </resource> </resourceList> </resourcesAndPolicies> <resourcesAndPolicies> <serviceAndPolicyList> <service name="Ftp" resourceAsignmentPolicy="SpecificResource"/> </serviceAndPolicyList> <resourceList> <resource name="FtpServer"> <property name="IPAddress">212.200.163.20</property> <property name="ServerName">120.troxo.com</property> </resource> </resourceList> </resourcesAndPolicies> </resourceDescription>
In this example we can see that IIS service can be located on 3 resources: IISWebServer1 , IISWebServer2 and IISWebServer3 . Each of those resources are described with two properties:
IPAddress
ServerName
The ist of properties can be custom for any group of similar resources. From this example we can see that
RoundRobin
resource assignment policy will be used for IIS services. In the resource description, it is enough to define the resource policy and available resources for a root simple service. All child simple services are by convention located on the same resource as their parent.
The resource description file consists of a list of bindings. Each binding has a list of modules and a list of resources. All services from one module can be provisioned to the resources listed within the binding their module belongs to:
Bindings section
Module list section
Resource list section
<resourceDescription> <bindings> <moduleList> ... </moduleList> <resourceList> ... </resourceList> </bindings> ... <bindings> <moduleList> ... </moduleList> <resourceList> ... </resourceList> </bindings>
As stated before, each resource description consists of a list of
bindings
sections. Each
bindings
section provides a list of modules,
moduleList
, and a list of resources,
resourceList
. Modules from the list can provision their services only to the resources from the
resourceList
within same
bindings
section.
<resourceDescription> <bindings> <moduleList> <module name="Atomia.Example.Module1" ... /> <module name="Atomia.Example.Module2" ... /> <module name="Atomia.Example.Module3" ... /> </moduleList> <resourceList> <resource name="Resource1" ... /> <resource name="Resource2" ... /> </resourceList> </bindings> ...
Each
module
section represents one provisioning module. Each module must have a name and a resource assignment policy. The attribute
name
should be the full name of the class which represents the Atomia Automation Server module,
Namespace
.
ClassName
. Which resource, if more then one, is going to be selected as a host for the service is determined by the resource assignment policy being used for the specific module. The attribute
resourceAsignmentPolicy
determines the resource assignment policy. The Atomia Automation Server system uses this information when deciding which Resource Assignment Policy agent should be evoked.
An example of a module configuration:
<resourceDescription> <bindings> <moduleList> <module name="Atomia.Provisioning.Examples.IIS" resourceAsignmentPolicy="RoundRobin" /> </moduleList> ... </bindings> ...
Section
resource
represents one resource in the system which can host services created by the Provisioning system. Each resource has a name and a list of properties. This properties are used so that resource can be easily accessed, i.e. MSSQL server has address, username and password as properties. Attribute
locckable
tells whether resource can be accessed by multiple threads simultaneously. Default value is false. Each resource can also have
propertyList
which represents grouped properties.
An example of resource configuration:
<resourceDescription> <bindings> ... <resourceList> <resource name="MSSQL1"> <property name="DatabaseServer">192.168.0.1</property> <property name="PublicIpAddress">10.0.2.10</property> <property name="User">admin_user</property> <property name="Password">p@ssw0rd</property> <property name="InitialCatalog">master</property> <property name="AdminIpAddress">10.0.2.11</property> </resource> </resourceList> </bindings> ...
ResourceDescriptionExample represents an example of a full, working, resource description file.
The Service Description is an XML document describing services that the Atomia Automation Server can work with, relations between services and their limitations. The Service Description uses the Provisioning Description Schema . Together with the Package Description it forms a Provisioning description file.
The Service description has two parts:
Simple service description section.
Complex service description section.
Example:
<provisioningDescription xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <servicesDescription> <simpleServiceList> ... </simpleServiceList> <complexServiceList> ... </complexServiceList> </servicesDescription> ... </provisioningDescription>
This is a simplified view of a fully functional IIS website in a real environment and represented as a composite service
A service description has exactly one ([1..1])
simpleServiceList
element. This element has no attributes.
The element
simpleServiceList
can have one or more ([1..*])
simpleService
elements. Each of these elements represents one Simple Service.
<simpleService name="Name" friendlyName="FriendlyName" providingModule="ModuleName" min="0" max="4294967296" hidden="true" noSave="true" />
Simple Service attributes:
name
-
Required attribute
. Name of the simple service. Must be unique. Accepted value is any combination of alphanumeric characters.
friendlyName
- Friendly name of the service. Accepted values are all alphanumeric and special characters except
XML special characters
.
providingModule
- Name of the module that can provide and manage services on a resource. Although this property is not required for each simple service element, root simple services must have this property set. All
child services
are provisioned by the same module so there is no need to set this property for them. The accepted value is the full name of the provisioning module in the format:
Namespace.ModuleName
.
min
- Minimum number of this service that can occur in a parent service. Accepted values are unsigned int. Default value is
0
.
max
- Maximum number of this service that can occur in a parent service. Accepted values are unsigned int. By default maximum number is unlimited.
hidden
- If set to true, service will not be visible outside the Atomia Automation Server core. Accepted value is of boolean type. Default value is
false
.
noSave
- If set to true, service is not saved in the Atomia Automation Server database. Control of this type of service is managed completely by modules. These types of services are called
DirectProvisioned services
. Accepted value is of boolean type. Default value is
false
.
Each simple service can a have maximum of one property list ([0..1]) containing properties that are needed for creating the service. The XML tag that describes this is
propertyList
:
<simpleService name="Name" providingModule="ModuleName"> <propertyList> <property name="PropertyNameForService" /> <propertyList> <!-- ... --> </propertyList> </propertyList> </simpleService>
propertyList
element does not have any specific attributes. It can appear zero or one ([\0..1]) times per service.
propertyList
element has list of none or many ([0..*])
property
elements.
Element
property
has following attributes:
<simpleService name="Name" providingModule="ModuleName"> <propertyList> <property name="PropertyNameForService" friendlyName="PropertyFriendlyName" storeType="store" defaultValue="" key="false" allowDefaultOverride="false" required="true" log="true" /> <propertyList> </simpleService>
name
-
Required attribute
. Property name. It must be unique per service. Accepted values are all alphanumeric characters.
friendlyName
- Friendly name of the service property. Used to display name of the property to the user. Accepted value are all alphanumeric and special characters except
XML special characters
.
storeType
- Determines how property value should be stored. It could be stored in its original form, encrypted or even not stored. Accepted values are:
store
,
encrypt
and
noStore
. Default value is
store
.
defaultValue
- Property default value. Accepted values are all alphanumeric and special characters except
XML special characters
. If this value is set user will not be asked for this property value.
key
- Determine if this property is key property for service. Service could have one or more key properties. If two services have the same values for key properties then we are considered to be same service. It is used to determine if two logical services should point to the same physical service. Accepted values are of boolean type. Default value is
false
.
allowDefaultOverride
- Tells whether it is possible to override default value of the service property, if it exists. Accepted values are of boolean type. Default value is false. This property is not counted unless
defaultValue
is set.
required
- Tells whether this property is required. Value for service properties which has
required
set to
true
must be provided. Accepted values are of boolean type. Default value is
false
.
log
- Tells whether this property's value should be written to the Atomia Provisioning log. Accepted values are of boolean type. Default value is
true
.
Transforms input value of the service property as described in the
inputValueTransformation
element. Expressions used for describing transformation are
Atomia Provisioning Element Transformations
. Each service property can have ([0..1]) of this elements as child elements.
<simpleService name="Name" providingModule="ModuleName"> <propertyList> <property name="PropertyNameForService" > <inputValueTransformation>literal\.+$Service::Property</inputValueTransformation> </property> <propertyList> </simpleService>
Each simple service can have maximum one list ([0..1]) of service operations which can be called for that service. When called, this operations are executed on specific instance of Atomia Provisioning service. XML tag that describes this is
operationList
:
<simpleService name="Name" providingModule="ModuleName"> ... <operationList> ... </operationList> ... </simpleService>
operationList
element does not have any specific attributes. It can appear zero or one ([\0..1]) time per service.
operationList
element has list of none or many ([0..*])
operation
elements.
The element
operation
has the following attributes:
<simpleService name="Name" providingModule="ModuleName"> ... <operationList> <operation name="Start" /> <operation name="Stop" /> <operation name="Pause" /> </operationList> ... </simpleService>
name
- Name of service operation. It must be unique per service. Accepted values are alphanumeric characters.
Each simple service can have zero or one list ([0..1]) of childSimpleServices. The XML tag that describes this is
childSimpleServices
:
<simpleService name="ParentName" providingModule="ModuleName"> <propertyList> <property name="PropertyNameForService" /> </propertyList> <childSimpleServices> <simpleService name="ChildName" providingModule="ModuleName"> </simpleService> </childSimpleServices> </simpleService>
There are no specific attributes for this element. Every simple service can have children which must be of type simple service. A simple service can have a recursive structure (for example simple service "Folder" can have child "Folder"). Example:
<simpleService name="WebSite" providingModule="WebSiteModule"> <childServiceList> <simpleService name="Folder"> <propertyList> <param name="DirName" /> </propertyList> <childServiceList> <simpleService name="Folder"></simpleService> </childServiceList> </simpleService> </childServiceList> </simpleService>
Each simple service can have zero or one list ([0..1]) of
actionHooks
element. This element has no attributes.
The element
actionHooks
can have zero or more ([0..*]) of
onBeforeAddService
or
onSwitchService
elements. This elements have the following attributes:
<simpleService name="VirtualDir"> ... <actionHooks> <onBeforeAddService type="Namespace.Type, Assembly" argument="Argument" /> </actionHooks> </simpleService>
Action hooks contain logic which can be executed on different events which occur in the provisioning process. Currently, available events are
onBeforeAddService
and
onSwitchService
.
type
-
Required attribute
. Full name of the type which represents an action hook. Accepted values are full names of the classes representing action hook.
argument
-
Required attribute
. Action hook argument. Accepted values are alpha numeric characters.
The service description file can contain multiple composite services. Simple services are services that are provisioned on a single resource and are not dependent of other services. They serve as building blocks for composite services.
Composite services are services composed of one or many services, not necessarily provisioned on a single resource. We describe composite service using:
list of properties
list of possible child services (part services and part instances)
list of services that are initially added on composite service creation
Example of a composite service description:
<complexService name="FtpSupport" friendlyName="FTP" systemUnique="true"> <complexServicePropertyList> <complexServiceProperty name="FtpSupportProperty" /> </complexServicePropertyList> <partList> <partService name="Storage" max="1" min="1"> </partService> <partService name="FTP"> <propertyTransformation> <simpleTransformer> <serviceProperty name="HomeDir"> <expression>\\\\#Instance(FtpStorageInstance).Resource.ServerName+\\+#Instance(FtpStorageInstance)::Path</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </partService> <partServiceInstance name="FTPAccunt" condition="\\\\#Instance(FtpStorageInstance).Resource.ServerName eq SomeValue" instanceName="FTPAcc"> <propertyTransformation> <simpleTransformer> <serviceProperty name="Name"> <expression>\\\\#Instance(FtpStorageInstance).Resource.ServerName+_acc</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </partServiceInstance> </partList> <init> <add partName="Storage" instanceName="FtpStorageInstance" canDelete="false" canEdit="false"> <initPropertyList> <propertyTransformation> <simpleTransformer> <serviceProperty name="Path"> <expression>\\users\\UserName</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </initPropertyList> </add> </init> </complexService>
Composite service element attributes:
name
- Gives a name to the service. Must be unique. Required attribute. Accepted value are any of the anySimpleType.
friendlyName
- Friendly name of the service. Attribute not required. Accepted value are any of the anySimpleType.
systemUnique
- Accepted type - boolean. Default value false.
A composite can have a list of properties. The list of properties is defined by:
<complexServicePropertyList> <complexServiceProperty name="ZoneName" /> <complexServiceProperty name="Subdomain" /> <complexServiceProperty name="Port" /> <complexServiceProperty name="ASPLocaleID" /> <complexServiceProperty name="LoggingType" /> </complexServicePropertyList>
The element complexServicePropertyList has no attributes.
Each property is defined by element
complexServiceProperty
.
<complexServiceProperty name="ZoneName" friendlyName="PropertyFriendlyName" defaultValue="PropertyDefaultValue" store="true" key="false" />
Attributes are:
name
- Composite service unique property name. Required attribute.
friendlyName
- Composite service user friendly property name. Optional attribute.
defaultValue
- Default value for property. Accepted data type - string.
store
- Determines if this property value will be stored in the database. Default attribute value - true. Accepted data type - boolean.
key
- Optional. Default value - false. Accepted data type boolean. Decalres property as a composite service key property.
A composite service child service is defined either with the element
partService
or
partServiceInstance
. The relation between a composite child service and its parent service is whole-part. This means that a composite service is defined by its set of services.
<partList> <partService name="partServiceName" min="" max="1" canAddSame="" equivalenceCriteriaParams=""> </partService> <partServiceInstance name="FTPAccunt" condition="\\\\#Instance(FtpStorageInstance).Resource.ServerName eq SomeValue" instanceName="FTPAcc"> </partServiceInstance> </partList>
A composite service may have zero or one time ([0..1]) partList elements. The partList element has no attributes.
The partService attribute is used for describing the child service. partList must have one or more ([1..*]) partService elements.
<partService name="partServiceName" min="0" max="12323" canAddSame="true" equivalenceCriteriaParams=""></partService>
partService
attributes are:
name
- Name of the simple or complex service defined above. Required attribute. Accepted type is alphanumeric
string
.
min
- Minimum number of service appearance in parent. Optional attribute.
max
- Maximum number of service appearance in parent. Optional attribute.
canAddSame
- Determines if user can add the same service more than once(compares to other services in the same complex service instance). Default value
true
. Accepted data type -
boolean
. Optional attribute.
equivalenceCriteriaParams
- List of properties name separated with ";" that defines what service properties must have the same value to be able to declare services as the same. Optional attribute.
condition
- If set, holds expression that is used to check if certain part service type can be added. Optional attribute. Accepted data type -
string
. Expressions are
Atomia Provisioning Element Transformations
.
forcePropertiesUpdate
- If this property is set system will schedule part service for update even if there are no changes to service properties. Useful when complex service property is expected to be changed after some other service property is updated by module, or any other Automation Server plug-in. Optional attribute. Accepted data type -
boolean
. Default value -
false
.
deletePriority
- Used to specify priority order for deletion. Parts with higher priority will be deleted first. Optional attribute. Accepted data type -
uint
. Default value -
0
.
partService
, if part is of type of simple service, it can also have a child part list. This structure must match the simple service structure. A
partService
that is type of composite service defines its parts in the composite service definition.
Child service defined as
partServiceInstance
is added when condition, described in
condition
attribute is met. Condition is evaluated whenever a service, involved in the condition, is being added, modified or deleted. Once a condition value becomes false, all partServiceInstance, owners of the condition, will be deleted.
partServiceInstance
attributes are:
name
- Name of the simple or complex service defined above. Required attribute. Accepted data type is alphanumeric
string
.
condition
- If set, holds expression that is used to check if certain part service type can be added. Optional attribute. Accepted data type -
string
. Expressions are
Atomia Provisioning Element Transformations
.
instanceName
- Instance name. Name used to distinguish this type of part service instance. Accepted data type is alphanumeric
string
.
deletePriority
- Used to specify priority order for deletion. Parts with higher priority will be deleted first. Optional attribute. Accepted data type -
uint
. Default value -
0
.
Composite service initialization consists of services that need to be initially added when the composite service is created. They are described with element the
init
.
<init> <add partName="Storage" instanceName="StorageInstance" canDelete="false" canEdit="false"> ... </add> </init>
The init
element has no attributes. It always has one or more ([1..*])
add
elements.
<add partName="Storage" instanceName="StorageInstance" canDelete="false" canEdit="false" instanceName="partNameInstanceName"> <initPropertyList> <propertyTransformation> <simpleTransformer> <serviceProperty name="Path"> <expression>\\users\\UserName</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </initPropertyList> </add>
The add
element attributes are:
partName
- Defines
partService
name. Required attribute. Accepted data type -
string
.
canDelete
- Determines if this
partService
instance can be deleted. Optional attribute. Default value -
true
.
canEdit
- Determines if this
partService
instance can be edited. Optional attribute. Default value -
true
.
instanceName
- Used for later referencing of this instance by some part other part in composite service initialization. Optional attribute. Accepted data type -
string
condition
- Defines condition which must be met in order to initialy add part service. Expressions used for describing transformation are
Atomia Provisioning Element Transformations
. Default value is an empty string.
The add
element can have zero or one ([0..1])
initPropertyList
elements. It is used to initialize a list of properties for the service instance.
<initPropertyList/>
initPropertyList
can have ([0..1])
initProperty
elements. They are used to initialize service instance properties with fixed values, instead of assigning property values using property transformation.
<initProperty name="propertyName" value="propertyValue"/>
The initProperty
value has the following attributes:
name
- Property name. Required attribute.
value
- Property value. Required attribute.
initPropertyList
can have ([0..1])
propertyTransformation
elements describing how a parent composite service property value will be transformed to this service property value.
<propertyTransformation> <simpleTransformer> <serviceProperty name="Subdomain"> <expression>$WindowsSite::Subdomain</expression> </serviceProperty> </simpleTransformer> </propertyTransformation>
propertyTransformation
has not attributes.
propertyTransfromation
must have one or more ([1..
])simpleTransformer
elements that describe the transformation process.simpleTransformer
does not have attributes but has one or more ([1..
])
serviceProperty
elements.
<serviceProperty name="Subdomain"> <expression>$WindowsSite::Subdomain</expression>
simpleTransformer
is a property transformer. The transformation is defined with the element
serviceProperty. }}It defines what service property value in the current service will be transformed. The {{expression
element that defines how it will be transformed.
<complexServiceList> <complexService name="WebSite"> <complexServicePropertyList> <complexServiceProperty name="Domain" /> </complexServicePropertyList> <partList> <partService name="DnsZone"> <propertyTransformation> <simpleTransformer> <serviceProperty name="Domain"> <expression>www\.+$WebSite::Domain</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </partService> </partList> </complexService> </complexServiceList>
serviceProperty
describes the property value transformation for a specific property. The
name
attribute is required.
The expression
element defines an expression that will be used for the property value transformation.
<serviceName>$<serviceName>::<paramName>+<text>!Instance(<instanceName>)::<paramName> !Instance(<instanceName>)::!Resource.<ResourceProperty>
The provisioning description file consists of:
Service Description section
Package Description section
System hooks section
<provisioningDescription xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../ProvisioningDescription.xsd"> <servicesDescription> ... </servicesDescription> <packageDescription> ... </packageDescription> <systemHooks> ... </systemHooks> </provisioningDescription>
The service description file have contain a description for one or more simple services , but it can also contain subsections about complex services .
The structure of the service description is given in the following example:
<provisioningDescription> <servicesDescription> <simpleServiceList> <!-- List of available simple service descriptions. --> </simpleServiceList> <complexServiceList> <!-- List of available complex service descriptions. --> </complexServiceList> </servicesDescription> ... </provisioningDescription>
The simple service structure looks like this:
<simpleService name="SimpleService" friendlyName="Simple service example" providingModule="Atomia.Provisioning.Modules.ExampleModule"> <propertyList> <!-- List of simple service properties. --> </propertyList> <operationList> <!-- List of operations which can be executed on this type of simple service. --> </operationList> <childServiceList> <!-- List of child simple services. --> </childServiceList> <actionHooks> <!-- Registered action hooks for this type of service. --> </actionHooks> </simpleService>
Let's say we want to describe the simple service
IISApplicationPool
. Its description should look like something like this:
<simpleService name="IISApplicationPool" friendlyName="IIS Application Pool" providingModule="Atomia.Provisioning.Modules.IIS.IIS7" min="1"> <propertyList> <property name="Name" friendlyName="Application Pool Name" defaultValue="" key="true" /> <property name="Username" friendlyName="Application Pool User" defaultValue="" key="true" /> <property name="Password" friendlyName="Application Pool User's Password" defaultValue="" storeType="encrypt" log="false" /> </propertyList> <operationList> <operation name="GenerateSSLRequest" /> </operationList> </simpleService>
Here we have defined one simple service, added some properties and marked properties
Name
and
Username
as key properties. Also, this service has one operation:
GenerateSSLRequest
.
Let's now say that we have a service called
IISWebSite
. This service is a child of
IISApplicationPool
and we want to describe this relationship using the service description. This is very simple to do. A complete
IISWebSite
service description should be added under the
childServiceList
subsection of the
IISApplicationPool
service:
<simpleService name="IISApplicationPool" friendlyName="IIS Application Pool" providingModule="Atomia.Provisioning.Modules.IIS.IIS7" min="1"> <propertyList> <property name="Name" friendlyName="Application Pool Name" defaultValue="" key="true" /> <property name="Username" friendlyName="Application Pool User" defaultValue="" key="true" /> <property name="Password" friendlyName="Application Pool User's Password" defaultValue="" storeType="encrypt" log="false" /> </propertyList> <operationList> <operation name="GenerateSSLRequest" /> </operationList> <childServiceList> <simpleService name="IISWebSite" friendlyName="IIS Web Site" providingModule="Atomia.Provisioning.Modules.IIS.IIS7"> <propertyList> <property name="Name" friendlyName="Web site name" key="true" /> <property name="HomeDirectory" friendlyName="Home Direcotory" /> <property name="ConnectionTimeout" friendlyName="Connection Timeout" defaultValue="00:02:00" /> <property name="MaximumBandwidth" friendlyName="Maximum Bandwidth" defaultValue="104857600" /> </propertyList> <operationList> <operation name="Start" /> <operation name="Stop" /> </operationList> </simpleService> </childServiceList> </simpleService>
If the simple service should not have a parent service then its description must be placed in the
simpleServiceList
subsection. Each child service description must be placed in the appropriate parent's
childServiceList
subsection.
A complex service represents a group of services which are not directly provisioned on a resource. It consists of part services which are grouped together to represent one logical unit. A complex service has the following structure:
<complexService name="ComplexService" friendlyName="Complex service example"> <complexServicePropertyList> <!-- List of complex service properties --> </complexServicePropertyList> <partList> <!-- List of part services which form this complex service --> <partList> <init> <!-- Initialization section. When complex service is added, this section must be executed too, i.e. add some part services with predefined property values. --> </init> <actionHooks> <!-- Registered action hooks for this type of service. --> </actionHooks> </complexService>
A basic implementation of the complex service could look like this:
<complexService name="CsWindowsBinding" friendlyName="IIS website binding"> <complexServicePropertyList> <complexServiceProperty name="Sitename" friendlyName="Site to bind to" /> <complexServiceProperty name="Hostname" friendlyName="Binding Hostname" key="true" /> <complexServiceProperty name="DnsZone" friendlyName="DNS Zone to add binding to" /> </complexServicePropertyList> <partList> <partService name="IISApplicationPool" equivalenceCriteriaParams="Name" min="1" max="1"> <partList> <partService name="IISWebSite" min="1" max="1" equivalenceCriteriaParams="Name"> </partService> </partList> </partService> </partList> <init> ... </init> </complexService>
The example above shows a complex service
CsWindowsBinding
with a part service
IISApplicationPool
and one child part service
IISWebSite
. One important feature must be explained here. Simple child services are declared and defined directly under the
childServiceList
subsection of the parent owner service. Part services of a complex service are defined outside of the
partList
subsection where they are just referenced with their parent-child, whole-part relations preserved. In the given example, it is assumed that
IISApplicationPool
and its child service are defined outside of the
partList
subsection. This means that
IISApplicationPool
could not be a subpart of the
IISWebSite
service, since later it is the child service of the
IISApplicationPool
. Part services can also be other complex services, but they too must be defined outside the
partList
subsection. Basically, there are no child complex services. All complex services are root service, but can be referenced as part services of another complex service. The consequence of this is that root part services can only be complex services or root simple services.
Part service property values can be transformed using Atomia Provisioning Element Transformations .
Example of
partList
subsection:
<complexService name="CsWindowsBinding" friendlyName="IIS website binding"> ... <partList> <partService name="IISApplicationPool" equivalenceCriteriaParams="Name" min="1" max="1"> <propertyTransformation> <simpleTransformer> <serviceProperty name="Name"> <expression>#Account()+AppPool</expression> </serviceProperty> <serviceProperty name="Username"> <expression>#Account()</expression> </serviceProperty> <serviceProperty name="Password"> <expression>$CsWindowsBinding::ADPassword</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> <partList> <partService name="IISWebSite" min="1" max="1" equivalenceCriteriaParams="Name"> <propertyTransformation> <simpleTransformer> <serviceProperty name="Name"> <expression>$CsWindowsBinding::Sitename</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </partService> </partList> </partService> </partList> ... </complexService>
The subsection
init
defines part service instances that should be added when an owner complex service is added. It is possible to predefine service property values and patterns for these values using
Atomia Provisioning Element Transformations
. During the addition of part services, Atomia Provisioning will use these transformations to calculate part service property values. Note that part services must keep their parent-child, whole-part structure here also.
Here is an example of the complex service
init
subsection for the above example:
<complexService name="CsWindowsBinding" friendlyName="IIS website binding"> ... <init> <add partName="IISApplicationPool" instanceName="CsWindowsBindingAppPoolInstance"> <initPropertyList> <propertyTransformation> <simpleTransformer> <serviceProperty name="Name"> <expression>$CsWindowsBinding::Hostname</expression> </serviceProperty> <serviceProperty name="Username"> <expression>#Account()+AppPool</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </initPropertyList> <add partName="IISWebSite"> <initPropertyList> <propertyTransformation> <simpleTransformer> <serviceProperty name="Name"> <expression>$CsWindowsBinding::Hostname</expression> </serviceProperty> <serviceProperty name="HomeDirectory"> <expression>\/mnt\/content\/+$CsLinuxWebsite::Sitename</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </initPropertyList> </add> <add partName="IISWebSite"> <initPropertyList> <propertyTransformation> <simpleTransformer> <serviceProperty name="Name"> <expression>$CsWindowsBinding::Hostname</expression> </serviceProperty> <serviceProperty name="HomeDirectory"> <expression>\/mnt\/content\/+$CsLinuxWebsite::Sitename+\.preview</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </initPropertyList> </add> </add> </init> </complexService>
The difference between the
partList
and
init
subsections is that the former describes the complex service structure, that is, it describes how the complex service is structured and what its parts are. Later on, it provides a tree of part service instances which must be added when the complex service owner is added.
The package description section describes available packages and package extensions in the system.
The basic structure of the package description looks like this:
<provisioningDescription> ... <packageDescription> <packageList> <!-- List of available packages. --> </packageList> <packageExtensionList> <!-- List of available package extensions. --> </packageExtensionList> </packageDescription> </provisioningDescription>
A package represents a group of services that are available for adding to an account. It also sets limitations on the number of allowed service instances.
Each package consists of the following subsections:
<package name="ExamplePackage"> <serviceList> <!-- List of services which form the package --> </serviceList> <serviceLimitationList> <!-- List of limitations per service. --> </serviceLimitationList> <propertySettings> <!-- Property values settings for specific services. --> </propertySettings> <init> <!-- Package initialization section. --> </init> <disable> <!-- List of package disable scripts --> </disable> <actionHooks> <!-- List of action hooks per package. --> </actionHooks> </package>
The following example shows a basic package description:
<package name="PremiumPackage"> <serviceList> <service name="CsBase" /> <service name="CsWindowsBinding" /> </serviceList> <serviceLimitationList> <globalLimitation> <group maxCount="1"> <service name="CsBase" /> </group> <group maxCount="1"> <service name="CsDomainRegList" /> </group> </globalLimitation> </serviceLimitationList> <init> <arguments> <argument serviceName="CsBase" propertyName="InitMasterFtpAccount" propertyValue="true" /> </arguments> <serviceToAdd serviceName="CsBase"> <propertyInitList> <property servicePropertyName="ADPassword" valueSource="ADPassword" /> <property servicePropertyName="PosixUid" valueSource="PosixUid" /> <property servicePropertyName="FtpPassword" valueSource="FtpPassword" /> <property servicePropertyName="RootFolderParentPath" valueSource="RootFolderParentPath" /> </propertyInitList> </serviceToAdd> </init> </package>
The subsection
serviceList
lists all services that can be added, as root services, for an account that has this instance of this package enabled. The consequence of this is that the list can be populated only with complex services and root simple services.
The number of available service instances can easily be limited by using the
serviceLimitationList
section. In this section, each service type, which can be provisioned (it doesn't need to be a complex or root simple service), can be limited in number of existing instances per account.
Just like a complex service, a package can also have an
init
section. This section is the same as for a complex service. It is used to initialize package instances when it is being added.
Let's take a look at a more complex package example:
<package name="PremiumPackage"> <serviceList> <service name="CsBase" /> <service name="CsWindowsBinding" /> </serviceList> <disable> <scriptList> <script name="Disable"> <serviceList> <service path="CsBase/CsWindowsWebsite/IISApplicationPool/IISWebSite" action="modify" > <propertyList> <property name="HomeDirectory" newValue="/mnt/content/suspended/public_html" /> </propertyList> </service> <service path="CsBase/CsLinuxWebsite/LiteSpeedWebSite" action="modify" > <propertyList> <property name="HomeDirectory" newValue="/mnt/content/suspended/public_html" /> </propertyList> </service> <service path="*/FTPAccount" action="modify" > <propertyList> <property name="Status" newValue="0" /> </propertyList> </service> </serviceList> </script> </scriptList> </disable> <actionHooks> <onBeforeChangePackage argument="BasePackage,PremiumPackage" type="Atomia.Provisioning.Example.ActionHook, Atomia.Provisioning.Example"/> </actionHooks> </package>
In the previous example, focus was on the
disable
subsection. This section defines a list of scripts which can be used to disable a package instance.
The Atomia Automation Server allows a package to be extended. For each package extension it is possible to define a list of services that will be enabled with this extension. Package extensions also allow package limitations per service to be overridden. It is also possible to set certain service property values.
The package extension structure is shown in the following example:
<packageExtension name="ExamplePackageExtension"> <serviceList> <!-- List of services which have been enabled by activating extension. --> </serviceList> <serviceLimitationList> <!-- List of limitations per service. --> </serviceLimitationList> <propertySettings> <!-- Property values settings for specific services. --> </propertySettings> <init> <!-- Package extension initialization section. --> </init> <disable> <!-- List of package extension disable scripts --> </disable> <extendsList> <!-- List of packages that can be extended by this extension. --> </extendsList> </packageExtension>
Common package extensions looks like this:
<packageExtension name="ExamplePackageExtension"> <serviceLimitationList> <globalLimitation> <group maxCount="1" name="SampleLimitation"> <service name="ExampleService" /> </group> </globalLimitation> </serviceLimitationList> <extendsList> <extends name="ExamplePackage" /> <extends name="PremiumExamplePackage" /> </extendsList> </packageExtension>
ProvisioningDescriptionExample represents a full, working, example of a provisioning description file. It can be used as a starting point for creating new provisioning descriptions.
Atomia Provisioning element transformations allow the one who writes the provisioning description to use expressions in order to transform service property values. There are two types of transformations:
Parameter value transformations
Input property value transformations
Parameter value transformations are used to define expressions used for generating part service property values. They can be used when part services are defined within a complex service or within the initialization section of a complex service .
Transformation expressions can be composed of literals, special characters, service property values, service resource properties and account properties.
Special characters:
+ - String concatenation:
<serviceProperty name="Dir"> <!-- in this expression, value of the property after the transformation will be 'abcdef' --> <expression>abc+def</expression> </serviceProperty>
$ - Provisioning service selector. When put before a literal, the system will assume the literal to be a complex service name. It is used to access the complex service owner of the part service. This literal cannot be the name of the simple service but rather a complex service. To access the parent simple service use the service path special character / as in the following example:
<serviceProperty name="Label"> <!-- in this expression, value of the property DomainPrefix of the CsMailSupport complex service is used as a value for the Label property. --> <expression>$CsMailSupport::DomainPrefix</expression> </serviceProperty> <serviceProperty name="Data"> <!-- in this example, simple service MailService is part service of the CsMailSupport and parent service for the service, owner of the Data property. --> <!-- value of the DomainData property of the MailService service is used as a value for the Data property. --> <expression>$CsMailSupport/MailService::DomainData</expression> </serviceProperty>
/ - Service path. Used for constructing service paths in expressions.
<serviceProperty name="Label"> <!-- in this expression, value of the property DomainPrefix of the CsMailSupport complex service is used as a value for the Label property. --> <expression>$CsMailSupport/$MailDomain/$MailService::DomainPrefix</expression> </serviceProperty>
:: - Parent complex service property accessor, used for accessing service property values. It allows you to include parent complex service property in expression values.
<serviceProperty name="Label"> <!-- in this expression, value of the property DomainPrefix of the CsMailSupport complex service is used as a value for the Label property. --> <expression>$CsMailSupport::DomainPrefix</expression> </serviceProperty>
. - This character is used for accessing properties or resource properties of a specific service instance (check list of key words below).
<serviceProperty name="Data"> <!-- MailDomainInstance is the name of the service instance, property of which is going to be used. --> <expression>#Instance(MailDomainInstance).MailIpAddress</expression> </serviceProperty>
\ - Escape character. Used for escaping all special characters.
<serviceProperty name="Path"> <expression>\\public_html\\index\.html</expression> </serviceProperty>
( and ) - Used when creating complex expressions to force evaluation order, just as in any programming language.
<serviceProperty name="Path"> <expression>($CsMailSupport::DomainPrefix and $CsMailSupport::Name) eq (some_value)</expression> </serviceProperty>
Operators
Used for expressions that should represent some kind of condition.
and
- Logical
and
operator.
or
- Logical
or
operator.
eq - Equality operator.
neq - Not-equal operator.
lt - Lower then operator.
gt - Greater then operator.
le - Less or equal operator.
ge - Greater or equal operator.
<serviceProperty name="Path"> <expression>($CsMailSupport::IsActive and $CsMailSupport::IsComplex) eq ($CsMailSupport::StatusFlag or "true")</expression> </serviceProperty>
.. - Parent service operator. Used when constructing service paths in expressions. It has similar meaning as "../" in folder path, that is, it tells system to go one service up in the service hierarchy.
<serviceProperty name="Path"> <expression>$../../$CsWebSite::Name</expression> </serviceProperty>
Keywords
#Instance() - If there is more than one child in the service instances that appears in the service path, the service path cannot be successfully resolved and in that case the "instance name" should be used. It accesses a specific service instance in order to get its property values as needed for the value transformation. This keyword acts as a command and requires one argument to be passed. This argument is the name of the instance, property of which are needed:
<add partName="MailDomain" instanceName="MailDomainInstance"> ... <add partName="DnsZoneRecord" > <initPropertyList> <propertyTransformation> <simpleTransformer> <serviceProperty name="Data"> <expression>#Instance(MailDomainInstance).Resource.MailIpAddress</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </initPropertyList> </add> </add>
#Account() - Represents account id, owner of the service.
null
- Keyword
null
represents null value.
Input value transformations are used to transform service property values the moment when they are specified. Expressions are written in the same manner as for property value transformations.
<simpleService name="Name" providingModule="ModuleName"> <propertyList> <property name="PropertyNameForService" > <inputValueTransformation>literal\.+$Service::Property</inputValueTransformation> </property> <propertyList> </simpleService>
Expressions use service path whenever a service property value is needed. Service path system is very similar to directory paths. Generally speaking, there are two types of service paths:
Absolute path - Path begins with
/
. First service in the path must be root service.
<serviceProperty name="SomeProperty"> <expression>/$RootComplexService/$ComplexService2/$SimpleServiceRoot2/$SecondChild1::ChildProperty1</expression> </serviceProperty>
Relative path - Path begins with service name. By default, all service paths are treated as if the begin from the complex service owner (in example below that is
ComplexServiceOwner
). Complex service owner is a complex service that "owns" part service description, for which we are calculating expression (see example below). In case that path begins with
$this
service path is evaluated starting with service for which expression is evaluated (in example below that is
ServiceWithExpressions
).
<complexService name="ComplexServiceOwner"> <complexServicePropertyList> <complexServiceProperty name="CProp1" storeType="encrypt"/> </complexServicePropertyList> <partList> <partService name="ServiceWithExpressions"> <propertyTransformation> <simpleTransformer> <serviceProperty name="SRootProp1"> <expression>$ComplexServiceOwner::CProp1</expression> </serviceProperty> <serviceProperty name="SRootProp2"> <expression>$../::CProp1</expression> </serviceProperty> <serviceProperty name="SRootProp3"> <expression>$this/$../$../SomeOtherService::CProp1</expression> </serviceProperty> </simpleTransformer> </propertyTransformation> </partService> </partList> </complexService>
A service name in service path can be described in following forms:
Concrete service name (type 1) - i.e. $ComplexService1 (in this case, system will try to find service
ComplexService1
as child service of the current service in the path).
$this (type 2) - represents service for which expression is evaluated.
$.. (type 3) - represents parent service of the current service in the path.
$Instance
(type 4) - works similar as
#Instance
keyword. Finds child service with given instance name.
In case of concrete service names and instance names (types 1 and 4) it is possible to additional specify service by setting properties to filter:
<serviceProperty name="ChildProperty2"> <expression>$../$ComplexService1/$Instance(Ins1)/$FirstChild[ChildProperty1="value1"]::ChildProperty1</expression> </serviceProperty> or <serviceProperty name="ChildProperty2"> <expression>$../$ComplexService1/$Instance(Ins1[InstanceProperty1="value1"])::InstanceProperty1</expression> </serviceProperty>