Puppet: lots of fixes & improvements

- resource_provider became a general provider for git/zip/whatever data
- library-puppet is used to install & manage all dependencies
- keystone_puppet resource is added, with manifests from openstack git
This commit is contained in:
Przemyslaw Kaminski 2015-07-09 12:36:36 +02:00
parent 420bb124b7
commit 7323a842da
11 changed files with 399 additions and 174 deletions

View File

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

View File

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

View File

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

View File

@ -0,0 +1,4 @@
class {'keystone':
admin_token => '{{ admin_token }}',
package_ensure => 'absent'
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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