Merge pull request #1 from Mirantis/KEERO-314

KEERO-314 - Fix all occurrences of old names (keero, glazier)
This commit is contained in:
Serg Melikyan 2013-04-25 00:42:20 -07:00
commit 3dd1b63a23
11 changed files with 594 additions and 594 deletions

View File

@ -1,8 +1,8 @@
Glazier Conductor README Murano Conductor README
======================== ========================
Conductor is an Glazier orchestration engine that transforms object model sent by Conductor is an Murano orchestration engine that transforms object model sent by
REST API service into a series of Heat and Glazier-Agent commands REST API service into a series of Heat and Murano-Agent commands
SEE ALSO SEE ALSO
-------- --------
* `Keero <http://keero.mirantis.com>`__ * `Murano <http://murano.mirantis.com>`__

View File

@ -1,7 +1,7 @@
#ps1 #ps1
$WindowsAgentConfigBase64 = '%WINDOWS_AGENT_CONFIG_BASE64%' $WindowsAgentConfigBase64 = '%WINDOWS_AGENT_CONFIG_BASE64%'
$WindowsAgentConfigFile = "C:\Keero\Agent\WindowsAgent.exe.config" $WindowsAgentConfigFile = "C:\Murano\Agent\WindowsAgent.exe.config"
$NewComputerName = '%INTERNAL_HOSTNAME%' $NewComputerName = '%INTERNAL_HOSTNAME%'
@ -9,12 +9,12 @@ $RestartRequired = $false
Import-Module CoreFunctions Import-Module CoreFunctions
Write-Log "Updating Keero Windows Agent." Write-Log "Updating Murano Windows Agent."
Stop-Service "Keero Agent" Stop-Service "Murano Agent"
Backup-File $WindowsAgentConfigFile Backup-File $WindowsAgentConfigFile
Remove-Item $WindowsAgentConfigFile -Force Remove-Item $WindowsAgentConfigFile -Force
ConvertFrom-Base64String -Base64String $WindowsAgentConfigBase64 -Path $WindowsAgentConfigFile ConvertFrom-Base64String -Base64String $WindowsAgentConfigBase64 -Path $WindowsAgentConfigFile
Exec sc.exe 'config','"Keero Agent"','start=','delayed-auto' Exec sc.exe 'config','"Murano Agent"','start=','delayed-auto'
Write-Log "Service has been updated." Write-Log "Service has been updated."
Write-Log "Renaming computer ..." Write-Log "Renaming computer ..."
@ -29,5 +29,5 @@ if ( $RestartRequired ) {
Restart-Computer -Force Restart-Computer -Force
} }
else { else {
Start-Service 'Keero Agent' Start-Service 'Murano Agent'
} }

View File

@ -7,7 +7,7 @@
"KeyName" : { "KeyName" : {
"Description" : "Name of an existing Amazon EC2 key pair for RDP access", "Description" : "Name of an existing Amazon EC2 key pair for RDP access",
"Type" : "String", "Type" : "String",
"Default" : "keero_key" "Default" : "murano-keys"
}, },
"InstanceType" : { "InstanceType" : {
"Description" : "Amazon EC2 instance type", "Description" : "Amazon EC2 instance type",

View File

@ -1,218 +1,218 @@
<workflow> <workflow>
<rule match="$.services.activeDirectories[?(@.domain)].units[?(not @.isMaster)]"> <rule match="$.services.activeDirectories[?(@.domain)].units[?(not @.isMaster)]">
<set path="domain"> <set path="domain">
<select path="::domain"/> <select path="::domain"/>
</set> </set>
</rule> </rule>
<rule match="$.services.activeDirectories[*].units[?(@.state.hostname and not @.state.instanceName)]"> <rule match="$.services.activeDirectories[*].units[?(@.state.hostname and not @.state.instanceName)]">
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id"/></parameter> <parameter name="id"><select path="id"/></parameter>
<parameter name="text">Creating instance <select path="name"/></parameter> <parameter name="text">Creating instance <select path="name"/></parameter>
</report> </report>
<update-cf-stack template="Windows"> <update-cf-stack template="Windows">
<parameter name="mappings"> <parameter name="mappings">
<map> <map>
<mapping name="instanceName"><select path="::name"/>-<select path="name"/></mapping> <mapping name="instanceName"><select path="::name"/>-<select path="name"/></mapping>
<mapping name="userData"> <mapping name="userData">
<prepare-user-data> <prepare-user-data>
<parameter name="hostname"><select path="state.hostname"/></parameter> <parameter name="hostname"><select path="state.hostname"/></parameter>
<parameter name="unit"><select path="name"/></parameter> <parameter name="unit"><select path="name"/></parameter>
<parameter name="service"><select path="::id"/></parameter> <parameter name="service"><select path="::id"/></parameter>
</prepare-user-data> </prepare-user-data>
</mapping> </mapping>
</map> </map>
</parameter> </parameter>
<parameter name="arguments"> <parameter name="arguments">
<map> <map>
<argument name="KeyName">keero-keys</argument> <argument name="KeyName">murano-keys</argument>
<argument name="InstanceType">m1.medium</argument> <argument name="InstanceType">m1.medium</argument>
<argument name="ImageName">ws-2012-full</argument> <argument name="ImageName">ws-2012-full</argument>
</map> </map>
</parameter> </parameter>
<success> <success>
<set path="state.instanceName"><select path="name"/></set> <set path="state.instanceName"><select path="name"/></set>
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id"/></parameter> <parameter name="id"><select path="id"/></parameter>
<parameter name="text">Instance <select path="name"/> created</parameter> <parameter name="text">Instance <select path="name"/> created</parameter>
</report> </report>
</success> </success>
</update-cf-stack> </update-cf-stack>
</rule> </rule>
<rule match="$.services.activeDirectories[*].units[?(@.state.instanceName and @.adminPassword and @.adminPassword != @.state.adminPassword)]"> <rule match="$.services.activeDirectories[*].units[?(@.state.instanceName and @.adminPassword and @.adminPassword != @.state.adminPassword)]">
<send-command template="SetPassword"> <send-command template="SetPassword">
<parameter name="host"> <parameter name="host">
<select path="name"/> <select path="name"/>
</parameter> </parameter>
<parameter name="service"> <parameter name="service">
<select path="::id"/> <select path="::id"/>
</parameter> </parameter>
<parameter name="mappings"> <parameter name="mappings">
<map> <map>
<mapping name="adminPassword"> <mapping name="adminPassword">
<select path="adminPassword"/> <select path="adminPassword"/>
</mapping> </mapping>
</map> </map>
</parameter> </parameter>
<success> <success>
<set path="state.adminPassword"> <set path="state.adminPassword">
<select path="adminPassword"/> <select path="adminPassword"/>
</set> </set>
</success> </success>
</send-command> </send-command>
</rule> </rule>
<rule match="$.services.activeDirectories[?(@.adminPassword and @.adminPassword != @.state.domainAdminPassword)].units[?(@.state.instanceName and @.isMaster)]"> <rule match="$.services.activeDirectories[?(@.adminPassword and @.adminPassword != @.state.domainAdminPassword)].units[?(@.state.instanceName and @.isMaster)]">
<send-command template="SetPassword"> <send-command template="SetPassword">
<parameter name="host"> <parameter name="host">
<select path="name"/> <select path="name"/>
</parameter> </parameter>
<parameter name="service"> <parameter name="service">
<select path="::id"/> <select path="::id"/>
</parameter> </parameter>
<parameter name="mappings"> <parameter name="mappings">
<map> <map>
<mapping name="adminPassword"> <mapping name="adminPassword">
<select path="::adminPassword"/> <select path="::adminPassword"/>
</mapping> </mapping>
</map> </map>
</parameter> </parameter>
<success> <success>
<set path="::state.domainAdminPassword"> <set path="::state.domainAdminPassword">
<select path="::adminPassword"/> <select path="::adminPassword"/>
</set> </set>
</success> </success>
</send-command> </send-command>
</rule> </rule>
<rule match="$.services.activeDirectories[?(@.state.primaryDc is None)].units[?(@.state.instanceName and @.isMaster)]"> <rule match="$.services.activeDirectories[?(@.state.primaryDc is None)].units[?(@.state.instanceName and @.isMaster)]">
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id"/></parameter> <parameter name="id"><select path="id"/></parameter>
<parameter name="text">Creating Primary Domain Controller on unit <select path="name"/></parameter> <parameter name="text">Creating Primary Domain Controller on unit <select path="name"/></parameter>
</report> </report>
<send-command template="CreatePrimaryDC"> <send-command template="CreatePrimaryDC">
<parameter name="host"> <parameter name="host">
<select path="name"/> <select path="name"/>
</parameter> </parameter>
<parameter name="service"> <parameter name="service">
<select path="::id"/> <select path="::id"/>
</parameter> </parameter>
<parameter name="mappings"> <parameter name="mappings">
<map> <map>
<mapping name="domain"> <mapping name="domain">
<select path="::domain"/> <select path="::domain"/>
</mapping> </mapping>
<mapping name="recoveryPassword"> <mapping name="recoveryPassword">
<select path="recoveryPassword"/> <select path="recoveryPassword"/>
</mapping> </mapping>
</map> </map>
</parameter> </parameter>
<success> <success>
<set path="::state.primaryDc"><select path="name"/></set> <set path="::state.primaryDc"><select path="name"/></set>
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id"/></parameter> <parameter name="id"><select path="id"/></parameter>
<parameter name="text">Primary Domain Controller created</parameter> <parameter name="text">Primary Domain Controller created</parameter>
</report> </report>
</success> </success>
</send-command> </send-command>
</rule> </rule>
<rule match="$.services.activeDirectories[?(@.state.primaryDc and not @.state.primaryDcIp)].units[?(@.state.instanceName and @.isMaster)]"> <rule match="$.services.activeDirectories[?(@.state.primaryDc and not @.state.primaryDcIp)].units[?(@.state.instanceName and @.isMaster)]">
<send-command template="AskDnsIp" result="ip"> <send-command template="AskDnsIp" result="ip">
<parameter name="host"> <parameter name="host">
<select path="name"/> <select path="name"/>
</parameter> </parameter>
<parameter name="service"> <parameter name="service">
<select path="::id"/> <select path="::id"/>
</parameter> </parameter>
<success> <success>
<set path="::state.primaryDcIp"> <set path="::state.primaryDcIp">
<select source="ip" path="0.Result.0"/> <select source="ip" path="0.Result.0"/>
</set> </set>
</success> </success>
</send-command> </send-command>
</rule> </rule>
<rule match="$..units[?(@.state.instanceName and @.domain and @.domain != @.state.domain)]"> <rule match="$..units[?(@.state.instanceName and @.domain and @.domain != @.state.domain)]">
<set path="#unit"> <set path="#unit">
<select/> <select/>
</set> </set>
<set path="#service"> <set path="#service">
<select path="::"/> <select path="::"/>
</set> </set>
<rule> <rule>
<parameter name="match">/$.services.activeDirectories[?(@.domain == '<select path="domain"/>' and @.state.primaryDcIp)]</parameter> <parameter name="match">/$.services.activeDirectories[?(@.domain == '<select path="domain"/>' and @.state.primaryDcIp)]</parameter>
<send-command template="JoinDomain"> <send-command template="JoinDomain">
<parameter name="host"> <parameter name="host">
<select path="name" source="unit"/> <select path="name" source="unit"/>
</parameter> </parameter>
<parameter name="service"> <parameter name="service">
<select path="id" source="service"/> <select path="id" source="service"/>
</parameter> </parameter>
<parameter name="mappings"> <parameter name="mappings">
<map> <map>
<mapping name="domain"> <mapping name="domain">
<select path="domain"/> <select path="domain"/>
</mapping> </mapping>
<mapping name="domainPassword"> <mapping name="domainPassword">
<select path="adminPassword"/> <select path="adminPassword"/>
</mapping> </mapping>
<mapping name="dnsIp"> <mapping name="dnsIp">
<select path="state.primaryDcIp"/> <select path="state.primaryDcIp"/>
</mapping> </mapping>
</map> </map>
</parameter> </parameter>
<success> <success>
<set path="state.domain" target="unit"> <set path="state.domain" target="unit">
<select path="domain"/> <select path="domain"/>
</set> </set>
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id" source="unit"/></parameter> <parameter name="id"><select path="id" source="unit"/></parameter>
<parameter name="text">Unit <select path="name" source="unit"/> has joined domain <select path="domain"/></parameter> <parameter name="text">Unit <select path="name" source="unit"/> has joined domain <select path="domain"/></parameter>
</report> </report>
</success> </success>
</send-command> </send-command>
</rule> </rule>
</rule> </rule>
<rule match="$.services.activeDirectories[*].units[?(@.state.domain and not @.isMaster and not @.state.installed)]"> <rule match="$.services.activeDirectories[*].units[?(@.state.domain and not @.isMaster and not @.state.installed)]">
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id"/></parameter> <parameter name="id"><select path="id"/></parameter>
<parameter name="text">Creating Secondary Domain Controller on unit <select path="name"/></parameter> <parameter name="text">Creating Secondary Domain Controller on unit <select path="name"/></parameter>
</report> </report>
<send-command template="CreateSecondaryDC"> <send-command template="CreateSecondaryDC">
<parameter name="host"> <parameter name="host">
<select path="name"/> <select path="name"/>
</parameter> </parameter>
<parameter name="service"> <parameter name="service">
<select path="::id"/> <select path="::id"/>
</parameter> </parameter>
<parameter name="mappings"> <parameter name="mappings">
<map> <map>
<mapping name="recoveryPassword"> <mapping name="recoveryPassword">
<select path="recoveryPassword"/> <select path="recoveryPassword"/>
</mapping> </mapping>
<mapping name="domainPassword"> <mapping name="domainPassword">
<select path="::adminPassword"/> <select path="::adminPassword"/>
</mapping> </mapping>
</map> </map>
</parameter> </parameter>
<success> <success>
<set path="state.installed"><true/></set> <set path="state.installed"><true/></set>
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id"/></parameter> <parameter name="id"><select path="id"/></parameter>
<parameter name="text">Secondary Domain Controller created</parameter> <parameter name="text">Secondary Domain Controller created</parameter>
</report> </report>
<report entity="service"> <report entity="service">
<parameter name="id"><select path="::id"/></parameter> <parameter name="id"><select path="::id"/></parameter>
<parameter name="text">Domain <select path="::domain"/> created</parameter> <parameter name="text">Domain <select path="::domain"/> created</parameter>
</report> </report>
</success> </success>
</send-command> </send-command>
</rule> </rule>
</workflow> </workflow>

View File

@ -1,19 +1,19 @@
<workflow> <workflow>
<rule match="$.services[*][*].units[?(@.state.hostname is None)]"> <rule match="$.services[*][*].units[?(@.state.hostname is None)]">
<set path="state.hostname"><generate-hostname/></set> <set path="state.hostname"><generate-hostname/></set>
</rule> </rule>
<rule match="$[?(not @.state.deleted)]"> <rule match="$[?(not @.state.deleted)]">
<rule match="$.services[*][*].units[*]"> <rule match="$.services[*][*].units[*]">
<empty> <empty>
<delete-cf-stack> <delete-cf-stack>
<success> <success>
<set path="/state.deleted"><true/></set> <set path="/state.deleted"><true/></set>
</success> </success>
</delete-cf-stack> </delete-cf-stack>
</empty> </empty>
</rule> </rule>
</rule> </rule>
</workflow> </workflow>

View File

@ -1,65 +1,65 @@
<workflow> <workflow>
<rule match="$.services.webServers[?(@.domain)].units[*]"> <rule match="$.services.webServers[?(@.domain)].units[*]">
<set path="domain"> <set path="domain">
<select path="::domain"/> <select path="::domain"/>
</set> </set>
</rule> </rule>
<rule match="$.services.webServers[*].units[?(@.state.hostname and not @.state.instanceName)]"> <rule match="$.services.webServers[*].units[?(@.state.hostname and not @.state.instanceName)]">
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id"/></parameter> <parameter name="id"><select path="id"/></parameter>
<parameter name="text">Creating instance <select path="name"/></parameter> <parameter name="text">Creating instance <select path="name"/></parameter>
</report> </report>
<update-cf-stack template="Windows"> <update-cf-stack template="Windows">
<parameter name="mappings"> <parameter name="mappings">
<map> <map>
<mapping name="instanceName"><select path="::name"/>-<select path="name"/></mapping> <mapping name="instanceName"><select path="::name"/>-<select path="name"/></mapping>
<mapping name="userData"> <mapping name="userData">
<prepare-user-data> <prepare-user-data>
<parameter name="hostname"><select path="state.hostname"/></parameter> <parameter name="hostname"><select path="state.hostname"/></parameter>
<parameter name="unit"><select path="name"/></parameter> <parameter name="unit"><select path="name"/></parameter>
<parameter name="service"><select path="::id"/></parameter> <parameter name="service"><select path="::id"/></parameter>
</prepare-user-data> </prepare-user-data>
</mapping> </mapping>
</map> </map>
</parameter> </parameter>
<parameter name="arguments"> <parameter name="arguments">
<map> <map>
<argument name="KeyName">keero-keys</argument> <argument name="KeyName">murano-keys</argument>
<argument name="InstanceType">m1.medium</argument> <argument name="InstanceType">m1.medium</argument>
<argument name="ImageName">ws-2012-full</argument> <argument name="ImageName">ws-2012-full</argument>
</map> </map>
</parameter> </parameter>
<success> <success>
<set path="state.instanceName"><select path="name"/></set> <set path="state.instanceName"><select path="name"/></set>
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id"/></parameter> <parameter name="id"><select path="id"/></parameter>
<parameter name="text">Instance <select path="name"/> created</parameter> <parameter name="text">Instance <select path="name"/> created</parameter>
</report> </report>
</success> </success>
</update-cf-stack> </update-cf-stack>
</rule> </rule>
<rule match="$.services.webServers[*].units[?(@.state.instanceName and not @.state.iisInstalled)]"> <rule match="$.services.webServers[*].units[?(@.state.instanceName and not @.state.iisInstalled)]">
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id"/></parameter> <parameter name="id"><select path="id"/></parameter>
<parameter name="text">Creating IIS Web Server on unit <select path="name"/></parameter> <parameter name="text">Creating IIS Web Server on unit <select path="name"/></parameter>
</report> </report>
<send-command template="InstallIIS"> <send-command template="InstallIIS">
<parameter name="host"> <parameter name="host">
<select path="name"/> <select path="name"/>
</parameter> </parameter>
<parameter name="service"> <parameter name="service">
<select path="::id"/> <select path="::id"/>
</parameter> </parameter>
<success> <success>
<set path="state.iisInstalled"><true/></set> <set path="state.iisInstalled"><true/></set>
<report entity="unit"> <report entity="unit">
<parameter name="id"><select path="id"/></parameter> <parameter name="id"><select path="id"/></parameter>
<parameter name="text">IIS <select path="name"/> has started</parameter> <parameter name="text">IIS <select path="name"/> has started</parameter>
</report> </report>
</success> </success>
</send-command> </send-command>
</rule> </rule>
</workflow> </workflow>

View File

@ -218,7 +218,7 @@ htmlhelp_basename = 'conductordoc'
# documentclass [howto/manual]). # documentclass [howto/manual]).
latex_documents = [ latex_documents = [
('index', 'Conductor.tex', u'Conductor Documentation', ('index', 'Conductor.tex', u'Conductor Documentation',
u'Keero Team', 'manual'), u'Murano Team', 'manual'),
] ]
# The name of an image file (relative to this directory) to place at the top of # The name of an image file (relative to this directory) to place at the top of

View File

@ -15,11 +15,11 @@
under the License. under the License.
======================================================= =======================================================
Welcome to Conductor, the Glazier orchestration engine! Welcome to Conductor, the Murano orchestration engine!
======================================================= =======================================================
Conductor is an Glazier orchestration engine that transforms object model sent by Conductor is an Murano orchestration engine that transforms object model sent by
REST API service into a series of Heat and Glazier-Agent commands REST API service into a series of Heat and Murano-Agent commands
This document describes Conductor for contributors of the project. This document describes Conductor for contributors of the project.
@ -31,20 +31,20 @@ Installation Guide
Install Install
------- -------
Check out sources to some directory (<home>/glazier): Check out sources to some directory (<home>/murano):
smelikyan@work:~/git clone ssh://<user>@gerrit.mirantis.com:29418/keero/keero.git smelikyan@work:~/git clone https://github.com/Mirantis/murano-conductor.git
Install Conductor: Install Conductor:
smelikyan@work:~/cd glazier/conductor && sudo python setup.py install smelikyan@work:~/cd murano/conductor && sudo python setup.py install
Configure Configure
--------- ---------
Open configuration file for editing: Open configuration file for editing:
smelikyan@work:~/cd glazier/conductor/etc && nano conductor.conf smelikyan@work:~/cd murano/conductor/etc && nano conductor.conf
Configure according to you environment: Configure according to you environment:
[DEFAULT] [DEFAULT]
@ -59,14 +59,14 @@ Configure
# this must be IP or hostname accessible from instances (VMs) # this must be IP or hostname accessible from instances (VMs)
host = YOUR.REAL.IP.HERE host = YOUR.REAL.IP.HERE
port = 5672 port = 5672
virtual_host = glazier virtual_host = murano
login = glazier login = murano
password = glazier password = murano
Run Run
---- ----
Run Conductor and supply valid configuration file: Run Conductor and supply valid configuration file:
smelikyan@work:~/cd glazier/conductor && conductor --config-file=./glazier/conductor/etc/conductor.conf smelikyan@work:~/cd murano/conductor && conductor --config-file=./murano/conductor/etc/conductor.conf

View File

@ -9,6 +9,6 @@ auth_url = http://172.18.124.101:5000/v2.0
[rabbitmq] [rabbitmq]
host = 172.18.124.101 host = 172.18.124.101
port = 5672 port = 5672
virtual_host = keero virtual_host = murano
login = keero login = murano
password = keero password = murano

View File

@ -1,171 +1,171 @@
# Copyright (c) 2013 Mirantis Inc. # Copyright (c) 2013 Mirantis Inc.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. # implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import json import json
import unittest import unittest
import mock import mock
import mockfs import mockfs
import heatclient.exc import heatclient.exc
from conductor.commands.cloud_formation import HeatExecutor from conductor.commands.cloud_formation import HeatExecutor
class TestHeatExecutor(unittest.TestCase): class TestHeatExecutor(unittest.TestCase):
def setUp(self): def setUp(self):
self.mfs = mockfs.replace_builtins() self.mfs = mockfs.replace_builtins()
template = { template = {
"$name": { "$name": {
"$key": "$value" "$key": "$value"
} }
} }
self.mfs.add_entries({ self.mfs.add_entries({
'./data/templates/cf/test.template': json.dumps(template)}) './data/templates/cf/test.template': json.dumps(template)})
def tearDown(self): def tearDown(self):
mockfs.restore_builtins() mockfs.restore_builtins()
def _init(self, config_mock, ksclient_mock): def _init(self, config_mock, ksclient_mock):
config_mock.heat.auth_url = 'http://invalid.url' config_mock.heat.auth_url = 'http://invalid.url'
auth_data = ksclient_mock().tokens.authenticate() auth_data = ksclient_mock().tokens.authenticate()
auth_data.id = '123456' auth_data.id = '123456'
auth_data.serviceCatalog = [{ auth_data.serviceCatalog = [{
'name': 'heat', 'name': 'heat',
'endpoints': [{'publicURL': 'http://invalid.heat.url'}] 'endpoints': [{'publicURL': 'http://invalid.heat.url'}]
}] }]
@mock.patch('heatclient.v1.client.Client') @mock.patch('heatclient.v1.client.Client')
@mock.patch('keystoneclient.v2_0.client.Client') @mock.patch('keystoneclient.v2_0.client.Client')
@mock.patch('conductor.config.CONF') @mock.patch('conductor.config.CONF')
def test_create_stack(self, config_mock, ksclient_mock, heat_mock): def test_create_stack(self, config_mock, ksclient_mock, heat_mock):
self._init(config_mock, ksclient_mock) self._init(config_mock, ksclient_mock)
executor = HeatExecutor('stack', 'token', 'tenant_id') executor = HeatExecutor('stack', 'token', 'tenant_id')
callback = mock.MagicMock() callback = mock.MagicMock()
executor.execute( executor.execute(
template='test', template='test',
command='CreateOrUpdate', command='CreateOrUpdate',
mappings={ mappings={
'name': 'testName', 'name': 'testName',
'key': 'testKey', 'key': 'testKey',
'value': 'testValue'}, 'value': 'testValue'},
arguments={ arguments={
'arg1': 'arg1Value', 'arg1': 'arg1Value',
'arg2': 'arg2Value'}, 'arg2': 'arg2Value'},
callback=callback) callback=callback)
heat_mock().stacks.get().stack_status = 'CREATE_COMPLETE' heat_mock().stacks.get().stack_status = 'CREATE_COMPLETE'
heat_mock().stacks.template = mock.MagicMock( heat_mock().stacks.template = mock.MagicMock(
side_effect=heatclient.exc.HTTPNotFound) side_effect=heatclient.exc.HTTPNotFound)
self.assertTrue(executor.has_pending_commands()) self.assertTrue(executor.has_pending_commands())
result = executor.execute_pending() result = executor.execute_pending()
self.assertTrue(result) self.assertTrue(result)
heat_mock().stacks.create.assert_called_with( heat_mock().stacks.create.assert_called_with(
stack_name='stack', stack_name='stack',
parameters={ parameters={
'arg1': 'arg1Value', 'arg1': 'arg1Value',
'arg2': 'arg2Value'}, 'arg2': 'arg2Value'},
template={ template={
"testName": { "testName": {
"testKey": "testValue" "testKey": "testValue"
} }
}) })
callback.assert_called_with(True) callback.assert_called_with(True)
@mock.patch('heatclient.v1.client.Client') @mock.patch('heatclient.v1.client.Client')
@mock.patch('keystoneclient.v2_0.client.Client') @mock.patch('keystoneclient.v2_0.client.Client')
@mock.patch('conductor.config.CONF') @mock.patch('conductor.config.CONF')
def test_update_stack(self, config_mock, ksclient_mock, heat_mock): def test_update_stack(self, config_mock, ksclient_mock, heat_mock):
self._init(config_mock, ksclient_mock) self._init(config_mock, ksclient_mock)
executor = HeatExecutor('stack', 'token', 'tenant_id') executor = HeatExecutor('stack', 'token', 'tenant_id')
callback = mock.MagicMock() callback = mock.MagicMock()
executor.execute( executor.execute(
template='test', template='test',
command='CreateOrUpdate', command='CreateOrUpdate',
mappings={ mappings={
'name': 'testName', 'name': 'testName',
'key': 'testKey', 'key': 'testKey',
'value': 'testValue'}, 'value': 'testValue'},
arguments={ arguments={
'arg1': 'arg1Value', 'arg1': 'arg1Value',
'arg2': 'arg2Value'}, 'arg2': 'arg2Value'},
callback=callback) callback=callback)
get_mock = heat_mock().stacks.get() get_mock = heat_mock().stacks.get()
get_mock.stack_name = 'stack' get_mock.stack_name = 'stack'
get_mock.id = 'stack' get_mock.id = 'stack'
get_mock.parameters = {} get_mock.parameters = {}
get_mock.stack_status = '' get_mock.stack_status = ''
get_mock._status_index = 0 get_mock._status_index = 0
def side_effect(*args, **kwargs): def side_effect(*args, **kwargs):
if get_mock._status_index < 2: if get_mock._status_index < 2:
get_mock.stack_status = 'IN_PROGRESS' get_mock.stack_status = 'IN_PROGRESS'
else: else:
get_mock.stack_status = 'UPDATE_COMPLETE' get_mock.stack_status = 'UPDATE_COMPLETE'
get_mock._status_index += 1 get_mock._status_index += 1
return get_mock return get_mock
heat_mock().stacks.get = mock.MagicMock(side_effect=side_effect) heat_mock().stacks.get = mock.MagicMock(side_effect=side_effect)
heat_mock().stacks.template = mock.MagicMock( heat_mock().stacks.template = mock.MagicMock(
return_value={'instance': {}}) return_value={'instance': {}})
self.assertTrue(executor.has_pending_commands()) self.assertTrue(executor.has_pending_commands())
result = executor.execute_pending() result = executor.execute_pending()
self.assertTrue(result) self.assertTrue(result)
heat_mock().stacks.update.assert_called_with( heat_mock().stacks.update.assert_called_with(
stack_id='stack', stack_id='stack',
parameters={ parameters={
'arg1': 'arg1Value', 'arg1': 'arg1Value',
'arg2': 'arg2Value'}, 'arg2': 'arg2Value'},
template={ template={
'instance': {}, 'instance': {},
"testName": { "testName": {
"testKey": "testValue" "testKey": "testValue"
} }
}) })
callback.assert_called_with(True) callback.assert_called_with(True)
@mock.patch('heatclient.v1.client.Client') @mock.patch('heatclient.v1.client.Client')
@mock.patch('keystoneclient.v2_0.client.Client') @mock.patch('keystoneclient.v2_0.client.Client')
@mock.patch('conductor.config.CONF') @mock.patch('conductor.config.CONF')
def test_delete_stack(self, config_mock, ksclient_mock, heat_mock): def test_delete_stack(self, config_mock, ksclient_mock, heat_mock):
self._init(config_mock, ksclient_mock) self._init(config_mock, ksclient_mock)
executor = HeatExecutor('stack', 'token', 'tenant_id') executor = HeatExecutor('stack', 'token', 'tenant_id')
callback = mock.MagicMock() callback = mock.MagicMock()
executor.execute( executor.execute(
template='test', template='test',
command='Delete', command='Delete',
callback=callback) callback=callback)
heat_mock().stacks.get = mock.MagicMock( heat_mock().stacks.get = mock.MagicMock(
side_effect=heatclient.exc.HTTPNotFound) side_effect=heatclient.exc.HTTPNotFound)
self.assertTrue(executor.has_pending_commands()) self.assertTrue(executor.has_pending_commands())
result = executor.execute_pending() result = executor.execute_pending()
self.assertTrue(result) self.assertTrue(result)
heat_mock().stacks.delete.assert_called_with(stack_id='stack') heat_mock().stacks.delete.assert_called_with(stack_id='stack')
callback.assert_called_with(True) callback.assert_called_with(True)

View File

@ -1,99 +1,99 @@
# Copyright (c) 2013 Mirantis Inc. # Copyright (c) 2013 Mirantis Inc.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. # implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import json import json
import os import os
import unittest import unittest
import deep import deep
import mock import mock
import mockfs import mockfs
from conductor.workflow import Workflow from conductor.workflow import Workflow
def load_sample(name): def load_sample(name):
with mockfs.storage.original_open(os.path.join( with mockfs.storage.original_open(os.path.join(
os.path.dirname(__file__), os.path.dirname(__file__),
'sample_data', 'sample_data',
name)) as sample_file: name)) as sample_file:
return sample_file.read() return sample_file.read()
class TestWorkflow(unittest.TestCase): class TestWorkflow(unittest.TestCase):
def setUp(self): def setUp(self):
self.mfs = mockfs.replace_builtins() self.mfs = mockfs.replace_builtins()
self.model = json.loads(load_sample('objectModel1.json')) self.model = json.loads(load_sample('objectModel1.json'))
self.original_model = json.loads(load_sample('objectModel1.json')) self.original_model = json.loads(load_sample('objectModel1.json'))
def tearDown(self): def tearDown(self):
mockfs.restore_builtins() mockfs.restore_builtins()
def _execute_workflow(self, xml): def _execute_workflow(self, xml):
self.mfs.add_entries({'test': xml}) self.mfs.add_entries({'test': xml})
stub = mock.MagicMock() stub = mock.MagicMock()
stub.side_effect = RuntimeError stub.side_effect = RuntimeError
workflow = Workflow('test', self.model, stub, stub, stub) workflow = Workflow('test', self.model, stub, stub, stub)
workflow.execute() workflow.execute()
def test_empty_workflow_leaves_object_model_unchanged(self): def test_empty_workflow_leaves_object_model_unchanged(self):
xml = '<workflow/>' xml = '<workflow/>'
self._execute_workflow(xml) self._execute_workflow(xml)
self.assertIsNone(deep.diff(self.original_model, self.model)) self.assertIsNone(deep.diff(self.original_model, self.model))
def test_modifying_object_model_from_workflow(self): def test_modifying_object_model_from_workflow(self):
xml = ''' xml = '''
<workflow> <workflow>
<rule match="$.services[*][?(@.id == <rule match="$.services[*][?(@.id ==
'9571747991184642B95F430A014616F9' '9571747991184642B95F430A014616F9'
and not @.state.invalid)]"> and not @.state.invalid)]">
<set path="state.invalid">value</set> <set path="state.invalid">value</set>
</rule> </rule>
</workflow> </workflow>
''' '''
self.assertNotIn( self.assertNotIn(
'state', 'state',
self.model['services']['activeDirectories'][0]) self.model['services']['activeDirectories'][0])
self._execute_workflow(xml) self._execute_workflow(xml)
self.assertEqual( self.assertEqual(
self.model['services']['activeDirectories'][0]['state']['invalid'], self.model['services']['activeDirectories'][0]['state']['invalid'],
'value') 'value')
self.assertIsNotNone(deep.diff(self.original_model, self.model)) self.assertIsNotNone(deep.diff(self.original_model, self.model))
del self.model['services']['activeDirectories'][0]['state'] del self.model['services']['activeDirectories'][0]['state']
self.assertIsNone(deep.diff(self.original_model, self.model)) self.assertIsNone(deep.diff(self.original_model, self.model))
def test_selecting_properties_from_object_model_within_workflow(self): def test_selecting_properties_from_object_model_within_workflow(self):
xml = ''' xml = '''
<workflow> <workflow>
<rule match="$.services[*][?(@.id == <rule match="$.services[*][?(@.id ==
'9571747991184642B95F430A014616F9' '9571747991184642B95F430A014616F9'
and not @.test)]"> and not @.test)]">
<set path="test"> <set path="test">
Domain <select Domain <select
path="domain"/> with primary DC <select path="domain"/> with primary DC <select
path="units.0.name"/> path="units.0.name"/>
</set> </set>
</rule> </rule>
</workflow> </workflow>
''' '''
self._execute_workflow(xml) self._execute_workflow(xml)
self.assertEqual( self.assertEqual(
self.model['services']['activeDirectories'][0]['test'], self.model['services']['activeDirectories'][0]['test'],
'Domain acme.loc with primary DC dc01') 'Domain acme.loc with primary DC dc01')