windc iteration2

This commit is contained in:
Stan Lagun 2013-02-25 04:00:09 +04:00
parent 11514bca96
commit b2ca5412ee
18 changed files with 378 additions and 117 deletions

View File

@ -1,6 +1,7 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.IO; using System.IO;
using System.Net;
using System.Threading; using System.Threading;
using NLog; using NLog;
@ -60,14 +61,13 @@ namespace Mirantis.Keero.WindowsAgent
} }
if (doReboot) if (doReboot)
{ {
Console.WriteLine("Rebooting...");
try try
{ {
System.Diagnostics.Process.Start("shutdown.exe", "-r -t 0"); System.Diagnostics.Process.Start("shutdown.exe", "-r -t 0");
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex); Log.ErrorException("Cannot execute shutdown.exe", ex);
} }
} }

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Configuration; using System.Configuration;
using System.Linq; using System.Linq;
using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using RabbitMQ.Client; using RabbitMQ.Client;
@ -32,7 +33,7 @@ namespace Mirantis.Keero.WindowsAgent
public MqMessage GetMessage() public MqMessage GetMessage()
{ {
var queueName = ConfigurationManager.AppSettings["rabbitmq.inputQueue"] ?? Environment.MachineName.ToLower(); var queueName = ConfigurationManager.AppSettings["rabbitmq.inputQueue"] ?? Dns.GetHostName().ToLower();
try try
{ {
IConnection connection = null; IConnection connection = null;

View File

@ -30,6 +30,7 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Newtonsoft.Json"> <Reference Include="Newtonsoft.Json">

View File

@ -38,6 +38,7 @@ from windc.common import cfg
from windc.common import config from windc.common import config
from windc.common import wsgi from windc.common import wsgi
from windc.db import session from windc.db import session
from windc.core import builder_set
gettext.install('balancer', unicode=1) gettext.install('balancer', unicode=1)
@ -50,10 +51,11 @@ if __name__ == '__main__':
conf.register_cli_opt(dbsync_opt) conf.register_cli_opt(dbsync_opt)
conf() conf()
config.setup_logging(conf)
if conf.dbsync: if conf.dbsync:
config.setup_logging(conf)
session.sync(conf) session.sync(conf)
else: else:
builder_set.builders.load(conf)
app = config.load_paste_app(conf) app = config.load_paste_app(conf)
server = wsgi.Server() server = wsgi.Server()
server.start(app, conf, default_port=8181) server.start(app, conf, default_port=8181)

View File

@ -0,0 +1,29 @@
{
"Scripts": [
"RnVuY3Rpb24gU2V0LUxvY2FsVXNlclBhc3N3b3JkIHsNCiAgICBwYXJhbSAoDQogICAgICAgIFtTdHJpbmddICRVc2VyTmFtZSwNCiAgICAgICAgW1N0cmluZ10gJFBhc3N3b3JkLA0KICAgICAgICBbU3dpdGNoXSAkRm9yY2UNCiAgICApDQogICAgDQogICAgdHJhcCB7IFN0b3AtRXhlY3V0aW9uICRfIH0NCiAgICANCiAgICBpZiAoKEdldC1XbWlPYmplY3QgV2luMzJfVXNlckFjY291bnQgLUZpbHRlciAiTG9jYWxBY2NvdW50ID0gJ1RydWUnIEFORCBOYW1lPSckVXNlck5hbWUnIikgLWVxICRudWxsKSB7DQogICAgICAgIHRocm93ICJVbmFibGUgdG8gZmluZCBsb2NhbCB1c2VyIGFjY291bnQgJyRVc2VyTmFtZSciDQogICAgfQ0KICAgIA0KICAgIGlmICgkRm9yY2UpIHsNCiAgICAgICAgV3JpdGUtTG9nICJDaGFuZ2luZyBwYXNzd29yZCBmb3IgdXNlciAnJFVzZXJOYW1lJyB0byAnKioqKionIiAjIDopDQogICAgICAgIChbQURTSV0gIldpbk5UOi8vLi8kVXNlck5hbWUiKS5TZXRQYXNzd29yZCgkUGFzc3dvcmQpDQogICAgfQ0KICAgIGVsc2Ugew0KICAgICAgICBXcml0ZS1Mb2dXYXJuaW5nICJZb3UgYXJlIHRyeWluZyB0byBjaGFuZ2UgcGFzc3dvcmQgZm9yIHVzZXIgJyRVc2VyTmFtZScuIFRvIGRvIHRoaXMgcGxlYXNlIHJ1biB0aGUgY29tbWFuZCBhZ2FpbiB3aXRoIC1Gb3JjZSBwYXJhbWV0ZXIuIg0KICAgICAgICAkVXNlckFjY291bnQNCiAgICB9DQp9DQoNCg0KDQpGdW5jdGlvbiBJbnN0YWxsLVJvbGVQcmltYXJ5RG9tYWluQ29udHJvbGxlcg0Kew0KPCMNCi5TWU5PUFNJUw0KQ29uZmlndXJlIG5vZGUncyBuZXR3b3JrIGFkYXB0ZXJzLg0KQ3JlYXRlIGZpcnN0IGRvbWFpbiBjb250cm9sbGVyIGluIHRoZSBmb3Jlc3QuDQoNCi5FWEFNUExFDQpQUz4gSW5zdGFsbC1Sb2xlUHJpbWFyeURvbWFpbkNvbnRyb2xsZXIgLURvbWFpbk5hbWUgYWNtZS5sb2NhbCAtU2FmZU1vZGVQYXNzd29yZCAiUEBzc3cwcmQiDQoNCkluc3RhbGwgRE5TIGFuZCBBRERTLCBjcmVhdGUgZm9yZXN0IGFuZCBkb21haW4gJ2FjbWUubG9jYWwnLg0KU2V0IERDIHJlY292ZXJ5IG1vZGUgcGFzc3dvcmQgdG8gJ1BAc3N3MHJkJy4NCiM+DQoJDQoJcGFyYW0NCgkoDQoJCVtTdHJpbmddDQoJCSMgTmV3IGRvbWFpbiBuYW1lLg0KCQkkRG9tYWluTmFtZSwNCgkJDQoJCVtTdHJpbmddDQoJCSMgRG9tYWluIGNvbnRyb2xsZXIgcmVjb3ZlcnkgbW9kZSBwYXNzd29yZC4NCgkJJFNhZmVNb2RlUGFzc3dvcmQNCgkpDQoNCgl0cmFwIHsgU3RvcC1FeGVjdXRpb24gJF8gfQ0KDQogICAgICAgICMgQWRkIHJlcXVpcmVkIHdpbmRvd3MgZmVhdHVyZXMNCglBZGQtV2luZG93c0ZlYXR1cmVXcmFwcGVyIGANCgkJLU5hbWUgIkROUyIsIkFELURvbWFpbi1TZXJ2aWNlcyIsIlJTQVQtREZTLU1nbXQtQ29uIiBgDQoJCS1JbmNsdWRlTWFuYWdlbWVudFRvb2xzIGANCiAgICAgICAgLU5vdGlmeVJlc3RhcnQNCg0KDQoJV3JpdGUtTG9nICJDcmVhdGluZyBmaXJzdCBkb21haW4gY29udHJvbGxlciAuLi4iDQoJCQ0KCSRTTUFQID0gQ29udmVydFRvLVNlY3VyZVN0cmluZyAtU3RyaW5nICRTYWZlTW9kZVBhc3N3b3JkIC1Bc1BsYWluVGV4dCAtRm9yY2UNCgkJDQoJSW5zdGFsbC1BRERTRm9yZXN0IGANCgkJLURvbWFpbk5hbWUgJERvbWFpbk5hbWUgYA0KCQktU2FmZU1vZGVBZG1pbmlzdHJhdG9yUGFzc3dvcmQgJFNNQVAgYA0KCQktRG9tYWluTW9kZSBEZWZhdWx0IGANCgkJLUZvcmVzdE1vZGUgRGVmYXVsdCBgDQoJCS1Ob1JlYm9vdE9uQ29tcGxldGlvbiBgDQoJCS1Gb3JjZSBgDQoJCS1FcnJvckFjdGlvbiBTdG9wIHwgT3V0LU51bGwNCg0KCVdyaXRlLUhvc3QgIldhaXRpbmcgZm9yIHJlYm9vdCAuLi4iCQkNCiMJU3RvcC1FeGVjdXRpb24gLUV4aXRDb2RlIDMwMTAgLUV4aXRTdHJpbmcgIkNvbXB1dGVyIG11c3QgYmUgcmVzdGFydGVkIHRvIGZpbmlzaCBkb21haW4gY29udHJvbGxlciBwcm9tb3Rpb24uIg0KIwlXcml0ZS1Mb2cgIlJlc3RhcmluZyBjb21wdXRlciAuLi4iDQojCVJlc3RhcnQtQ29tcHV0ZXIgLUZvcmNlDQp9DQo="
],
"Commands": [
{
"Name": "Import-Module",
"Arguments": {
"Name": "CoreFunctions"
}
},
{
"Name": "Set-LocalUserPassword",
"Arguments": {
"UserName": "Administrator",
"Password": "@adm_password",
"Force": true
}
},
{
"Name": "Install-RolePrimaryDomainController",
"Arguments": {
"DomainName": "@dc_name",
"SafeModePassword": "@recovery_password"
}
}
],
"RebootOnCompletion": 1
}

View File

@ -0,0 +1,61 @@
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "",
"Parameters" : {
"KeyName" : {
"Description" : "Name of an existing Amazon EC2 key pair for RDP access",
"Type" : "String",
"Default" : "keero_key"
},
"InstanceType" : {
"Description" : "Amazon EC2 instance type",
"Type" : "String",
"Default" : "m1.medium",
"AllowedValues" : [ "m1.small", "m1.medium", "m1.large" ]
},
"ImageName" : {
"Description" : "Image name",
"Type" : "String",
"Default" : "ws-2012-full-agent",
"AllowedValues" : [ "ws-2012-full", "ws-2012-core", "ws-2012-full-agent" ]
}
},
"Resources" : {
"IAMUser" : {
"Type" : "AWS::IAM::User",
"Properties" : {
"Path": "/",
"Policies": [{
"PolicyName": "root",
"PolicyDocument": { "Statement":[{
"Effect": "Allow",
"Action": "CloudFormation:DescribeStackResource",
"Resource": "*"
}]}
}]
}
},
"IAMUserAccessKey" : {
"Type" : "AWS::IAM::AccessKey",
"Properties" : {
"UserName" : {"Ref": "IAMUser"}
}
},
"InstanceTemplate": {
"Type" : "AWS::EC2::Instance",
"Properties": {
"InstanceType" : { "Ref" : "InstanceType" },
"ImageId" : { "Ref" : "ImageName" },
"KeyName" : { "Ref" : "KeyName" }
}
}
},
"Outputs" : {
}
}

View File

@ -51,3 +51,7 @@ admin_password = 000
[filter:auth-context] [filter:auth-context]
paste.filter_factory = windc.common.wsgi:filter_factory paste.filter_factory = windc.common.wsgi:filter_factory
windc.filter_factory = keystone.middleware.balancer_auth_token:KeystoneContextMiddleware windc.filter_factory = keystone.middleware.balancer_auth_token:KeystoneContextMiddleware
[rabbitmq]
host = 10.0.0.1
vhost = keero

View File

@ -20,3 +20,4 @@ PyChef
Paste Paste
passlib passlib
puka

View File

@ -18,4 +18,4 @@
import builder_set import builder_set
builder_set.builders = builder_set.BuilderSet() builder_set.builders = builder_set.BuilderSet()
builder_set.builders.load() #builder_set.builders.load()

View File

@ -20,7 +20,7 @@ class Builder:
type = "abstract" type = "abstract"
version = 0 version = 0
def __init__(self): def __init__(self, conf):
pass pass
def __str__(self): def __str__(self):

View File

@ -26,7 +26,7 @@ import traceback
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
global builders global builders
def load_from_file(filepath): def load_from_file(filepath, conf):
class_inst = None class_inst = None
mod_name,file_ext = os.path.splitext(os.path.split(filepath)[-1]) mod_name,file_ext = os.path.splitext(os.path.split(filepath)[-1])
@ -39,7 +39,7 @@ def load_from_file(filepath):
if hasattr(py_mod, mod_name): if hasattr(py_mod, mod_name):
callable = getattr(__import__(mod_name),mod_name) callable = getattr(__import__(mod_name),mod_name)
class_inst = callable() class_inst = callable(conf)
return class_inst return class_inst
@ -50,14 +50,14 @@ class BuilderSet:
sys.path.append(self.path) sys.path.append(self.path)
self.set = {} self.set = {}
def load(self): def load(self, conf):
files = glob.glob(self.path+'/*.py') files = glob.glob(self.path+'/*.py')
for file in files: for file in files:
LOG.debug("Trying to load builder from file: %s", file) LOG.debug("Trying to load builder from file: %s", file)
try: try:
builder = load_from_file(file) builder = load_from_file(file, conf)
LOG.info("Buider '%s' loaded.", builder.name) LOG.info("Buider '%s' loaded.", builder.name)
self.set[builder.type] = builder self.set[builder.type] = builder
except: except:

View File

@ -19,6 +19,8 @@
import logging import logging
import uuid import uuid
import os import os
from sphinx.ext.autosummary import generate
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
from windc.core.builder import Builder from windc.core.builder import Builder
@ -26,95 +28,183 @@ from windc.core import change_events as events
from windc.db import api as db_api from windc.db import api as db_api
from windc.core.templates import Template from windc.core.templates import Template
from windc.core import commands as command_api from windc.core import commands as command_api
import json
from windc.common import cfg
from random import choice
chars = 'abcdefghklmnopqrstvwxyz2345689'
class ActiveDirectory(Builder): class ActiveDirectory(Builder):
def __init__(self): def __init__(self, conf):
self.name = "Active Directory Builder" self.name = "Active Directory Builder"
self.type = "active_directory_service" self.type = "active_directory_service"
self.version = 1 self.version = 1
self.conf = conf
def build(self, context, event, data): conf.register_group(cfg.OptGroup(name="rabbitmq"))
dc = db_api.unpack_extra(data) conf.register_opts([
if event.scope == events.SCOPE_SERVICE_CHANGE: cfg.StrOpt('host', default='10.0.0.1'),
LOG.info ("Got service change event. Analysing..") cfg.StrOpt('vhost', default='keero'),
if self.do_analysis(context, event, dc): ], group="rabbitmq")
self.plan_changes(context, event, dc)
self.submit_commands(context, event, dc)
else:
LOG.debug("Not in my scope. Skip event.")
pass
def do_analysis(self, context, event, data): def build(self, context, event, data, executor):
LOG.debug("Doing analysis for data: %s", data) dc = db_api.unpack_extra(data)
print data if event.scope == events.SCOPE_SERVICE_CHANGE:
LOG.info ("Got service change event. Analysing..")
if self.do_analysis(context, event, dc):
self.plan_changes(context, event, dc)
context['zones'] = ['a1'] self.submit_commands(context, event, dc, executor)
if data['type'] == self.type: else:
LOG.debug("It is a service which I should build.") LOG.debug("Not in my scope. Skip event.")
datacenter_id = data['datacenter_id'] pass
dc = db_api.datacenter_get(context['conf'],data['tenant_id'],
data['datacenter_id'])
datacenter = db_api.unpack_extra(dc)
context['stack_name']=datacenter['name']
return True
else:
return False
def plan_changes(self, context, event, data): def generate(self, length):
# Here we can plan multiple command execution. return ''.join(choice(chars) for _ in range(length))
# It might be Heat call command, then chef call command and other
#
LOG.debug("Plan changes...")
self.prepare_template(context, event, data)
self.chef_configuration(context, event, data)
context['commands'].append(self.deploy_template_command(context, event, data))
context['commands'].append(self.chef_configuration_command(context, event, data))
pass
def prepare_template(self, context, event, data): def do_analysis(self, context, event, data):
LOG.debug("Prepare CloudFormation Template...") LOG.debug("Doing analysis for data: %s", data)
template = Template() print data
template.add_description('Base template for Active Directory deployment')
sec_grp = template.create_security_group('Security group for AD')
rule = template.create_securitygroup_rule('tcp','3389','3389','0.0.0.0/0')
template.add_rule_to_securitygroup(sec_grp, rule)
template.add_resource('ADSecurityGroup', sec_grp)
instance = template.create_instance() context['zones'] = ['a1']
instance_name= 'AD-DC001' if data['type'] == self.type:
template.add_security_group(instance, 'ADSecurityGroup') LOG.debug("It is a service which I should build.")
template.add_resource(instance_name, instance) datacenter_id = data['datacenter_id']
dc = db_api.datacenter_get(context['conf'],data['tenant_id'],
data['datacenter_id'])
datacenter = db_api.unpack_extra(dc)
context['stack_name']=datacenter['name']
return True
else:
return False
template.add_output_value(instance_name+'-IP',{"Fn::GetAtt" : [instance_name,'PublicIp']}, def plan_changes(self, context, event, data):
'Public IP for the domain controller.') # Here we can plan multiple command execution.
context['template']=template # It might be Heat call command, then chef call command and other
pass #
LOG.debug("Plan changes...")
self.prepare_template(context, event, data)
# self.chef_configuration(context, event, data)
# context['commands'].append(self.deploy_template_command(context, event, data))
# context['commands'].append(self.chef_configuration_command(context, event, data))
pass
def deploy_template_command(self, context, event, data): def prepare_template(self, context, event, data):
LOG.debug("Creating CloudFormation Template deployment command...") LOG.debug("Prepare CloudFormation Template...")
print context['template'].to_json() # template = Template()
LOG.debug(context['template']) # template.add_description('Base template for Active Directory deployment')
print os.system('pwd') # sec_grp = template.create_security_group('Security group for AD')
fname = "templates/"+str(uuid.uuid4()) # rule = template.create_securitygroup_rule('tcp','3389','3389','0.0.0.0/0')
f=open(fname, "w") # template.add_rule_to_securitygroup(sec_grp, rule)
f.write(context['template'].to_json()) # template.add_resource('ADSecurityGroup', sec_grp)
f.close() #
context['template_name']=fname # instance = template.create_instance()
command = command_api.Command(command_api.TEMPLATE_DEPLOYMENT_COMMAND, context) # instance_name= 'AD-DC001'
return command # template.add_security_group(instance, 'ADSecurityGroup')
pass # template.add_resource(instance_name, instance)
#
# template.add_output_value(instance_name+'-IP',{"Fn::GetAtt" : [instance_name,'PublicIp']},
# 'Public IP for the domain controller.')
def chef_configuration(self, context, event, data): print "-------------------"
LOG.debug("Creating Chef configuration...") print data
context['Role'] = 'pdc' print "-------------------"
pass print context
print "********"
try:
print self.conf.rabbitmq.vhost
except Exception, ex:
print ex
print "********"
def chef_configuration_command(self, context, event, data): with open('data/Windows.template', 'r') as f:
LOG.debug("Creating Chef configuration command...") read_data = f.read()
command = command_api.Command(command_api.CHEF_COMMAND, context)
return command
def submit_commands(self, context, event, data): template = json.loads(read_data)
LOG.debug("Submit commands for execution...")
pass instance_template = template['Resources']['InstanceTemplate']
del template['Resources']['InstanceTemplate']
context['instances'] = []
context['template_arguments'] = {
"KeyName": "keero-linux-keys",
"InstanceType": "m1.medium",
"ImageName": "ws-2012-full-agent"
}
for i in range(data['dc_count']):
instance_name = 'dc' + str(i) + "x" + self.generate(9)
context['instances'].append(instance_name)
template['Resources'][instance_name] = instance_template
context['template']=template
pass
def deploy_template_command(self, context, event, data, executor):
LOG.debug("Creating CloudFormation Template deployment command...")
#print context['template'].to_json()
LOG.debug(context['template'])
if not os.path.exists("templates"):
os.mkdir("templates")
fname = "templates/"+str(uuid.uuid4())
print "Saving template to", fname
f=open(fname, "w")
f.write(json.dumps(context['template']))
f.close()
context['template_name']=fname
command = command_api.Command(command_api.TEMPLATE_DEPLOYMENT_COMMAND, context)
executor.execute(command)
def chef_configuration(self, context, event, data):
LOG.debug("Creating Chef configuration...")
context['Role'] = 'pdc'
pass
def transform(self, path, map):
with open(path, 'r') as f:
read_data = f.read()
template = json.loads(read_data)
if 'Commands' in template:
for command in template['Commands']:
if 'Arguments' in command:
for argument, argument_value in command['Arguments'].items():
if isinstance(argument_value, (str, unicode)) and argument_value.startswith("@"):
command['Arguments'][argument] = map[argument_value[1:]]
return json.dumps(template)
def deploy_execution_plan(self, context, event, data, executor):
i = 0
for instance in context['instances']:
i += 1
if i == 1:
files = ["data/CreatePrimaryDC.json"]
else:
files = []
for file in files:
queueData = {
"queueName" : str("%s-%s" % (context['stack_name'], instance)),
"resultQueueName": "-execution-results",
"body": self.transform(file, data)
}
command = command_api.Command(command_api.EXECUTION_PLAN_DEPLOYMENT_COMMAND, context, queueData)
executor.execute(command)
def chef_configuration_command(self, context, event, data):
LOG.debug("Creating Chef configuration command...")
command = command_api.Command(command_api.CHEF_COMMAND, context)
return command
def submit_commands(self, context, event, data, executor):
LOG.debug("Submit commands for execution...")
self.deploy_template_command(context, event, data, executor)
self.deploy_execution_plan(context, event, data, executor)
print "Commands submitted"
pass

View File

@ -23,12 +23,12 @@ from windc.core.builder import Builder
from windc.core import change_events as events from windc.core import change_events as events
class DataCenter(Builder): class DataCenter(Builder):
def __init__(self): def __init__(self, conf):
self.name = "Data Center Builder" self.name = "Data Center Builder"
self.type = "datacenter" self.type = "datacenter"
self.version = 1 self.version = 1
def build(self, context, event, data): def build(self, context, event, data, executor):
if event.scope == events.SCOPE_DATACENTER_CHANGE: if event.scope == events.SCOPE_DATACENTER_CHANGE:
LOG.info ("Got Data Center change event. Analysing...") LOG.info ("Got Data Center change event. Analysing...")
else: else:

View File

@ -33,24 +33,21 @@ ACTION_MODIFY = "Modify"
ACTION_DELETE = "Delete" ACTION_DELETE = "Delete"
class Event: class Event:
scope = None scope = None
action = None action = None
previous_state = None previous_state = None
def __init__(self, scope, action): def __init__(self, scope, action):
self.scope = scope self.scope = scope
self.action = action self.action = action
def change_event(conf, event, data): def change_event(conf, event, data):
LOG.info("Change event of type: %s ", event) LOG.info("Change event of type: %s ", event)
context = builder.create_context() context = builder.create_context()
context['conf'] = conf context['conf'] = conf
for builder_type in builder_set.builders.set: executor = command_executor.Executor(conf)
builder_instance = builder_set.builders.set[builder_type] for builder_type in builder_set.builders.set:
builder_instance.build(context, event, data) builder_instance = builder_set.builders.set[builder_type]
builder_instance.build(context, event, data, executor)
executor = command_executor.Executor()
executor.execute(context['commands'])
pass

View File

@ -16,13 +16,14 @@
# under the License. # under the License.
TEMPLATE_DEPLOYMENT_COMMAND = "Template" TEMPLATE_DEPLOYMENT_COMMAND = "Template"
EXECUTION_PLAN_DEPLOYMENT_COMMAND = "EPlan"
CHEF_COMMAND = "Chef" CHEF_COMMAND = "Chef"
CHEF_OP_CREATE_ENV = "Env" CHEF_OP_CREATE_ENV = "Env"
CHEF_OP_CREATE_ROLE = "Role" CHEF_OP_CREATE_ROLE = "Role"
CHEF_OP_ASSIGN_ROLE = "AssignRole" CHEF_OP_ASSIGN_ROLE = "AssignRole"
CHEF_OP_CREATE_NODE = "CRNode" CHEF_OP_CREATE_NODE = "CRNode"
class Command: class Command(object):
type = "Empty" type = "Empty"
context = None context = None

View File

@ -20,18 +20,21 @@
from windc.core import commands as commands_api from windc.core import commands as commands_api
from windc.drivers import openstack_heat from windc.drivers import openstack_heat
from windc.drivers import windows_agent
class Executor: class Executor:
map = {commands_api.TEMPLATE_DEPLOYMENT_COMMAND : openstack_heat.Heat} map = {commands_api.TEMPLATE_DEPLOYMENT_COMMAND : openstack_heat.Heat}
def __init__(self): def __init__(self, conf):
pass self._conf = conf
def execute(self, commands): def execute(self, command):
for command in commands: if command.type == commands_api.TEMPLATE_DEPLOYMENT_COMMAND:
if command.type == commands_api.TEMPLATE_DEPLOYMENT_COMMAND: executor = openstack_heat.Heat()
executor = openstack_heat.Heat() return executor.execute(command)
executor.execute(command) elif command.type == commands_api.EXECUTION_PLAN_DEPLOYMENT_COMMAND:
executor = windows_agent.Agent(self._conf)
return executor.execute(command)

View File

@ -32,7 +32,12 @@ class Heat:
def execute(self, command): def execute(self, command):
# client = Client('1',OS_IMAGE_ENDPOINT, OS_TENANT_ID) # client = Client('1',OS_IMAGE_ENDPOINT, OS_TENANT_ID)
LOG.debug('Calling heat script to execute template') LOG.debug('Calling heat script to execute template')
call(["./heat_run","stack-create","-f"+command.context['template_name'], arguments = ";".join(['%s=%s' % (key, value) for (key, value) in command.context['template_arguments'].items()])
command.context['stack_name']]) call([
"./heat_run","stack-create",
"-f" + command.context['template_name'],
"-P" + arguments,
command.context['stack_name']
])
pass pass

View File

@ -0,0 +1,66 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# Copyright 2011 Piston Cloud Computing, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import traceback
import puka
import logging
import sys
LOG = logging.getLogger(__name__)
class Agent(object):
def __init__(self, conf):
self._conf = conf
def execute(self, command):
try:
client = puka.Client("amqp://keero:keero@%s/%s" % (
self._conf.rabbitmq.host, self._conf.rabbitmq.vhost))
promise = client.connect()
client.wait(promise)
promise = client.queue_declare(queue=command.data['queueName'], durable=True)
client.wait(promise)
promise = client.queue_declare(queue=command.data['resultQueueName'], durable=True)
client.wait(promise)
promise = client.basic_publish(exchange='', routing_key=command.data['queueName'],
body=command.data['body'])
client.wait(promise)
consume_promise = client.basic_consume(queue=command.data['resultQueueName'])
result = client.wait(consume_promise)
result_msg = result['body']
client.basic_ack(result)
client.basic_cancel(consume_promise)
promise = client.close()
client.wait(promise)
return result_msg
except Exception:
exc_type, exc_value, exc_traceback = sys.exc_info()
print exc_type, exc_value, exc_traceback
print traceback.format_exc()