diff --git a/data/init.ps1 b/data/init.ps1
index 790b65e..b522123 100644
--- a/data/init.ps1
+++ b/data/init.ps1
@@ -10,6 +10,16 @@ $MuranoFileShare = '\\%MURANO_SERVER_ADDRESS%\share'
$RestartRequired = $false
Import-Module CoreFunctions
+Initialize-Logger 'CloudBase-Init' 'C:\Murano\PowerShell.log'
+
+$ErrorActionPreference = 'Stop'
+
+trap {
+ Write-LogError ''
+ Write-LogError $_ -EntireObject
+ Write-LogError ''
+ exit 1
+}
Write-Log "Updating Murano Windows Agent."
Stop-Service "Murano Agent"
@@ -25,7 +35,8 @@ Write-Log "Adding environment variable 'MuranoFileShare' = '$MuranoFileShare' ..
Write-Log "Environment variable added."
Write-Log "Renaming computer to '$NewComputerName' ..."
-Rename-Computer -NewName $NewComputerName | Out-Null
+$null = Rename-Computer -NewName $NewComputerName -Force
+
Write-Log "New name assigned, restart required."
$RestartRequired = $true
diff --git a/data/templates/agent/SqlServerCluster/FailoverCluster.template b/data/templates/agent/SqlServerCluster/FailoverCluster.template
index b30c9ac..cf13598 100644
--- a/data/templates/agent/SqlServerCluster/FailoverCluster.template
+++ b/data/templates/agent/SqlServerCluster/FailoverCluster.template
@@ -15,16 +15,6 @@
"UserPassword": "$domainAdminAccountPassword",
"StaticAddress": "$clusterIP"
}
- },
- {
- "Name": "New-FailoverClusterSharedFolder",
- "Arguments": {
- "ClusterName": "$clusterName",
- "UserName": "$domainAdminAccountName",
- "UserPassword": "$domainAdminAccountPassword",
- "ShareServer": "$shareServer",
- "DomainName": "$domainName"
- }
}
],
"RebootOnCompletion": 0
diff --git a/data/templates/agent/scripts/DeployWebApp.ps1 b/data/templates/agent/scripts/DeployWebApp.ps1
index 8c4ca69..5dd90f4 100644
--- a/data/templates/agent/scripts/DeployWebApp.ps1
+++ b/data/templates/agent/scripts/DeployWebApp.ps1
@@ -10,13 +10,13 @@ Function Register-WebApp {
http://www.iis.net/learn/manage/powershell/powershell-snap-in-creating-web-sites-web-applications-virtual-directories-and-application-pools
#>
- param (
- [String] $Source,
- [String] $Path = "C:\inetpub\wwwroot",
- [String] $Name = "",
- [String] $Username = "",
- [String] $Password = ""
- )
+ param (
+ [String] $Source,
+ [String] $Path = "C:\inetpub\wwwroot",
+ [String] $Name = "",
+ [String] $Username = "",
+ [String] $Password = ""
+ )
begin {
Show-InvocationInfo $MyInvocation
}
@@ -28,70 +28,74 @@ http://www.iis.net/learn/manage/powershell/powershell-snap-in-creating-web-sites
&$TrapHandler
}
- Import-Module WebAdministration
-
- if ($Name -eq "") {
- $Name = @([IO.Path]::GetDirectoryName($Source) -split '\\')[-1]
- if ($Name -eq "wwwroot") {
- throw("Application pool name couldn't be 'wwwroot'.")
- }
- }
- else {
- $Path = [IO.Path]::Combine($Path, $Name)
- }
+ Import-Module WebAdministration
- Copy-Item -Path $Source -Destination $Path -Recurse -Force
-
+ if ($Name -eq "") {
+ $Name = @([IO.Path]::GetDirectoryName($Source) -split '\\')[-1]
+ if ($Name -eq "wwwroot") {
+ throw("Application pool name couldn't be 'wwwroot'.")
+ }
+ }
+ else {
+ $Path = [IO.Path]::Combine($Path, $Name)
+ }
- # Create new application pool
- $AppPool = New-WebAppPool -Name $Name -Force
- #$AppPool = Get-Item "IIS:\AppPools\$Name"
- $AppPool.managedRuntimeVersion = 'v4.0'
- $AppPool.managedPipelineMode = 'Classic'
- $AppPool.processModel.loadUserProfile = $true
- $AppPool.processModel.logonType = 'LogonBatch'
-
- #Set Identity type
- if ($Username -eq "") {
- $AppPool.processModel.identityType = 'ApplicationPoolIdentity'
- }
- else {
- $AppPool.processModel.identityType = 'SpecificUser'
- $AppPool.processModel.userName = $Username
- $AppPool.processModel.password = $Password
- $AppPool | Set-Item
- }
+ $null = Copy-Item -Path $Source -Destination $Path -Recurse -Force
+
+ # Create new application pool
+ $AppPool = New-WebAppPool -Name $Name -Force
+ #$AppPool = Get-Item "IIS:\AppPools\$Name"
+ $AppPool.managedRuntimeVersion = 'v4.0'
+ $AppPool.managedPipelineMode = 'Classic'
+ $AppPool.processModel.loadUserProfile = $true
+ $AppPool.processModel.logonType = 'LogonBatch'
+
+ #Set Identity type
+ if ($Username -eq "") {
+ $AppPool.processModel.identityType = 'ApplicationPoolIdentity'
+ }
+ else {
+ $AppPool.processModel.identityType = 'SpecificUser'
+ $AppPool.processModel.userName = $Username
+ $AppPool.processModel.password = $Password
+ $null = $AppPool | Set-Item
+ }
- # Create Website
- $WebSite = New-WebSite -Name $Name -Port 80 -HostHeader $Name -PhysicalPath $Path -Force
- #$WebSite = Get-Item "IIS:\Sites\$Name"
-
- # Set the Application Pool
- Set-ItemProperty "IIS:\Sites\$Name" 'ApplicationPool' $Name
-
- #Turn on Directory Browsing
- #Set-WebConfigurationProperty -Filter '/system.webServer/directoryBrowse' -Name 'enabled' -Value $true -PSPath "IIS:\Sites\$Name"
-
- # Update Authentication
- #Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/AnonymousAuthentication' -Name 'enabled' -Value $true -Location $name
- #Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/windowsAuthentication' -Name 'enabled' -Value $false -Location $Name
- #Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/basicAuthentication' -Name 'enabled' -Value $false -Location $Name
-
- $WebSite.Start()
+ # Create Website
+ $WebSite = New-WebSite -Name $Name -Port 80 -HostHeader $Name -PhysicalPath $Path -Force
+ #$WebSite = Get-Item "IIS:\Sites\$Name"
- Add-Content -Path "C:\Windows\System32\Drivers\etc\hosts" -Value "127.0.0.1 $Name"
- }
+ # Set the Application Pool
+ $null = Set-ItemProperty "IIS:\Sites\$Name" 'ApplicationPool' $Name
+
+ #Turn on Directory Browsing
+ #Set-WebConfigurationProperty -Filter '/system.webServer/directoryBrowse' -Name 'enabled' -Value $true -PSPath "IIS:\Sites\$Name"
+
+ # Update Authentication
+ #Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/AnonymousAuthentication' -Name 'enabled' -Value $true -Location $name
+ #Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/windowsAuthentication' -Name 'enabled' -Value $false -Location $Name
+ #Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/basicAuthentication' -Name 'enabled' -Value $false -Location $Name
+
+ $null = $WebSite.Start()
+
+ $null = Add-Content -Path "C:\Windows\System32\Drivers\etc\hosts" -Value "127.0.0.1 $Name"
+
+ # Remove standard IIS 'Hello World' application from localhost:80
+ $null = Get-WebBinding 'Default Web Site' | Remove-WebBinding
+ # Add new application on http://localhost:80
+ $null = New-WebBinding -Name "$Name" -IP "*" -Port 80 -Protocol http
+ }
}
Function Deploy-WebAppFromGit {
- param (
- [String] $URL,
- [String] $TempPath = [IO.Path]::Combine([IO.Path]::GetTempPath(), [IO.Path]::GetRandomFileName()),
- [String] $OutputPath = [IO.Path]::Combine([IO.Path]::GetTempPath(), [IO.Path]::GetRandomFileName())
- )
+ param (
+ [String] $URL,
+ [String] $TempPath = [IO.Path]::Combine([IO.Path]::GetTempPath(), [IO.Path]::GetRandomFileName()),
+ [String] $OutputPath = [IO.Path]::Combine([IO.Path]::GetTempPath(), [IO.Path]::GetRandomFileName())
+ )
begin {
Show-InvocationInfo $MyInvocation
}
@@ -103,46 +107,46 @@ Function Deploy-WebAppFromGit {
&$TrapHandler
}
- Write-Log "TempPath = '$TempPath'"
- Write-Log "OutputPath = '$OutputPath'"
-
-
- # Fetch web application
- #----------------------
- Write-Log "Fetching sources from Git ..."
-
- $null = New-Item -Path $TempPath -ItemType Container
- Exec -FilePath 'git.exe' -ArgumentList @('clone', $URL) -WorkingDir $TempPath -RedirectStreams
-
- $Path = @(Get-ChildItem $TempPath)[0].FullName
- #----------------------
-
-
- # Build web application
- #----------------------
- Write-Log "Building sources ..."
-
- $msbuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
-
- $null = New-Item -Path $OutputPath -ItemType Container
-
- $SlnFiles = @(Get-ChildItem -Path $Path -Filter *.sln -Recurse)
+ Write-Log "TempPath = '$TempPath'"
+ Write-Log "OutputPath = '$OutputPath'"
- # Start new processs with additional env variables:
- #* VisualStudioVersion = "10.0"
- #* EnableNuGetPackageRestore = "true"
- Exec -FilePath $msbuild `
- -ArgumentList @($SlnFiles[0].FullName, "/p:OutputPath=$OutputPath") `
- -Environment @{'VisualStudioVersion' = '10.0'; 'EnableNuGetPackageRestore' = 'true'} `
- -RedirectStreams
-
- $AppFolder = @(Get-ChildItem ([IO.Path]::Combine($OutputPath, '_PublishedWebsites')))[0]
- #----------------------
-
-
- # Install web application
- #------------------------
- Register-WebApp -Source $AppFolder.FullName -Name $AppFolder.Name
- #------------------------
- }
+
+ # Fetch web application
+ #----------------------
+ Write-Log "Fetching sources from Git ..."
+
+ $null = New-Item -Path $TempPath -ItemType Container
+ $null = Exec -FilePath 'git.exe' -ArgumentList @('clone', $URL) -WorkingDir $TempPath -RedirectStreams
+
+ $Path = @(Get-ChildItem $TempPath)[0].FullName
+ #----------------------
+
+
+ # Build web application
+ #----------------------
+ Write-Log "Building sources ..."
+
+ $msbuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
+
+ $null = New-Item -Path $OutputPath -ItemType Container
+
+ $SlnFiles = @(Get-ChildItem -Path $Path -Filter *.sln -Recurse)
+
+ # Start new processs with additional env variables:
+ #* VisualStudioVersion = "10.0"
+ #* EnableNuGetPackageRestore = "true"
+ $null = Exec -FilePath $msbuild `
+ -ArgumentList @($SlnFiles[0].FullName, "/p:OutputPath=$OutputPath") `
+ -Environment @{'VisualStudioVersion' = '10.0'; 'EnableNuGetPackageRestore' = 'true'} `
+ -RedirectStreams
+
+ $AppFolder = @(Get-ChildItem ([IO.Path]::Combine($OutputPath, '_PublishedWebsites')))[0]
+ #----------------------
+
+
+ # Install web application
+ #------------------------
+ $null = Register-WebApp -Source $AppFolder.FullName -Name $AppFolder.Name
+ #------------------------
+ }
}
diff --git a/data/templates/agent/scripts/ImportCoreFunctions.ps1 b/data/templates/agent/scripts/ImportCoreFunctions.ps1
index 33ee499..85e6434 100644
--- a/data/templates/agent/scripts/ImportCoreFunctions.ps1
+++ b/data/templates/agent/scripts/ImportCoreFunctions.ps1
@@ -1,4 +1,6 @@
+
Import-Module CoreFunctions -Force
+Initialize-Logger 'MuranoAgent' 'C:\Murano\PowerShell.log'
function Show-InvocationInfo {
@@ -27,7 +29,8 @@ function Show-InvocationInfo {
$TrapHandler = {
- Write-LogError @("", $_) -EntireObject
+ Write-LogError ""
+ Write-LogError $_ -EntireObject
Write-LogError ""
break
}
diff --git a/data/templates/agent/scripts/Install-RoleSecondaryDomainController.ps1 b/data/templates/agent/scripts/Install-RoleSecondaryDomainController.ps1
index 47e5980..be9258e 100644
--- a/data/templates/agent/scripts/Install-RoleSecondaryDomainController.ps1
+++ b/data/templates/agent/scripts/Install-RoleSecondaryDomainController.ps1
@@ -1,4 +1,4 @@
-
+
trap {
&$TrapHandler
}
diff --git a/data/templates/agent/scripts/Join-Domain.ps1 b/data/templates/agent/scripts/Join-Domain.ps1
index 025555d..4716709 100644
--- a/data/templates/agent/scripts/Join-Domain.ps1
+++ b/data/templates/agent/scripts/Join-Domain.ps1
@@ -49,6 +49,8 @@ Requires 'CoreFunctions' module.
Add-Computer -DomainName $DomainName -Credential $Credential -OUPath $OUPath -Force
}
+ $null = Exec 'ipconfig' @('/registerdns') -RedirectStreams
+
Write-Log "Waiting 30 seconds to restart ..."
Start-Sleep -Seconds 30
<#
diff --git a/data/templates/cf/Windows.template b/data/templates/cf/Windows.template
index f562de3..d42d425 100644
--- a/data/templates/cf/Windows.template
+++ b/data/templates/cf/Windows.template
@@ -6,20 +6,6 @@
"Description" : "Key Pair name for Load Balancer",
"Type" : "String",
"Default" : "murano-lb-key"
- },
- "InstanceType" : {
- "Description" : "Amazon EC2 instance type",
- "Type" : "String",
- "Default" : "m1.medium"
- },
- "ImageName" : {
- "Description" : "Image name",
- "Type" : "String"
- },
- "AvailabilityZone" : {
- "Description" : "The Availability Zone in which to launch the instance.",
- "Type" : "String",
- "Default" : "nova"
}
},
@@ -27,9 +13,9 @@
"$instanceName": {
"Type" : "AWS::EC2::Instance",
"Properties": {
- "InstanceType" : { "Ref" : "InstanceType" },
- "ImageId" : { "Ref" : "ImageName" },
- "AvailabilityZone" : { "Ref" : "AvailabilityZone" },
+ "InstanceType" : "$instanceType",
+ "ImageId" : "$imageName",
+ "AvailabilityZone" : "$availabilityZone",
"UserData": "$userData"
}
}
diff --git a/data/workflows/AD.xml b/data/workflows/AD.xml
index da7fa7c..b961a84 100644
--- a/data/workflows/AD.xml
+++ b/data/workflows/AD.xml
@@ -4,9 +4,10 @@
+
-
@@ -23,13 +24,9 @@
-
-
-
-
@@ -72,11 +69,11 @@
-
+
Unable to set admin password on unit () due to
-
+
@@ -290,6 +287,9 @@
+
+
+
@@ -306,7 +306,7 @@
- Unable to create Secondary Domain Controller on unit () due to
+ Unable to create Secondary Domain Controller on unit () due to
diff --git a/data/workflows/AspNetApps.xml b/data/workflows/AspNetApps.xml
index 3215f96..aba3eba 100644
--- a/data/workflows/AspNetApps.xml
+++ b/data/workflows/AspNetApps.xml
@@ -4,9 +4,10 @@
+
-
@@ -23,16 +24,11 @@
+
+
+
-
-
-
-
@@ -96,11 +92,11 @@
-
+
Unable to set admin password on unit () due to
-
+
diff --git a/data/workflows/ExternalAD.xml.example b/data/workflows/ExternalAD.xml.example
index a9e05db..1e5a6bb 100644
--- a/data/workflows/ExternalAD.xml.example
+++ b/data/workflows/ExternalAD.xml.example
@@ -1,5 +1,5 @@
-
-
@@ -24,16 +25,11 @@
+
+
+
-
-
-
-
-
-
-
-
@@ -85,11 +81,11 @@
-
+
Unable to set admin password on unit () due to
-
+
@@ -184,7 +180,7 @@
-
diff --git a/data/workflows/MsSqlServer.xml b/data/workflows/MsSqlServer.xml
index 01cee9e..484c3e6 100644
--- a/data/workflows/MsSqlServer.xml
+++ b/data/workflows/MsSqlServer.xml
@@ -4,9 +4,10 @@
+
-
@@ -23,18 +24,13 @@
+
+
+
-
-
-
-
-
-
-
-
-
+
Instance () created
@@ -72,11 +68,11 @@
-
+
Unable to set admin password on unit () due to
-
+
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 2b551cb..6cd8e02 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -61,12 +61,33 @@ Configure
# "data" must be subdirectory to this.
data_dir = /etc/murano-conductor
- [heat]
-
+ [keystone]
# URL of OpenStack KeyStone service REST API.
# Typically only hostname (or IP) needs to be changed
auth_url = http://localhost:5000/v2.0
+ # Keystone SSL parameters
+ # Optional CA cert file to use in SSL connections
+ ca_file =
+ # Optional PEM-formatted certificate chain file
+ cert_file =
+ # Optional PEM-formatted file that contains the private key
+ key_file =
+ # If set then the server's certificate will not be verified
+ insecure = False
+
+ [heat]
+ # Heat SSL parameters
+ # Optional CA cert file to use in SSL connections
+ ca_file =
+ # Optional PEM-formatted certificate chain file
+ cert_file =
+ # Optional PEM-formatted file that contains the private key
+ key_file =
+ # If set then the server's certificate will not be verified
+ insecure = False
+ # Valid endpoint types: publicURL (default), internalURL, adminURL
+ endpoint_type = publicURL
[rabbitmq]
# Connection parameters to RabbitMQ service
diff --git a/etc/conductor.conf b/etc/conductor.conf
index 778b356..1af8b22 100644
--- a/etc/conductor.conf
+++ b/etc/conductor.conf
@@ -14,12 +14,33 @@ data_dir = /etc/murano-conductor
# Maximum number of environments that can be processed simultaneously
max_environments = 20
-[heat]
-
+[keystone]
# URL of OpenStack KeyStone service REST API.
# Typically only hostname (or IP) needs to be changed
auth_url = http://localhost:5000/v2.0
+# Keystone SSL parameters
+# Optional CA cert file to use in SSL connections
+ca_file =
+# Optional PEM-formatted certificate chain file
+cert_file =
+# Optional PEM-formatted file that contains the private key
+key_file =
+# If set then the server's certificate will not be verified
+insecure = False
+
+[heat]
+# Heat SSL parameters
+# Optional CA cert file to use in SSL connections
+ca_file =
+# Optional PEM-formatted certificate chain file
+cert_file =
+# Optional PEM-formatted file that contains the private key
+key_file =
+# If set then the server's certificate will not be verified
+insecure = False
+# Valid endpoint types: publicURL (default), internalURL, adminURL
+endpoint_type = publicURL
[rabbitmq]
# Connection parameters to RabbitMQ service
diff --git a/muranoconductor/app.py b/muranoconductor/app.py
index ac8f17f..c25b6c0 100644
--- a/muranoconductor/app.py
+++ b/muranoconductor/app.py
@@ -26,6 +26,7 @@ from openstack.common import log as logging
from config import Config
import reporting
from muranocommon.messaging import MqClient, Message
+from muranocommon.helpers.token_sanitizer import TokenSanitizer
from muranoconductor import config as cfg
import windows_agent
@@ -34,6 +35,11 @@ import cloud_formation
log = logging.getLogger(__name__)
+def secure_task(task):
+ sanitizer = TokenSanitizer()
+ return sanitizer.sanitize(task)
+
+
class ConductorWorkflowService(service.Service):
def __init__(self):
super(ConductorWorkflowService, self).__init__()
@@ -80,7 +86,7 @@ class ConductorWorkflowService(service.Service):
with self.create_rmq_client() as mq:
try:
log.info('Starting processing task {0}: {1}'.format(
- message_id, anyjson.dumps(task)))
+ message_id, anyjson.dumps(secure_task(task))))
reporter = reporting.Reporter(mq, message_id, task['id'])
config = Config()
@@ -135,7 +141,7 @@ class ConductorWorkflowService(service.Service):
mq.send(message=result_msg, key='task-results')
message.ack()
log.info('Finished processing task {0}. Result = {1}'.format(
- message_id, anyjson.dumps(task)))
+ message_id, anyjson.dumps(secure_task(task))))
def cleanup(self, model, reporter):
try:
diff --git a/muranoconductor/cloud_formation.py b/muranoconductor/cloud_formation.py
index 7b52241..80b8d34 100644
--- a/muranoconductor/cloud_formation.py
+++ b/muranoconductor/cloud_formation.py
@@ -57,8 +57,8 @@ def update_cf_stack(engine, context, body, template, result=None, error=None,
command_dispatcher.execute(
name='cf', command='CreateOrUpdate', template=template,
- mappings=kwargs.get('mappings', {}),
- arguments=kwargs.get('arguments', {}),
+ mappings=(kwargs.get('mappings') or {}),
+ arguments=(kwargs.get('arguments') or {}),
callback=callback)
diff --git a/muranoconductor/commands/cloud_formation.py b/muranoconductor/commands/cloud_formation.py
index bd7e829..48f5170 100644
--- a/muranoconductor/commands/cloud_formation.py
+++ b/muranoconductor/commands/cloud_formation.py
@@ -12,13 +12,10 @@
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-import sys
import anyjson
import eventlet
-from muranoconductor.reporting import ReportedException
import types
-import jsonpath
from muranoconductor.openstack.common import log as logging
import muranoconductor.helpers
@@ -37,24 +34,36 @@ class HeatExecutor(CommandBase):
self._delete_pending_list = []
self._stack = stack
self._reporter = reporter
- settings = muranoconductor.config.CONF.heat
- client = ksclient.Client(endpoint=settings.auth_url)
- auth_data = client.tokens.authenticate(
- tenant_id=tenant_id,
- token=token)
+ keystone_settings = muranoconductor.config.CONF.keystone
+ heat_settings = muranoconductor.config.CONF.heat
- scoped_token = auth_data.id
+ client = ksclient.Client(
+ endpoint=keystone_settings.auth_url,
+ cacert=keystone_settings.ca_file or None,
+ cert=keystone_settings.cert_file or None,
+ key=keystone_settings.key_file or None,
+ insecure=keystone_settings.insecure)
- heat_url = jsonpath.jsonpath(
- auth_data.serviceCatalog,
- "$[?(@.name == 'heat')].endpoints[0].publicURL")[0]
+ if not client.authenticate(
+ auth_url=keystone_settings.auth_url,
+ tenant_id=tenant_id,
+ token=token):
+ raise heatclient.exc.HTTPUnauthorized()
+
+ heat_url = client.service_catalog.url_for(
+ service_type='orchestration',
+ endpoint_type=heat_settings.endpoint_type)
self._heat_client = Client(
'1',
heat_url,
token_only=True,
- token=scoped_token)
+ token=client.auth_token,
+ ca_file=heat_settings.ca_file or None,
+ cert_file=heat_settings.cert_file or None,
+ key_file=heat_settings.key_file or None,
+ insecure=heat_settings.insecure)
def execute(self, command, callback, **kwargs):
log.debug('Got command {0} on stack {1}'.format(command, self._stack))
@@ -93,6 +102,8 @@ class HeatExecutor(CommandBase):
self._delete_pending_list) > 0
def execute_pending(self):
+ # wait for the stack not to be IN_PROGRESS
+ self._wait_state(lambda status: True)
r1 = self._execute_pending_updates()
r2 = self._execute_pending_deletes()
return r1 or r2
@@ -126,7 +137,8 @@ class HeatExecutor(CommandBase):
log.debug(
'Waiting for the stack {0} to be update'.format(
self._stack))
- outs = self._wait_state('UPDATE_COMPLETE')
+ outs = self._wait_state(
+ lambda status: status == 'UPDATE_COMPLETE')
log.info('Stack {0} updated'.format(self._stack))
else:
self._heat_client.stacks.create(
@@ -137,7 +149,8 @@ class HeatExecutor(CommandBase):
log.debug('Waiting for the stack {0} to be create'.format(
self._stack))
- outs = self._wait_state('CREATE_COMPLETE')
+ outs = self._wait_state(
+ lambda status: status == 'CREATE_COMPLETE')
log.info('Stack {0} created'.format(self._stack))
pending_list = self._update_pending_list
@@ -163,7 +176,8 @@ class HeatExecutor(CommandBase):
stack_id=self._stack)
log.debug(
'Waiting for the stack {0} to be deleted'.format(self._stack))
- self._wait_state(['DELETE_COMPLETE', ''])
+ self._wait_state(
+ lambda status: status in ('DELETE_COMPLETE', 'NOT_FOUND'))
log.info('Stack {0} deleted'.format(self._stack))
except Exception as ex:
log.exception(ex)
@@ -186,15 +200,10 @@ class HeatExecutor(CommandBase):
except heatclient.exc.HTTPNotFound:
return {}, {}
- def _wait_state(self, state):
+ def _wait_state(self, status_func):
tries = 4
delay = 1
while tries > 0:
- if isinstance(state, types.ListType):
- states = state
- else:
- states = [state]
-
while True:
try:
stack_info = self._heat_client.stacks.get(
@@ -204,19 +213,21 @@ class HeatExecutor(CommandBase):
delay = 1
except heatclient.exc.HTTPNotFound:
stack_info = None
- status = ''
+ status = 'NOT_FOUND'
except Exception:
tries -= 1
delay *= 2
+ if not tries:
+ raise
eventlet.sleep(delay)
break
if 'IN_PROGRESS' in status:
- eventlet.sleep(1)
+ eventlet.sleep(2)
continue
- if status not in states:
+ if not status_func(status):
raise EnvironmentError(
- "Unexpected state {0}".format(status))
+ "Unexpected stack state {0}".format(status))
try:
return dict([(t['output_key'], t['output_value'])
diff --git a/muranoconductor/config.py b/muranoconductor/config.py
index 70c12e8..a40727d 100644
--- a/muranoconductor/config.py
+++ b/muranoconductor/config.py
@@ -45,13 +45,26 @@ rabbit_opts = [
]
heat_opts = [
+ cfg.BoolOpt('insecure', default=False),
+ cfg.StrOpt('ca_file'),
+ cfg.StrOpt('cert_file'),
+ cfg.StrOpt('key_file'),
+ cfg.StrOpt('endpoint_type', default='publicURL')
+]
+
+keystone_opts = [
cfg.StrOpt('auth_url'),
+ cfg.BoolOpt('insecure', default=False),
+ cfg.StrOpt('ca_file'),
+ cfg.StrOpt('cert_file'),
+ cfg.StrOpt('key_file')
]
CONF = cfg.CONF
CONF.register_opts(paste_deploy_opts, group='paste_deploy')
CONF.register_opts(rabbit_opts, group='rabbitmq')
CONF.register_opts(heat_opts, group='heat')
+CONF.register_opts(keystone_opts, group='keystone')
CONF.register_opt(cfg.StrOpt('file_server'))
CONF.register_cli_opt(cfg.StrOpt('data_dir', default='./'))
diff --git a/muranoconductor/windows_agent.py b/muranoconductor/windows_agent.py
index 01986cb..7459eeb 100644
--- a/muranoconductor/windows_agent.py
+++ b/muranoconductor/windows_agent.py
@@ -12,6 +12,7 @@
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+import os.path
from muranoconductor.commands.windows_agent import AgentTimeoutException
from muranoconductor.commands.windows_agent import UnhandledAgentException
@@ -22,10 +23,13 @@ from openstack.common import log as logging
log = logging.getLogger(__name__)
-def send_command(engine, context, body, template, service, unit, mappings=None,
- result=None, error=None, timeout=None, **kwargs):
+def send_command(engine, context, body, template, service, unit,
+ mappings=None, result=None, error=None, timeout=None,
+ osVersion=None, **kwargs):
if not mappings:
mappings = {}
+ if osVersion:
+ template = os.path.join(osVersion, template)
command_dispatcher = context['/commandDispatcher']
if timeout:
timeout = int(timeout)
diff --git a/requirements.txt b/requirements.txt
index 10718ca..47b02b8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,13 +1,14 @@
+pbr>=0.5.21,<1.0
anyjson
eventlet>=0.9.12
jsonpath
Paste
PasteDeploy
iso8601>=0.1.4
-python-heatclient==0.2.1
+python-heatclient>=0.2.4
jsonschema==2.0.0
netaddr
oslo.config
deep
-http://github.com/sergmelikyan/murano-common/releases/download/0.2.1/muranocommon-0.2.1.tar.gz#egg=muranocommon-0.2.1
+http://tarballs.openstack.org/murano-common/murano-common-release-0.2.tar.gz#egg=muranocommon-dev
diff --git a/setup-centos.sh b/setup-centos.sh
index 372cbd9..0192302 100644
--- a/setup-centos.sh
+++ b/setup-centos.sh
@@ -17,7 +17,7 @@
LOGLVL=1
SERVICE_CONTENT_DIRECTORY=`cd $(dirname "$0") && pwd`
-PREREQ_PKGS="upstart wget git make python-pip python-devel mysql-connector-python"
+PREREQ_PKGS="upstart wget git make python-pip python-devel mysql-connector-python libffi-devel"
PIPAPPS="pip python-pip pip-python"
PIPCMD=""
SERVICE_SRV_NAME="murano-conductor"
@@ -152,8 +152,7 @@ CLONE_FROM_GIT=$1
fi
# making sample configs
log "Making sample configuration files at \"$ETC_CFG_DIR\""
- #for file in `ls $GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc`
- for file in `ls $SERVICE_CONTENT_DIRECTORY/etc`
+ for file in $(ls $SERVICE_CONTENT_DIRECTORY/etc)
do
cp -f "$SERVICE_CONTENT_DIRECTORY/etc/$file" "$ETC_CFG_DIR/$file.sample"
done
@@ -166,7 +165,7 @@ CLONE_FROM_GIT=$1
get_service_exec_path()
{
if [ -z "$SERVICE_EXEC_PATH" ]; then
- SERVICE_EXEC_PATH=`which conductor`
+ SERVICE_EXEC_PATH=$(which muranoconductor)
if [ $? -ne 0 ]; then
log "Can't find \"conductor ($SERVICE_SRV_NAME)\", please install the \"$SERVICE_SRV_NAME\" by running \"$(basename "$0") install\" or set variable SERVICE_EXEC_PATH=/path/to/daemon before running setup script, exiting!"
exit 1
@@ -206,7 +205,7 @@ uninst()
# Uninstall trough pip
find_pip
# looking up for python package installed
- PYPKG=`echo $SERVICE_SRV_NAME | sed -e 's/murano-//'`
+ PYPKG=$SERVICE_SRV_NAME
_pkg=$($PIPCMD freeze | grep $PYPKG)
if [ $? -eq 0 ]; then
log "Removing package \"$PYPKG\" with pip"
diff --git a/setup.py b/setup.py
index d0f89e4..14f18d1 100644
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,7 @@ import setuptools
setuptools.setup(
setup_requires=[
'd2to1>=0.2.10,<0.3',
- 'pbr>=0.5,<0.6'
+ 'pbr>=0.5.21,<1.0'
],
d2to1=True,
pbr=True
diff --git a/setup.sh b/setup.sh
index b5b6c3c..09f76fe 100644
--- a/setup.sh
+++ b/setup.sh
@@ -17,7 +17,7 @@
LOGLVL=1
SERVICE_CONTENT_DIRECTORY=`cd $(dirname "$0") && pwd`
-PREREQ_PKGS="upstart wget git make python-pip python-dev python-mysqldb libxml2-dev libxslt-dev"
+PREREQ_PKGS="upstart wget git make python-pip python-dev python-mysqldb libxml2-dev libxslt-dev libffi-dev"
SERVICE_SRV_NAME="murano-conductor"
GIT_CLONE_DIR=`echo $SERVICE_CONTENT_DIRECTORY | sed -e "s/$SERVICE_SRV_NAME//"`
ETC_CFG_DIR="/etc/$SERVICE_SRV_NAME"
@@ -72,7 +72,6 @@ CLONE_FROM_GIT=$1
do
in_sys_pkg $PKG
done
-
# If clone from git set
if [ ! -z $CLONE_FROM_GIT ]; then
# Preparing clone root directory
@@ -92,20 +91,13 @@ CLONE_FROM_GIT=$1
# Setupping...
log "Running setup.py"
- #MRN_CND_SPY=$GIT_CLONE_DIR/$SERVICE_SRV_NAME/setup.py
MRN_CND_SPY=$SERVICE_CONTENT_DIRECTORY/setup.py
if [ -e $MRN_CND_SPY ];then
chmod +x $MRN_CND_SPY
- log "$MRN_CND_SPY output:_____________________________________________________________"
- #cd $GIT_CLONE_DIR/$SERVICE_SRV_NAME && $MRN_CND_SPY install
- #if [ $? -ne 0 ]; then
- # log "\"$MRN_CND_SPY\" python setup FAILS, exiting!"
- # exit 1
- #fi
+ log "$MRN_CND_SPY output:_____________________________________________________________"
## Setup through pip
# Creating tarball
- #cd $GIT_CLONE_DIR/$SERVICE_SRV_NAME && $MRN_CND_SPY sdist
- rm -rf $SERVICE_CONTENT_DIRECTORY/*.egg-info
+ rm -rf $SERVICE_CONTENT_DIRECTORY/*.egg-info
cd $SERVICE_CONTENT_DIRECTORY && python $MRN_CND_SPY egg_info
if [ $? -ne 0 ];then
log "\"$MRN_CND_SPY\" egg info creation FAILS, exiting!!!"
@@ -118,8 +110,6 @@ CLONE_FROM_GIT=$1
exit 1
fi
# Running tarball install
- #TRBL_FILE=$(basename `ls $GIT_CLONE_DIR/$SERVICE_SRV_NAME/dist/*.tar.gz`)
- #pip install $GIT_CLONE_DIR/$SERVICE_SRV_NAME/dist/$TRBL_FILE
TRBL_FILE=$(basename `ls $SERVICE_CONTENT_DIRECTORY/dist/*.tar.gz`)
pip install $SERVICE_CONTENT_DIRECTORY/dist/$TRBL_FILE
if [ $? -ne 0 ];then
@@ -140,15 +130,12 @@ CLONE_FROM_GIT=$1
fi
# making sample configs
log "Making sample configuration files at \"$ETC_CFG_DIR\""
- #for file in `ls $GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc`
- for file in `ls $SERVICE_CONTENT_DIRECTORY/etc`
+ for file in $(ls $SERVICE_CONTENT_DIRECTORY/etc)
do
- #cp -f "$GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc/$file" "$ETC_CFG_DIR/$file.sample"
cp -f "$SERVICE_CONTENT_DIRECTORY/etc/$file" "$ETC_CFG_DIR/$file.sample"
done
# making templates data
log "Making templates directory"
- #cp -f -R "$GIT_CLONE_DIR/$SERVICE_SRV_NAME/data" "$ETC_CFG_DIR/"
cp -f -R "$SERVICE_CONTENT_DIRECTORY/data" "$ETC_CFG_DIR/"
}
@@ -156,7 +143,7 @@ CLONE_FROM_GIT=$1
get_service_exec_path()
{
if [ -z "$SERVICE_EXEC_PATH" ]; then
- SERVICE_EXEC_PATH=`which muranoconductor`
+ SERVICE_EXEC_PATH=$(which muranoconductor)
if [ $? -ne 0 ]; then
log "Can't find \"conductor ($SERVICE_SRV_NAME)\", please install the \"$SERVICE_SRV_NAME\" by running \"$(basename "$0") install\" or set variable SERVICE_EXEC_PATH=/path/to/daemon before running setup script, exiting!"
exit 1
@@ -199,11 +186,9 @@ purgeinit()
# uninstall
uninst()
{
- #rm -f $SERVICE_EXEC_PATH
- #rm -rf $SERVICE_CONTENT_DIRECTORY
# Uninstall trough pip
# looking up for python package installed
- PYPKG=`echo $SERVICE_SRV_NAME | sed -e 's/murano-//'`
+ PYPKG=$SERVICE_SRV_NAME
pip freeze | grep $PYPKG
if [ $? -eq 0 ]; then
log "Removing package \"$PYPKG\" with pip"