diff --git a/example-puppet.py b/example-puppet.py index eed90038..12cadb21 100644 --- a/example-puppet.py +++ b/example-puppet.py @@ -1,12 +1,10 @@ import click -import json -import requests import sys import time from solar.core import actions from solar.core import resource -from solar.core.resource_provider import GitProvider +from solar.core.provider import GitProvider from solar.core import signals from solar.core import validation from solar.core import virtual_resource as vr @@ -17,6 +15,14 @@ from solar.interfaces.db import get_db GIT_PUPPET_LIBS_URL = 'https://github.com/CGenie/puppet-libs-resource' +# TODO +# Resource for repository OR puppet apt-module in run.pp +# add-apt-repository cloud-archive:juno +# No copy of manifests, pull from upstream +# Official puppet manifests, not fuel-library +# To discuss: install stuff in Docker container + + @click.group() def main(): pass @@ -31,65 +37,65 @@ def deploy(): node1 = vr.create('node1', 'resources/ro_node/', {'ip': '10.0.0.3', 'ssh_key': '/vagrant/.vagrant/machines/solar-dev1/virtualbox/private_key', 'ssh_user': 'vagrant'})[0] - rabbitmq_service1 = vr.create('rabbitmq_service1', 'resources/rabbitmq_service/', {'management_port': 15672, 'port': 5672, 'container_name': 'rabbitmq_service1', 'image': 'rabbitmq:3-management'})[0] - openstack_vhost = vr.create('openstack_vhost', 'resources/rabbitmq_vhost/', {'vhost_name': 'openstack'})[0] - openstack_rabbitmq_user = vr.create('openstack_rabbitmq_user', 'resources/rabbitmq_user/', {'user_name': 'openstack', 'password': 'openstack_password'})[0] + # rabbitmq_service1 = vr.create('rabbitmq_service1', 'resources/rabbitmq_service/', {'management_port': 15672, 'port': 5672, 'container_name': 'rabbitmq_service1', 'image': 'rabbitmq:3-management'})[0] + # openstack_vhost = vr.create('openstack_vhost', 'resources/rabbitmq_vhost/', {'vhost_name': 'openstack'})[0] + # openstack_rabbitmq_user = vr.create('openstack_rabbitmq_user', 'resources/rabbitmq_user/', {'user_name': 'openstack', 'password': 'openstack_password'})[0] - puppet_inifile = vr.create('puppet_inifile', GitProvider(GIT_PUPPET_LIBS_URL, path='inifile'), {})[0] - puppet_mysql = vr.create('puppet_mysql', GitProvider(GIT_PUPPET_LIBS_URL, path='mysql'), {})[0] - puppet_stdlib = vr.create('puppet_stdlib', GitProvider(GIT_PUPPET_LIBS_URL, path='stdlib'), {})[0] + # puppet_inifile = vr.create('puppet_inifile', GitProvider(GIT_PUPPET_LIBS_URL, path='inifile'), {})[0] + # puppet_mysql = vr.create('puppet_mysql', GitProvider(GIT_PUPPET_LIBS_URL, path='mysql'), {})[0] + # puppet_stdlib = vr.create('puppet_stdlib', GitProvider(GIT_PUPPET_LIBS_URL, path='stdlib'), {})[0] mariadb_service1 = vr.create('mariadb_service1', 'resources/mariadb_service', {'image': 'mariadb', 'root_password': 'mariadb', 'port': 3306})[0] keystone_db = vr.create('keystone_db', 'resources/mariadb_keystone_db/', {'db_name': 'keystone_db', 'login_user': 'root'})[0] keystone_db_user = vr.create('keystone_db_user', 'resources/mariadb_keystone_user/', {'new_user_name': 'keystone', 'new_user_password': 'keystone', 'login_user': 'root'})[0] - keystone_puppet = vr.create('keystone_puppet', GitProvider(GIT_PUPPET_LIBS_URL, path='keystone'), {})[0] - #keystone_puppet = vr.create('keystone_puppet', 'resources/keystone_puppet', {})[0] + #keystone_puppet = vr.create('keystone_puppet', GitProvider(GIT_PUPPET_LIBS_URL, path='keystone'), {})[0] + keystone_puppet = vr.create('keystone_puppet', 'resources/keystone_puppet', {})[0] - # TODO: vhost cannot be specified in neutron Puppet manifests so this user has to be admin anyways - neutron_puppet = vr.create('neutron_puppet', GitProvider(GIT_PUPPET_LIBS_URL, path='neutron'), {'rabbitmq_user': 'guest', 'rabbitmq_password': 'guest'})[0] - #neutron_puppet = vr.create('neutron_puppet', 'resources/neutron_puppet', {'rabbitmq_user': 'guest', 'rabbitmq_password': 'guest'})[0] + # # TODO: vhost cannot be specified in neutron Puppet manifests so this user has to be admin anyways + # neutron_puppet = vr.create('neutron_puppet', GitProvider(GIT_PUPPET_LIBS_URL, path='neutron'), {'rabbitmq_user': 'guest', 'rabbitmq_password': 'guest'})[0] + # #neutron_puppet = vr.create('neutron_puppet', 'resources/neutron_puppet', {'rabbitmq_user': 'guest', 'rabbitmq_password': 'guest'})[0] admin_tenant = vr.create('admin_tenant', 'resources/keystone_tenant', {'tenant_name': 'admin'})[0] admin_user = vr.create('admin_user', 'resources/keystone_user', {'user_name': 'admin', 'user_password': 'admin'})[0] admin_role = vr.create('admin_role', 'resources/keystone_role', {'role_name': 'admin'})[0] - services_tenant = vr.create('services_tenant', 'resources/keystone_tenant', {'tenant_name': 'services'})[0] - neutron_keystone_user = vr.create('neutron_keystone_user', 'resources/keystone_user', {'user_name': 'neutron', 'user_password': 'neutron'})[0] - neutron_keystone_role = vr.create('neutron_keystone_role', 'resources/keystone_role', {'role_name': 'neutron'})[0] + # services_tenant = vr.create('services_tenant', 'resources/keystone_tenant', {'tenant_name': 'services'})[0] + # neutron_keystone_user = vr.create('neutron_keystone_user', 'resources/keystone_user', {'user_name': 'neutron', 'user_password': 'neutron'})[0] + # neutron_keystone_role = vr.create('neutron_keystone_role', 'resources/keystone_role', {'role_name': 'neutron'})[0] #neutron_keystone_service_endpoint = vr.create('neutron_keystone_service_endpoint', 'resources/keystone_service_endpoint', {'adminurl': 'http://{{ip}}:{{admin_port}}', 'internalurl': 'http://{{ip}}:{{port}}', 'publicurl': 'http://{{ip}}:{{port}}', 'description': 'OpenStack Network Service', 'type': 'network', 'port': 9696, 'admin_port': 9696})[0] - #cinder_puppet = vr.create('cinder_puppet', GitProvider(GIT_PUPPET_LIBS_URL, 'cinder'), {})[0] - cinder_puppet = vr.create('cinder_puppet', 'resources/cinder_puppet', {})[0] + # #cinder_puppet = vr.create('cinder_puppet', GitProvider(GIT_PUPPET_LIBS_URL, 'cinder'), {})[0] + # cinder_puppet = vr.create('cinder_puppet', 'resources/cinder_puppet', {})[0] - cinder_keystone_user = vr.create('cinder_keystone_user', 'resources/keystone_user', {'user_name': 'cinder', 'user_password': 'cinder'})[0] - cinder_keystone_role = vr.create('cinder_keystone_role', 'resources/keystone_role', {'role_name': 'cinder'})[0] + # cinder_keystone_user = vr.create('cinder_keystone_user', 'resources/keystone_user', {'user_name': 'cinder', 'user_password': 'cinder'})[0] + # cinder_keystone_role = vr.create('cinder_keystone_role', 'resources/keystone_role', {'role_name': 'cinder'})[0] - #nova_network_puppet = vr.create('nova_network_puppet', GitProvider(GIT_PUPPET_LIBS_URL, 'nova_network'), {'rabbitmq_user': 'guest', 'rabbitmq_password': 'guest'})[0] - # TODO: fix rabbitmq user/password - nova_network_puppet = vr.create('nova_network_puppet', 'resources/nova_network_puppet', {'rabbitmq_user': 'guest', 'rabbitmq_password': 'guest'})[0] + # #nova_network_puppet = vr.create('nova_network_puppet', GitProvider(GIT_PUPPET_LIBS_URL, 'nova_network'), {'rabbitmq_user': 'guest', 'rabbitmq_password': 'guest'})[0] + # # TODO: fix rabbitmq user/password + # nova_network_puppet = vr.create('nova_network_puppet', 'resources/nova_network_puppet', {'rabbitmq_user': 'guest', 'rabbitmq_password': 'guest'})[0] - nova_keystone_user = vr.create('nova_keystone_user', 'resources/keystone_user', {'user_name': 'nova', 'user_password': 'nova'})[0] - nova_keystone_role = vr.create('nova_keystone_role', 'resources/keystone_role', {'role_name': 'nova'})[0] + # nova_keystone_user = vr.create('nova_keystone_user', 'resources/keystone_user', {'user_name': 'nova', 'user_password': 'nova'})[0] + # nova_keystone_role = vr.create('nova_keystone_role', 'resources/keystone_role', {'role_name': 'nova'})[0] # TODO: 'services' tenant-id is hardcoded #nova_keystone_service_endpoint = vr.create('nova_keystone_service_endpoint', 'resources/keystone_service_endpoint', {'adminurl': 'http://{{ip}}:{{admin_port}}/v2/services', 'internalurl': 'http://{{ip}}:{{public_port}}/v2/services', 'publicurl': 'http://{{ip}}:{{port}}/v2/services', 'description': 'OpenStack Compute Service', 'type': 'compute', 'port': 8776, 'admin_port': 8776})[0] - signals.connect(node1, rabbitmq_service1) - signals.connect(rabbitmq_service1, openstack_vhost) - signals.connect(rabbitmq_service1, openstack_rabbitmq_user) - signals.connect(openstack_vhost, openstack_rabbitmq_user, {'vhost_name': 'vhost_name'}) - signals.connect(rabbitmq_service1, neutron_puppet, {'ip': 'rabbitmq_host', 'port': 'rabbitmq_port'}) - signals.connect(openstack_vhost, cinder_puppet, {'vhost_name': 'rabbitmq_vhost'}) - signals.connect(openstack_rabbitmq_user, cinder_puppet, {'user_name': 'rabbitmq_user', 'password': 'rabbitmq_password'}) - signals.connect(rabbitmq_service1, cinder_puppet, {'ip': 'rabbitmq_host', 'port': 'rabbitmq_port'}) - signals.connect(rabbitmq_service1, nova_network_puppet, {'ip': 'rabbitmq_host', 'port': 'rabbitmq_port'}) + # signals.connect(node1, rabbitmq_service1) + # signals.connect(rabbitmq_service1, openstack_vhost) + # signals.connect(rabbitmq_service1, openstack_rabbitmq_user) + # signals.connect(openstack_vhost, openstack_rabbitmq_user, {'vhost_name': 'vhost_name'}) + # signals.connect(rabbitmq_service1, neutron_puppet, {'ip': 'rabbitmq_host', 'port': 'rabbitmq_port'}) + # signals.connect(openstack_vhost, cinder_puppet, {'vhost_name': 'rabbitmq_vhost'}) + # signals.connect(openstack_rabbitmq_user, cinder_puppet, {'user_name': 'rabbitmq_user', 'password': 'rabbitmq_password'}) + # signals.connect(rabbitmq_service1, cinder_puppet, {'ip': 'rabbitmq_host', 'port': 'rabbitmq_port'}) + # signals.connect(rabbitmq_service1, nova_network_puppet, {'ip': 'rabbitmq_host', 'port': 'rabbitmq_port'}) - signals.connect(node1, puppet_inifile) - signals.connect(node1, puppet_mysql) - signals.connect(node1, puppet_stdlib) + # signals.connect(node1, puppet_inifile) + # signals.connect(node1, puppet_mysql) + # signals.connect(node1, puppet_stdlib) signals.connect(node1, mariadb_service1) signals.connect(node1, keystone_db) @@ -103,41 +109,41 @@ def deploy(): signals.connect(admin_tenant, admin_user) signals.connect(admin_user, admin_role) - signals.connect(keystone_puppet, services_tenant) - signals.connect(keystone_puppet, services_tenant, {'admin_port': 'keystone_port', 'ip': 'keystone_host'}) - signals.connect(services_tenant, neutron_keystone_user) - signals.connect(neutron_keystone_user, neutron_keystone_role) + # signals.connect(keystone_puppet, services_tenant) + # signals.connect(keystone_puppet, services_tenant, {'admin_port': 'keystone_port', 'ip': 'keystone_host'}) + # signals.connect(services_tenant, neutron_keystone_user) + # signals.connect(neutron_keystone_user, neutron_keystone_role) signals.connect(node1, keystone_puppet) signals.connect(keystone_db, keystone_puppet, {'db_name': 'db_name'}) signals.connect(keystone_db_user, keystone_puppet, {'new_user_name': 'db_user', 'new_user_password': 'db_password'}) # NEUTRON - signals.connect(node1, neutron_puppet) - signals.connect(admin_user, neutron_puppet, {'user_name': 'keystone_user', 'user_password': 'keystone_password', 'tenant_name': 'keystone_tenant'}) - signals.connect(keystone_puppet, neutron_puppet, {'ip': 'keystone_host', 'port': 'keystone_port'}) + # signals.connect(node1, neutron_puppet) + # signals.connect(admin_user, neutron_puppet, {'user_name': 'keystone_user', 'user_password': 'keystone_password', 'tenant_name': 'keystone_tenant'}) + # signals.connect(keystone_puppet, neutron_puppet, {'ip': 'keystone_host', 'port': 'keystone_port'}) #signals.connect(neutron_puppet, neutron_keystone_service_endpoint, {'ip': 'ip', 'ssh_key': 'ssh_key', 'ssh_user': 'ssh_user'}) #signals.connect(neutron_puppet, neutron_keystone_service_endpoint, {'port': 'admin_port'}) #signals.connect(keystone_puppet, neutron_keystone_service_endpoint, {'ip': 'keystone_host', 'admin_port': 'keystone_port', 'admin_token': 'admin_token'}) # CINDER - signals.connect(node1, cinder_puppet) - signals.connect(keystone_puppet, cinder_puppet, {'ip': 'keystone_host', 'port': 'keystone_port'}) + # signals.connect(node1, cinder_puppet) + # signals.connect(keystone_puppet, cinder_puppet, {'ip': 'keystone_host', 'port': 'keystone_port'}) - signals.connect(services_tenant, cinder_keystone_user) - signals.connect(cinder_keystone_user, cinder_keystone_role) + # signals.connect(services_tenant, cinder_keystone_user) + # signals.connect(cinder_keystone_user, cinder_keystone_role) - signals.connect(cinder_keystone_user, cinder_puppet, {'user_name': 'keystone_user', 'user_password': 'keystone_password', 'tenant_name': 'keystone_tenant'}) + # signals.connect(cinder_keystone_user, cinder_puppet, {'user_name': 'keystone_user', 'user_password': 'keystone_password', 'tenant_name': 'keystone_tenant'}) # NOVA - signals.connect(node1, nova_network_puppet) + # signals.connect(node1, nova_network_puppet) - signals.connect(services_tenant, nova_keystone_user) - signals.connect(neutron_keystone_user, nova_keystone_role) + # signals.connect(services_tenant, nova_keystone_user) + # signals.connect(neutron_keystone_user, nova_keystone_role) - signals.connect(nova_keystone_user, nova_network_puppet, {'user_name': 'keystone_user', 'user_password': 'keystone_password', 'tenant_name': 'keystone_tenant'}) - signals.connect(keystone_puppet, nova_network_puppet, {'ip': 'keystone_host', 'port': 'keystone_port'}) + # signals.connect(nova_keystone_user, nova_network_puppet, {'user_name': 'keystone_user', 'user_password': 'keystone_password', 'tenant_name': 'keystone_tenant'}) + # signals.connect(keystone_puppet, nova_network_puppet, {'ip': 'keystone_host', 'port': 'keystone_port'}) #signals.connect(nova_network_puppet, nova_keystone_service_endpoint, {'ip': 'ip', 'ssh_key': 'ssh_key', 'ssh_user': 'ssh_user'}) #signals.connect(keystone_puppet, nova_keystone_service_endpoint, {'ip': 'keystone_host', 'admin_port': 'keystone_port', 'admin_token': 'admin_token'}) @@ -159,13 +165,13 @@ def deploy(): # run - actions.resource_action(rabbitmq_service1, 'run') - actions.resource_action(openstack_vhost, 'run') - actions.resource_action(openstack_rabbitmq_user, 'run') + # actions.resource_action(rabbitmq_service1, 'run') + # actions.resource_action(openstack_vhost, 'run') + # actions.resource_action(openstack_rabbitmq_user, 'run') - actions.resource_action(puppet_inifile, 'run') - actions.resource_action(puppet_mysql, 'run') - actions.resource_action(puppet_stdlib, 'run') + # actions.resource_action(puppet_inifile, 'run') + # actions.resource_action(puppet_mysql, 'run') + # actions.resource_action(puppet_stdlib, 'run') actions.resource_action(mariadb_service1, 'run') @@ -177,22 +183,22 @@ def deploy(): actions.resource_action(admin_user, 'run') actions.resource_action(admin_role, 'run') - actions.resource_action(services_tenant, 'run') - actions.resource_action(neutron_keystone_user, 'run') - actions.resource_action(neutron_keystone_role, 'run') + # actions.resource_action(services_tenant, 'run') + # actions.resource_action(neutron_keystone_user, 'run') + # actions.resource_action(neutron_keystone_role, 'run') - actions.resource_action(neutron_puppet, 'run') + # actions.resource_action(neutron_puppet, 'run') #actions.resource_action(neutron_keystone_service_endpoint, 'run') - actions.resource_action(cinder_keystone_user, 'run') - actions.resource_action(cinder_keystone_role, 'run') + # actions.resource_action(cinder_keystone_user, 'run') + # actions.resource_action(cinder_keystone_role, 'run') - actions.resource_action(cinder_puppet, 'run') + # actions.resource_action(cinder_puppet, 'run') - actions.resource_action(nova_keystone_user, 'run') - actions.resource_action(nova_keystone_role, 'run') + # actions.resource_action(nova_keystone_user, 'run') + # actions.resource_action(nova_keystone_role, 'run') - actions.resource_action(nova_network_puppet, 'run') + # actions.resource_action(nova_network_puppet, 'run') #actions.resource_action(nova_keystone_service_endpoint, 'run') time.sleep(10) @@ -201,39 +207,39 @@ def deploy(): #requests.get('http://%s:%s' % (keystone_service1.args['ip'].value, keystone_service1.args['port'].value)) #requests.get('http://%s:%s' % (keystone_service2.args['ip'].value, keystone_service2.args['port'].value)) #requests.get('http://%s:%s' % (haproxy_service.args['ip'].value, haproxy_service.args['ports'].value[0]['value'][0]['value'])) - requests.get('http://%s:%s' % (keystone_puppet.args['ip'].value, keystone_puppet.args['port'].value)) - - for service_name in ['admin', 'neutron', 'cinder', 'nova']: - if service_name == 'admin': - tenant = admin_tenant.args['tenant_name'].value - else: - tenant = services_tenant.args['tenant_name'].value - - if service_name == 'admin': - user = admin_user - elif service_name == 'neutron': - user = neutron_keystone_user - elif service_name == 'cinder': - user = cinder_keystone_user - elif service_name == 'nova': - user = nova_keystone_user - - token_data = requests.post( - 'http://%s:%s/v2.0/tokens' % (keystone_puppet.args['ip'].value, 5000), - json.dumps({ - 'auth': { - 'tenantName': tenant, - 'passwordCredentials': { - 'username': user.args['user_name'].value, - 'password': user.args['user_password'].value, - }, - }, - }), - headers={'Content-Type': 'application/json'} - ) - - token = token_data.json()['access']['token']['id'] - print '{} TOKEN: {}'.format(service_name.upper(), token) + # requests.get('http://%s:%s' % (keystone_puppet.args['ip'].value, keystone_puppet.args['port'].value)) + # + # for service_name in ['admin', 'neutron', 'cinder', 'nova']: + # if service_name == 'admin': + # tenant = admin_tenant.args['tenant_name'].value + # else: + # tenant = services_tenant.args['tenant_name'].value + # + # if service_name == 'admin': + # user = admin_user + # elif service_name == 'neutron': + # user = neutron_keystone_user + # elif service_name == 'cinder': + # user = cinder_keystone_user + # elif service_name == 'nova': + # user = nova_keystone_user + # + # token_data = requests.post( + # 'http://%s:%s/v2.0/tokens' % (keystone_puppet.args['ip'].value, 5000), + # json.dumps({ + # 'auth': { + # 'tenantName': tenant, + # 'passwordCredentials': { + # 'username': user.args['user_name'].value, + # 'password': user.args['user_password'].value, + # }, + # }, + # }), + # headers={'Content-Type': 'application/json'} + # ) + # + # token = token_data.json()['access']['token']['id'] + # print '{} TOKEN: {}'.format(service_name.upper(), token) # neutron_token_data = requests.post( # 'http://%s:%s/v2.0/tokens' % (keystone_puppet.args['ip'].value, 5000), diff --git a/example.py b/example.py index d53682bb..16ba902b 100644 --- a/example.py +++ b/example.py @@ -11,7 +11,7 @@ from solar.core import signals from solar.core import testing from solar.interfaces.db import get_db -from solar.core.resource_provider import GitProvider, RemoteZipProvider +from solar.core.provider import GitProvider, RemoteZipProvider GIT_KEYSTONE_RESOURCE_URL = 'https://github.com/loles/keystone-resource' diff --git a/main.yml b/main.yml index 9235f52f..27b6ebbe 100644 --- a/main.yml +++ b/main.yml @@ -21,6 +21,11 @@ - file: path=/etc/puppet/hieradata state=directory - file: path=/etc/puppetlabs/code/ state=directory - file: src=/etc/puppet/hiera.yaml dest=/etc/puppetlabs/code/hiera.yaml state=link + - apt: name=ruby-dev state=present + - shell: gem install librarian-puppet + - file: path=/tmp/puppet-modules state=directory + - file: path=/tmp/puppet-modules/Puppetfile state=touch + - file: src=/tmp/puppet-modules/modules dest=/etc/puppet/modules state=link # Setup additional development tools - apt: name=vim state=present @@ -49,13 +54,13 @@ #- apt: name=ubuntu-cloud-keyring state=present #- shell: echo "deb http://ubuntu-cloud.archive.canonical.com/ubuntu trusty-updates/kilo main" > /etc/apt/sources.list.d/cloudarchive-kilo.list #- shell: echo "deb http://osci-mirror-poz.infra.mirantis.net/pkgs/ubuntu-2015-06-25-194717 trusty-updates main" > /etc/apt/sources.list.d/fuel-kilo.list - - shell: echo "deb http://osci-mirror-poz.infra.mirantis.net/pkgs/ubuntu-2015-06-25-194717 trusty main" > /etc/apt/sources.list.d/fuel-kilo.list + #- shell: echo "deb http://osci-mirror-poz.infra.mirantis.net/pkgs/ubuntu-latest trusty main" > /etc/apt/sources.list.d/fuel-kilo.list # cloudarchive key - - shell: apt-key adv --recv-key --keyserver keyserver.ubuntu.com 5EDB1B62EC4926EA + #- shell: apt-key adv --recv-key --keyserver keyserver.ubuntu.com 5EDB1B62EC4926EA # some other keys - - shell: apt-key adv --recv-key --keyserver keyserver.ubuntu.com 9D6D8F6BC857C906 - - shell: apt-key adv --recv-key --keyserver keyserver.ubuntu.com 7638D0442B90D010 + #- shell: apt-key adv --recv-key --keyserver keyserver.ubuntu.com 9D6D8F6BC857C906 + #- shell: apt-key adv --recv-key --keyserver keyserver.ubuntu.com 7638D0442B90D010 # mirantis poznan - - shell: apt-key adv --recv-key --keyserver keyserver.ubuntu.com 40976EAF437D05B5 - - shell: apt-key adv --recv-key --keyserver keyserver.ubuntu.com 3B4FE6ACC0B21F32 - - shell: apt-get update + #- shell: apt-key adv --recv-key --keyserver keyserver.ubuntu.com 40976EAF437D05B5 + #- shell: apt-key adv --recv-key --keyserver keyserver.ubuntu.com 3B4FE6ACC0B21F32 + #- shell: apt-get update diff --git a/resources/keystone_puppet/actions/remove.pp b/resources/keystone_puppet/actions/remove.pp new file mode 100644 index 00000000..958de8c7 --- /dev/null +++ b/resources/keystone_puppet/actions/remove.pp @@ -0,0 +1,4 @@ +class {'keystone': + admin_token => '{{ admin_token }}', + package_ensure => 'absent' +} diff --git a/resources/keystone_puppet/actions/run.pp b/resources/keystone_puppet/actions/run.pp new file mode 100644 index 00000000..0ece8356 --- /dev/null +++ b/resources/keystone_puppet/actions/run.pp @@ -0,0 +1,25 @@ +$resource = hiera('{{ resource_name }}') + +$ip = $resource['input']['ip']['value'] +$admin_token = $resource['input']['admin_token']['value'] +$db_user = $resource['input']['db_user']['value'] +$db_password = $resource['input']['db_password']['value'] +$db_name = $resource['input']['db_name']['value'] +$admin_port = $resource['input']['admin_port']['value'] +$port = $resource['input']['port']['value'] + +class {'keystone': + package_ensure => 'present', + verbose => True, + catalog_type => 'sql', + admin_token => $admin_token, + database_connection => "mysql://$db_user:$db_password@$ip/$db_name", + public_port => "$port", + token_driver => 'keystone.token.backends.kvs.Token' +} + +#file { '/etc/keystone/keystone-exports': +# owner => 'root', +# group => 'root', +# content => template('keystone/exports.erb') +#} diff --git a/resources/keystone_puppet/actions/update.pp b/resources/keystone_puppet/actions/update.pp new file mode 100644 index 00000000..eb2ef649 --- /dev/null +++ b/resources/keystone_puppet/actions/update.pp @@ -0,0 +1,7 @@ +class {'keystone': + verbose => True, + catalog_type => 'sql', + admin_token => '{{ admin_token }}', + sql_connection => 'mysql://{{ db_user }}:{{ db_password }}@{{ ip }}/{{ db_name }}', + public_port => '{{ port }}' +} diff --git a/resources/keystone_puppet/meta.yaml b/resources/keystone_puppet/meta.yaml new file mode 100644 index 00000000..e55a9055 --- /dev/null +++ b/resources/keystone_puppet/meta.yaml @@ -0,0 +1,44 @@ +id: keystone_puppet +handler: puppet +puppet_module: keystone +version: 1.0.0 +input: + admin_token: + schema: str! + value: admin_token + db_user: + schema: str! + value: keystone + db_password: + schema: str! + value: keystone + db_name: + schema: str! + value: keystone + + admin_port: + schema: int! + value: 35357 + port: + schema: int! + value: 5000 + + git: + schema: {repository: str!, branch: str!} + value: {repository: 'https://github.com/openstack/puppet-keystone', branch: 'stable/juno'} + +# forge: +# schema: str! +# value: 'stackforge-keystone' + + ip: + schema: str! + value: + ssh_key: + schema: str! + value: + ssh_user: + schema: str! + value: + +tags: [resource/keystone_service, resources/keystone] diff --git a/slave.yml b/slave.yml index bdb8851b..0a2bf440 100644 --- a/slave.yml +++ b/slave.yml @@ -5,3 +5,7 @@ tasks: - lineinfile: line='slaveof 10.0.0.2 6379' dest=/etc/redis/redis.conf - service: name=redis-server state=restarted + + # turn off default ubuntu repos since they conflict with our custom mirrors + #- template: src=/vagrant/sources.list dest=/etc/apt/sources.list + # shell: apt-get update diff --git a/solar/solar/core/handlers/puppet.py b/solar/solar/core/handlers/puppet.py index d111b30f..7599b6bb 100644 --- a/solar/solar/core/handlers/puppet.py +++ b/solar/solar/core/handlers/puppet.py @@ -1,10 +1,109 @@ # -*- coding: utf-8 -*- +from contextlib import nested + from fabric import api as fabric_api from fabric.contrib import project as fabric_project import os from solar.core.log import log from solar.core.handlers.base import BaseHandler +from solar.core.provider import GitProvider + + +class ResourceSSHMixin(object): + @staticmethod + def _ssh_command(resource, *args, **kwargs): + log.debug('SSH: %s', args) + + managers = [ + fabric_api.settings(**ResourceSSHMixin._fabric_settings(resource)), + ] + + if 'cwd' in kwargs: + managers.append( + fabric_api.cd(kwargs['cwd']) + ) + + with nested(*managers): + return fabric_api.run(' '.join(args)) + + @staticmethod + def _scp_command(resource, _from, _to): + log.debug('SCP: %s -> %s', _from, _to) + + with fabric_api.settings(**ResourceSSHMixin._fabric_settings(resource)): + return fabric_project.rsync_project(_to, local_dir=_from) + + @staticmethod + def _fabric_settings(resource): + return { + 'host_string': ResourceSSHMixin._ssh_command_host(resource), + 'key_filename': resource.args['ssh_key'].value, + } + + @staticmethod + def _ssh_command_host(resource): + return '{}@{}'.format(resource.args['ssh_user'].value, + resource.args['ip'].value) + + +class LibrarianPuppet(ResourceSSHMixin): + def __init__(self, resource, organization='openstack'): + self.resource = resource + self.organization = organization + + def install(self): + puppet_module = '{}-{}'.format( + self.organization, + self.resource.metadata['puppet_module'] + ) + + puppetlabs = self._ssh_command( + self.resource, + 'sudo', 'cat', '/tmp/puppet-modules/Puppetfile' + ) + + git = self.resource.args['git'].value + + definition = "mod '{module_name}', :git => '{repository}', :ref => '{branch}'".format( + module_name=puppet_module, + repository=git['repository'], + branch=git['branch'] + ) + + modules = puppetlabs.split('\n') + + idx = -1 + for i, module in enumerate(modules): + if "mod '{}'".format(puppet_module) in module: + log.debug('Module {} found in librarian Puppetfile, overwriting'.format(puppet_module)) + idx = i + modules[i] = definition + break + + if idx == -1: + log.debug('Adding module {} to librarian Puppetfile'.format(puppet_module)) + modules.append(definition) + + with open('/tmp/Puppetfile', 'w') as f: + f.write('\n'.join(modules)) + + self._scp_command( + self.resource, + '/tmp/Puppetfile', + '/tmp/Puppetfile' + ) + + self._ssh_command( + self.resource, + 'sudo', 'cp', '/tmp/Puppetfile', '/tmp/puppet-modules/Puppetfile' + ) + + self._ssh_command( + self.resource, + 'sudo', 'librarian-puppet', 'install', + cwd='/tmp/puppet-modules' + ) # NOTE: We assume that: @@ -12,13 +111,63 @@ from solar.core.handlers.base import BaseHandler # - hiera-redis is installed with the 2.0 fix (https://github.com/GGenie/hiera-redis) # - redis is installed and cluster set up with master (on slaves set up 'slaveof 10.0.0.2 6379') # - redis keys are separated by colon (same as in hiera-redis backend) -class Puppet(BaseHandler): +class Puppet(ResourceSSHMixin, BaseHandler): def action(self, resource, action_name): - print 'Executing Puppet manifest ', action_name, resource + log.debug('Executing Puppet manifest %s %s', action_name, resource) action_file = self._compile_action_file(resource, action_name) log.debug('action_file: %s', action_file) + self.upload_manifests(resource) + + self._scp_command(resource, action_file, '/tmp/action.pp') + + self._ssh_command( + resource, 'sudo', 'puppet', 'apply', '/tmp/action.pp' + ) + + def clone_manifests(self, resource): + git = resource.args['git'].value + p = GitProvider(git['repository'], branch=git['branch']) + + return p.directory + + def upload_manifests(self, resource): + if 'forge' in resource.args and resource.args['forge'].value: + self.upload_manifests_forge(resource) + else: + self.upload_manifests_librarian(resource) + + def upload_manifests_forge(self, resource): + forge = resource.args['forge'].value + + # Check if module already installed + modules = self._ssh_command( + resource, + 'sudo', 'puppet', 'module', 'list' + ) + + module_installed = False + for module in modules.decode('utf-8').split('\n'): + if forge in module: + module_installed = True + break + + if not module_installed: + self._ssh_command( + resource, + 'sudo', 'puppet', 'module', 'install', forge + ) + else: + log.debug('Skipping module installation, already installed') + + def upload_manifests_librarian(self, resource): + librarian = LibrarianPuppet(resource) + librarian.install() + + def upload_manifests_git(self, resource): + manifests_path = self.clone_manifests(resource) + module_directory = '/etc/puppet/modules/{}'.format( resource.metadata['puppet_module'] ) @@ -30,41 +179,10 @@ class Puppet(BaseHandler): resource, 'sudo', 'mkdir', '-p', module_directory ) - self._scp_command( + self._scp_command(resource, manifests_path, '/tmp') + self._ssh_command( resource, - os.path.join(resource.metadata['base_path'], 'puppet'), - '/tmp' + 'sudo', 'mv', + '/tmp/{}/*'.format(os.path.split(manifests_path)[1]), + module_directory ) - self._ssh_command( - resource, 'sudo', 'mv', '/tmp/puppet/*', module_directory - ) - - self._scp_command(resource, action_file, '/tmp/action.pp') - - self._ssh_command( - resource, 'sudo', 'puppet', 'apply', '/tmp/action.pp' - ) - - def _ssh_command(self, resource, *args): - print 'SSH ', args - - with fabric_api.settings(**self._fabric_settings(resource)): - return fabric_api.run(' '.join(args)) - - def _scp_command(self, resource, _from, _to): - print 'SCP: ', _from, _to - - with fabric_api.settings(**self._fabric_settings(resource)): - #return fabric_api.put(_from, _to) - return fabric_project.rsync_project(_to, local_dir=_from) - - - def _fabric_settings(self, resource): - return { - 'host_string': self._ssh_command_host(resource), - 'key_filename': resource.args['ssh_key'].value, - } - - def _ssh_command_host(self, resource): - return '{}@{}'.format(resource.args['ssh_user'].value, - resource.args['ip'].value) diff --git a/solar/solar/core/resource_provider.py b/solar/solar/core/provider.py similarity index 53% rename from solar/solar/core/resource_provider.py rename to solar/solar/core/provider.py index 88cb2ab7..65397a98 100644 --- a/solar/solar/core/resource_provider.py +++ b/solar/solar/core/provider.py @@ -8,50 +8,62 @@ from solar import utils class BaseProvider(object): + def __init__(self, base_path=None): + if base_path is None: + self.base_path = utils.read_config()['resources-directory'] + else: + self.base_path = base_path + def run(self): pass class DirectoryProvider(BaseProvider): - def __init__(self, directory): + def __init__(self, directory, *args, **kwargs): self.directory = directory + super(DirectoryProvider, self).__init__(*args, **kwargs) + class GitProvider(BaseProvider): - def __init__(self, repository, path='.'): + def __init__(self, repository, branch='master', path='.', *args, **kwargs): + super(GitProvider, self).__init__(*args, **kwargs) + self.repository = repository + self.branch = 'master' self.path = path - resources_directory = self._resources_directory() + directory = self._directory() - if not os.path.exists(resources_directory): + if not os.path.exists(directory): self._clone_repo() if path != '.': - self.directory = os.path.join(resources_directory, path) + self.directory = os.path.join(directory, path) else: - self.directory = resources_directory + self.directory = directory - def _resources_directory(self): + def _directory(self): repo_name = os.path.split(self.repository)[1] return os.path.join( - utils.read_config()['resources-directory'], + self.base_path, repo_name ) def _clone_repo(self): - resources_directory = self._resources_directory() + directory = self._directory() with open('/tmp/git-provider.yaml', 'w') as f: f.write(""" --- - hosts: all tasks: - - git: repo={repository} dest={destination} clone={clone} update=yes + - git: repo={repository} dest={destination} clone={clone} update=yes version={branch} """.format( repository=self.repository, - destination=resources_directory, + branch=self.branch, + destination=directory, clone='yes' )) @@ -70,7 +82,9 @@ class RemoteZipProvider(BaseProvider): ... """ - def __init__(self, url, path='.'): + def __init__(self, url, path='.', *args, **kwargs): + super(RemoteZipProvider, self).__init__(*args, **kwargs) + self.url = url self.path = path @@ -79,14 +93,13 @@ class RemoteZipProvider(BaseProvider): z = zipfile.ZipFile(s) group_name = os.path.dirname(z.namelist()[0]) - base_resources_directory = utils.read_config()['resources-directory'] - resources_directory = os.path.join( - base_resources_directory, group_name + directory = os.path.join( + self.base_path, group_name ) - if not os.path.exists(resources_directory): - z.extractall(base_resources_directory) + if not os.path.exists(directory): + z.extractall(self.base_path) if path != '.': - self.directory = os.path.join(resources_directory, path) + self.directory = os.path.join(directory, path) else: - self.directory = resources_directory + self.directory = directory diff --git a/solar/solar/core/virtual_resource.py b/solar/solar/core/virtual_resource.py index 65c9db04..e5616fa5 100644 --- a/solar/solar/core/virtual_resource.py +++ b/solar/solar/core/virtual_resource.py @@ -9,14 +9,12 @@ from jinja2 import Template, Environment, meta from solar import utils from solar.core import validation from solar.core import resource as resource_module -from solar.core import resource_provider +from solar.core import provider from solar.core import signals def create_resource(name, base_path, args, virtual_resource=None): - from solar.core import resource_provider - - if isinstance(base_path, resource_provider.BaseProvider): + if isinstance(base_path, provider.BaseProvider): base_path = base_path.directory base_meta_file = os.path.join(base_path, 'meta.yaml') @@ -66,8 +64,9 @@ def create_virtual_resource(vr_name, template): def create(name, base_path, kwargs, virtual_resource=None): - if isinstance(base_path, resource_provider.BaseProvider): + if isinstance(base_path, provider.BaseProvider): base_path = base_path.directory + if not os.path.exists(base_path): raise Exception( 'Base resource does not exist: {0}'.format(base_path)