Cherry-pick following change-ids from release-0.2.

Iec6b3c56d464d26e4f1fc143e6a7804add67a35d
I3f2d3a12fcb53759a906fcbae6fae768833d325e
I566811521da16055a73c73052ffcd497aaa8e475
I2ee04b6d5aaa26d49243cf7e0b6045026f052625
I329620f3c8aa7e7f1bdd658cbaa8ea20d9aa4ba5
I5ff3d9146b4fbec74d8d65de84d7ab61d869725c
Ib38fd52811812170bdd9bf9df90a66f1a2e6c8d9
I64ce3efaec6df2e402ca2acf6a3cf1a6f2bb1909
I66c3659ab0f33772d7a51c8961a37e32c65354c2
I29ce4a6ef165daa0fe60003301a0d807fd1cce42
Ibd2a4f55e2a64d9a992833200a791dbb20c41eca
I16133a213ef25a1b374f10fa80cd5a03d1f40753
Ie09f32fcacfe70f436cad71e5749edf94be038ed
Iaba6a6bf07ff223e41f705f0f1db5688a5290f5c
I64a0474ecfe5ea38393fe681d520a7b6ce00d959
I270b3ce5ef776522a62d9622b36f0d6b50b9cc57
Ic5f6849ea166bb0295f84685b0a2b5c4701f972a
I51190cb02255254a888f66404ecdc3dfc5be0386
I0c2180c603cd09e29d4e6c5e592b987e2b447972
Iae1cdbeb7fa3e49c2cb5cac7c92eceffef477e7e
I6c643f58aada0a8525711bc452d0c581625f3d26
I9c4f999b1b3006b8ae5f18a030d5b30c7e85e03b
I32eaad36edcb889b448c45ba36f4e97f7c87d1e5
I8c91c40a922690b475aac1c0a3b2c0c28274b130
I574fd1dbeea58dbf41f77d295dc03c23d2feaf96

Change-Id: I0ffb3c38c0c1b3aafa8617364e22036c47aaef76
This commit is contained in:
Igor Yozhikov 2013-08-13 16:27:23 +04:00 committed by Timur Sufiev
parent cb48af0fe8
commit 8fc771e980
24 changed files with 289 additions and 273 deletions

View File

@ -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 '<exception>'
Write-LogError $_ -EntireObject
Write-LogError '</exception>'
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

View File

@ -15,16 +15,6 @@
"UserPassword": "$domainAdminAccountPassword",
"StaticAddress": "$clusterIP"
}
},
{
"Name": "New-FailoverClusterSharedFolder",
"Arguments": {
"ClusterName": "$clusterName",
"UserName": "$domainAdminAccountName",
"UserPassword": "$domainAdminAccountPassword",
"ShareServer": "$shareServer",
"DomainName": "$domainName"
}
}
],
"RebootOnCompletion": 0

View File

@ -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
#------------------------
}
}

View File

@ -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 @("<exception>", $_) -EntireObject
Write-LogError "<exception>"
Write-LogError $_ -EntireObject
Write-LogError "</exception>"
break
}

View File

@ -1,4 +1,4 @@

trap {
&$TrapHandler
}

View File

@ -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
<#

View File

@ -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"
}
}

View File

@ -4,9 +4,10 @@
<set path="domain">
<select path="::domain"/>
</set>
<mute/>
</rule>
<rule match="$.services[?(@.type == 'activeDirectory')].units[?(@.state.hostname and @.state.osImageName and not @.temp.instanceName)]"
<rule match="$.services[?(@.type == 'activeDirectory' and @.osImage.name)].units[?(@.state.hostname and not @.temp.instanceName)]"
desc="Units of AD services which have got hostname and image assigned, but instances not deployed yet">
<report entity="unit">
<parameter name="id"><select path="id"/></parameter>
@ -23,13 +24,9 @@
<parameter name="service"><select path="::id"/></parameter>
</prepare-user-data>
</mapping>
</map>
</parameter>
<parameter name="arguments">
<map>
<argument name="InstanceType"><select path="::flavor" default="m1.medium"/></argument>
<argument name="ImageName"><select path="state.osImageName"/></argument>
<argument name="AvailabilityZone"><select path="::availabilityZone" default="nova"/></argument>
<mapping name="instanceType"><select path="::flavor" default="m1.medium"/></mapping>
<mapping name="imageName"><select path="::osImage.name"/></mapping>
<mapping name="availabilityZone"><select path="::availabilityZone" default="nova"/></mapping>
</map>
</parameter>
@ -72,11 +69,11 @@
</set>
</success>
<failure>
<report entity="unit" level="error">
<report entity="unit" level="warning">
<parameter name="id"><select path="id"/></parameter>
<parameter name="text">Unable to set admin password on unit <select path="state.hostname"/> (<select path="name"/>) due to <select source="exception" path="0.messages.0" default="unknown Agent error"/> </parameter>
</report>
<stop/>
<mute/>
</failure>
</send-command>
</rule>
@ -290,6 +287,9 @@
<mapping name="domainPassword">
<select path="::adminPassword"/>
</mapping>
<mapping name="domain">
<select path="::domain"/>
</mapping>
</map>
</parameter>
<success>
@ -306,7 +306,7 @@
<failure>
<report entity="unit" level="error">
<parameter name="id"><select path="id"/></parameter>
<parameter name="text">Unable to create Secondary Domain Controller on unit <select path="state.hostname" source="unit"/> (<select path="name" source="unit"/>) due to <select source="exception" path="0.messages.0" default="unknown Agent error"/> </parameter>
<parameter name="text">Unable to create Secondary Domain Controller on unit <select path="state.hostname" /> (<select path="name" />) due to <select source="exception" path="0.messages.0" default="unknown Agent error"/> </parameter>
</report>
<report entity="service" level="error">
<parameter name="id"><select path="::id"/></parameter>

View File

@ -4,9 +4,10 @@
<set path="domain">
<select path="::domain"/>
</set>
<mute/>
</rule>
<rule match="$.services[?(@.type in ('webServer', 'aspNetApp', 'webServerFarm', 'aspNetAppFarm'))].units[?(@.state.hostname and @.state.osImageName and not @.temp.instanceName)]"
<rule match="$.services[?(@.type in ('webServer', 'aspNetApp', 'webServerFarm', 'aspNetAppFarm') and @.osImage.name)].units[?(@.state.hostname and not @.temp.instanceName)]"
desc="Units of web services having hostname and image names assigned but without instances">
<report entity="unit">
<parameter name="id"><select path="id"/></parameter>
@ -23,16 +24,11 @@
<parameter name="service"><select path="::id"/></parameter>
</prepare-user-data>
</mapping>
<mapping name="instanceType"><select path="::flavor" default="m1.medium"/></mapping>
<mapping name="imageName"><select path="::osImage.name"/></mapping>
<mapping name="availabilityZone"><select path="::availabilityZone" default="nova"/></mapping>
</map>
</parameter>
<parameter name="arguments">
<map>
<argument name="InstanceType"><select path="::flavor" default="m1.medium"/></argument>
<argument name="ImageName"><select path="state.osImageName"/></argument>
<argument name="AvailabilityZone"><select path="::availabilityZone" default="nova"/></argument>
</map>
</parameter>
<success>
<set path="temp.instanceName"><select path="name"/></set>
<report entity="unit">
@ -96,11 +92,11 @@
</set>
</success>
<failure>
<report entity="unit" level="error">
<report entity="unit" level="warning">
<parameter name="id"><select path="id"/></parameter>
<parameter name="text">Unable to set admin password on unit <select path="state.hostname"/> (<select path="name"/>) due to <select source="exception" path="0.messages.0" default="unknown Agent error"/> </parameter>
</report>
<stop/>
<mute/>
</failure>
</send-command>
</rule>

View File

@ -1,5 +1,5 @@
<workflow>
<rule match="$.services[?(@.type != 'activeDirectory' and @.availabilityZone)].units[?(@.state.instanceName and @.state.hostname and not @.domain)]"
<rule match="$.services[?(@.type != 'activeDirectory' and @.availabilityZone)].units[?(@.temp.instanceName and @.state.hostname and not @.domain)]"
desc="Units of Non-AD services with availability zone specified which are deployed and are not part of the domain">
<set path="#externalADmap">
<map>

View File

@ -1,29 +0,0 @@
<workflow>
<rule match="$.services[*].units[?(not @.state.osImageName)]" desc="Units with no image">
<set path="#osImageMap">
<map>
<!-- ====================================================================== -->
<!-- Mappings between image IDs and image file names can be configured here -->
<!-- ====================================================================== -->
<mapping name="ws-2012-std">ws-2012-std</mapping>
<mapping name="ws-2012-core">ws-2012-core</mapping>
<mapping name="ws-2008r2-std">ws-2008r2-std</mapping>
<mapping name="ws-2008r2-core">ws-2008r2-core</mapping>
<!-- image to use if no image id provided -->
<mapping name="DEFAULT">ws-2012-full</mapping>
<!-- ====================================================================== -->
</map>
</set>
<set path="state.osImageName">
<select source="osImageMap">
<parameter name="path"><select path="::osImage" default="DEFAULT"/></parameter>
</select>
</set>
</rule>
</workflow>

View File

@ -5,9 +5,10 @@
<set path="domain">
<select path="::domain"/>
</set>
<mute/>
</rule>
<rule match="$.services[?(@.type == 'msSqlClusterServer')].units[?(@.state.hostname and @.state.osImageName and not @.temp.instanceName)]"
<rule match="$.services[?(@.type == 'msSqlClusterServer' and @.osImage.name)].units[?(@.state.hostname and not @.temp.instanceName)]"
desc="Units of SQL Server Cluster services having hostname and image names assigned but without instances">
<report entity="unit">
<parameter name="id"><select path="id"/></parameter>
@ -24,16 +25,11 @@
<parameter name="service"><select path="::id"/></parameter>
</prepare-user-data>
</mapping>
<mapping name="instanceType"><select path="::flavor" default="m1.medium"/></mapping>
<mapping name="imageName"><select path="::osImage.name"/></mapping>
<mapping name="availabilityZone"><select path="::availabilityZone" default="nova"/></mapping>
</map>
</parameter>
<parameter name="arguments">
<map>
<argument name="InstanceType"><select path="::flavor" default="m1.medium"/></argument>
<argument name="ImageName"><select path="state.osImageName"/></argument>
<argument name="AvailabilityZone"><select path="::availabilityZone" default="nova"/></argument>
</map>
</parameter>
<success>
<set path="temp.instanceName"><select path="name"/></set>
<report entity="unit">
@ -85,11 +81,11 @@
</set>
</success>
<failure>
<report entity="unit" level="error">
<report entity="unit" level="warning">
<parameter name="id"><select path="id"/></parameter>
<parameter name="text">Unable to set admin password on unit <select path="state.hostname"/> (<select path="name"/>) due to <select source="exception" path="0.messages.0" default="unknown Agent error"/> </parameter>
</report>
<stop/>
<mute/>
</failure>
</send-command>
</rule>
@ -184,7 +180,7 @@
</send-command>
</rule>
<rule match="$.services[?(@.type == 'msSqlClusterServer' and @.state.failoverClusterCreated and not @.state.agEnvironmentConfigured)].units[*]" limit="1"
<rule match="$.services[?(@.type == 'msSqlClusterServer' and @.state.failoverClusterCreated and not @.state.agEnvironmentConfigured)].units[*]"
desc="First unit of SQL Server Cluster services that is already has failover cluster created">
<send-command template="SqlServerCluster/ConfigureEnvironmentForAOAG" error="exception">
<parameter name="unit">

View File

@ -4,9 +4,10 @@
<set path="domain">
<select path="::domain"/>
</set>
<mute/>
</rule>
<rule match="$.services[?(@.type == 'msSqlServer')].units[?(@.state.hostname and @.state.osImageName and not @.temp.instanceName)]"
<rule match="$.services[?(@.type == 'msSqlServer' and @.osImage.name)].units[?(@.state.hostname and not @.temp.instanceName)]"
desc="Units of SQL Server services having hostname and image names assigned but without instances">
<report entity="unit">
<parameter name="id"><select path="id"/></parameter>
@ -23,18 +24,13 @@
<parameter name="service"><select path="::id"/></parameter>
</prepare-user-data>
</mapping>
<mapping name="instanceType"><select path="::flavor" default="m1.medium"/></mapping>
<mapping name="imageName"><select path="::osImage.name"/></mapping>
<mapping name="availabilityZone"><select path="::availabilityZone" default="nova"/></mapping>
</map>
</parameter>
<parameter name="arguments">
<map>
<argument name="InstanceType"><select path="::flavor" default="m1.medium"/></argument>
<argument name="ImageName"><select path="state.osImageName"/></argument>
<argument name="AvailabilityZone"><select path="::availabilityZone" default="nova"/></argument>
</map>
</parameter>
<success>
<set path="instanceName.instanceName"><select path="name"/></set>
<set path="temp.instanceName"><select path="name"/></set>
<report entity="unit">
<parameter name="id"><select path="id"/></parameter>
<parameter name="text">Instance <select path="state.hostname"/> (<select path="name"/>) created</parameter>
@ -72,11 +68,11 @@
</set>
</success>
<failure>
<report entity="unit" level="error">
<report entity="unit" level="warning">
<parameter name="id"><select path="id"/></parameter>
<parameter name="text">Unable to set admin password on unit <select path="state.hostname"/> (<select path="name"/>) due to <select source="exception" path="0.messages.0" default="unknown Agent error"/> </parameter>
</report>
<stop/>
<mute/>
</failure>
</send-command>
</rule>

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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'])

View File

@ -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='./'))

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"