Merge pull request #101 from xarses/vr

Virtual Resources
This commit is contained in:
CGenie 2015-06-30 12:08:43 +02:00
commit c96203073b
35 changed files with 498 additions and 170 deletions

View File

@ -5,16 +5,16 @@ import sys
import time import time
from solar.core import actions from solar.core import actions
from solar.core import virtual_resource as vr
from solar.core import resource from solar.core import resource
from solar.core import signals from solar.core import signals
from solar.core import validation
from solar.interfaces.db import get_db from solar.interfaces.db import get_db
from solar.core.resource_provider import GitProvider, RemoteZipProvider from solar.core.resource_provider import GitProvider, RemoteZipProvider
GIT_KEYSTONE_RESOURCE_URL = 'https://github.com/CGenie/keystone-resource' GIT_KEYSTONE_RESOURCE_URL = 'https://github.com/loles/keystone-resource'
ZIP_KEYSTONE_RESOURCE_URL = 'https://github.com/CGenie/keystone-resource/archive/master.zip' ZIP_KEYSTONE_RESOURCE_URL = 'https://github.com/loles/keystone-resource/archive/master.zip'
@click.group() @click.group()
@ -29,51 +29,51 @@ def deploy():
signals.Connections.clear() signals.Connections.clear()
node1 = resource.create('node1', 'resources/ro_node/', {'ip': '10.0.0.3', 'ssh_key': '/vagrant/.vagrant/machines/solar-dev1/virtualbox/private_key', 'ssh_user': 'vagrant'}) 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]
node2 = resource.create('node2', 'resources/ro_node/', {'ip': '10.0.0.4', 'ssh_key': '/vagrant/.vagrant/machines/solar-dev2/virtualbox/private_key', 'ssh_user': 'vagrant'}) node2 = vr.create('node2', 'resources/ro_node/', {'ip': '10.0.0.4', 'ssh_key': '/vagrant/.vagrant/machines/solar-dev2/virtualbox/private_key', 'ssh_user': 'vagrant'})[0]
rabbitmq_service1 = resource.create('rabbitmq_service1', 'resources/rabbitmq_service/', {'management_port': '15672', 'port': '5672', 'container_name': 'rabbitmq_service1', 'image': 'rabbitmq:3-management'}) 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 = resource.create('openstack_vhost', 'resources/rabbitmq_vhost/', {'vhost_name': 'openstack'}) openstack_vhost = vr.create('openstack_vhost', 'resources/rabbitmq_vhost/', {'vhost_name': 'openstack'})[0]
openstack_rabbitmq_user = resource.create('openstack_rabbitmq_user', 'resources/rabbitmq_user/', {'user_name': 'openstack', 'password': 'openstack_password'}) openstack_rabbitmq_user = vr.create('openstack_rabbitmq_user', 'resources/rabbitmq_user/', {'user_name': 'openstack', 'password': 'openstack_password'})[0]
mariadb_service1 = resource.create('mariadb_service1', 'resources/mariadb_service', {'image': 'mariadb', 'root_password': 'mariadb', 'port': 3306}) mariadb_service1 = vr.create('mariadb_service1', 'resources/mariadb_service', {'image': 'mariadb', 'root_password': 'mariadb', 'port': 3306})[0]
keystone_db = resource.create('keystone_db', 'resources/mariadb_keystone_db/', {'db_name': 'keystone_db', 'login_user': 'root'}) keystone_db = vr.create('keystone_db', 'resources/mariadb_keystone_db/', {'db_name': 'keystone_db', 'login_user': 'root'})[0]
keystone_db_user = resource.create('keystone_db_user', 'resources/mariadb_keystone_user/', {'new_user_name': 'keystone', 'new_user_password': 'keystone', 'login_user': 'root'}) keystone_db_user = vr.create('keystone_db_user', 'resources/mariadb_user/', {'user_name': 'keystone', 'user_password': 'keystone', 'login_user': 'root'})[0]
keystone_config1 = resource.create('keystone_config1', GitProvider(GIT_KEYSTONE_RESOURCE_URL, path='keystone_config'), {'config_dir': '/etc/solar/keystone', 'admin_token': 'admin'}) keystone_config1 = vr.create('keystone_config1', GitProvider(GIT_KEYSTONE_RESOURCE_URL, path='keystone_config'), {'config_dir': '/etc/solar/keystone', 'admin_token': 'admin'})[0]
keystone_service1 = resource.create('keystone_service1', RemoteZipProvider(ZIP_KEYSTONE_RESOURCE_URL, 'keystone_service'), {'port': 5001, 'admin_port': 35357}) keystone_service1 = vr.create('keystone_service1', RemoteZipProvider(ZIP_KEYSTONE_RESOURCE_URL, 'keystone_service'), {'port': 5001, 'admin_port': 35357})[0]
keystone_config2 = resource.create('keystone_config2', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_config'), {'config_dir': '/etc/solar/keystone', 'admin_token': 'admin'}) keystone_config2 = vr.create('keystone_config2', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_config'), {'config_dir': '/etc/solar/keystone', 'admin_token': 'admin'})[0]
keystone_service2 = resource.create('keystone_service2', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_service'), {'port': 5002, 'admin_port': 35358}) keystone_service2 = vr.create('keystone_service2', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_service'), {'port': 5002, 'admin_port': 35358})[0]
haproxy_keystone_config = resource.create('haproxy_keystone1_config', 'resources/haproxy_service_config/', {'name': 'keystone_config', 'listen_port': 5000, 'servers':[], 'ports':[]}) haproxy_keystone_config = vr.create('haproxy_keystone1_config', 'resources/haproxy_service_config/', {'name': 'keystone_config', 'listen_port': 5000, 'servers':[], 'ports':[]})[0]
haproxy_config = resource.create('haproxy_config', 'resources/haproxy_config', {'configs_names':[], 'configs_ports':[], 'listen_ports':[], 'configs':[]}) haproxy_config = vr.create('haproxy_config', 'resources/haproxy_config', {'configs_names':[], 'configs_ports':[], 'listen_ports':[], 'configs':[]})[0]
haproxy_service = resource.create('haproxy_service', 'resources/docker_container/', {'image': 'tutum/haproxy', 'ports': [], 'host_binds': [], 'volume_binds':[]}) haproxy_service = vr.create('haproxy_service', 'resources/docker_container/', {'image': 'tutum/haproxy', 'ports': [], 'host_binds': [], 'volume_binds':[]})[0]
glance_db = resource.create('glance_db', 'resources/mariadb_db/', {'db_name': 'glance_db', 'login_user': 'root'}) glance_db = vr.create('glance_db', 'resources/mariadb_db/', {'db_name': 'glance_db', 'login_user': 'root'})[0]
glance_db_user = resource.create('glance_db_user', 'resources/mariadb_user/', {'new_user_name': 'glance', 'new_user_password': 'glance', 'login_user': 'root'}) glance_db_user = vr.create('glance_db_user', 'resources/mariadb_user/', {'user_name': 'glance', 'user_password': 'glance', 'login_user': 'root'})[0]
services_tenant = resource.create('glance_keystone_tenant', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_tenant'), {'tenant_name': 'services'}) services_tenant = vr.create('glance_keystone_tenant', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_tenant'), {'tenant_name': 'services'})[0]
glance_keystone_user = resource.create('glance_keystone_user', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_user'), {'user_name': 'glance_admin', 'user_password': 'password1234', 'tenant_name': 'service_admins'}) glance_keystone_user = vr.create('glance_keystone_user', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_user'), {'user_name': 'glance_admin', 'user_password': 'password1234', 'tenant_name': 'service_admins'})[0]
glance_keystone_role = resource.create('glance_keystone_role', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_role'), {'role_name': 'admin'}) glance_keystone_role = vr.create('glance_keystone_role', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_role'), {'role_name': 'admin'})[0]
# TODO: add api_host and registry_host -- they can be different! Currently 'ip' is used. # TODO: add api_host and registry_host -- they can be different! Currently 'ip' is used.
glance_config = resource.create('glance_config', 'resources/glance_config/', {'api_port': 9393}) glance_config = vr.create('glance_config', 'resources/glance_config/', {'api_port': 9393})[0]
glance_api_container = resource.create('glance_api_container', 'resources/glance_api_service/', {'image': 'cgenie/centos-rdo-glance-api', 'ports': [{'value': [{'value': 9393}]}], 'host_binds': [], 'volume_binds': []}) glance_api_container = vr.create('glance_api_container', 'resources/glance_api_service/', {'image': 'cgenie/centos-rdo-glance-api', 'ports': [{'value': [{'value': 9393}]}], 'host_binds': [], 'volume_binds': []})[0]
glance_registry_container = resource.create('glance_registry_container', 'resources/glance_registry_service/', {'image': 'cgenie/centos-rdo-glance-registry', 'ports': [{'value': [{'value': 9191}]}], 'host_binds': [], 'volume_binds': []}) glance_registry_container = vr.create('glance_registry_container', 'resources/glance_registry_service/', {'image': 'cgenie/centos-rdo-glance-registry', 'ports': [{'value': [{'value': 9191}]}], 'host_binds': [], 'volume_binds': []})[0]
# TODO: admin_port should be refactored, we need to rethink docker # TODO: admin_port should be refactored, we need to rethink docker
# container resource and make it common for all # container resource and make it common for all
# resources used in this demo # resources used in this demo
glance_api_endpoint = resource.create('glance_api_endpoint', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_service_endpoint'), {'adminurl': 'http://{{ip}}:{{admin_port}}', 'internalurl': 'http://{{ip}}:{{port}}', 'publicurl': 'http://{{ip}}:{{port}}', 'description': 'OpenStack Image Service', 'type': 'image'}) glance_api_endpoint = vr.create('glance_api_endpoint', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_service_endpoint'), {'adminurl': 'http://{{ip}}:{{admin_port}}', 'internalurl': 'http://{{ip}}:{{port}}', 'publicurl': 'http://{{ip}}:{{port}}', 'description': 'OpenStack Image Service', 'type': 'image'})[0]
# TODO: ports value 9393 is a HACK -- fix glance_api_container's port and move to some config # TODO: ports value 9393 is a HACK -- fix glance_api_container's port and move to some config
# TODO: glance registry container's API port needs to point to haproxy_config # TODO: glance registry container's API port needs to point to haproxy_config
haproxy_glance_api_config = resource.create('haproxy_glance_api_config', 'resources/haproxy_service_config/', {'name': 'glance_api_config', 'listen_port': 9292, 'servers': [], 'ports':[{'value': 9393}]}) haproxy_glance_api_config = vr.create('haproxy_glance_api_config', 'resources/haproxy_service_config/', {'name': 'glance_api_config', 'listen_port': 9292, 'servers': [], 'ports':[{'value': 9393}]})[0]
admin_tenant = resource.create('admin_tenant', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_tenant'), {'tenant_name': 'admin'}) admin_tenant = vr.create('admin_tenant', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_tenant'), {'tenant_name': 'admin'})[0]
admin_user = resource.create('admin_user', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_user'), {'user_name': 'admin', 'user_password': 'admin'}) admin_user = vr.create('admin_user', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_user'), {'user_name': 'admin', 'user_password': 'admin'})[0]
admin_role = resource.create('admin_role', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_role'), {'role_name': 'admin'}) admin_role = vr.create('admin_role', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_role'), {'role_name': 'admin'})[0]
keystone_service_endpoint = resource.create('keystone_service_endpoint', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_service_endpoint'), {'adminurl': 'http://{{ip}}:{{admin_port}}/v2.0', 'internalurl': 'http://{{ip}}:{{port}}/v2.0', 'publicurl': 'http://{{ip}}:{{port}}/v2.0', 'description': 'OpenStack Identity Service', 'type': 'identity'}) keystone_service_endpoint = vr.create('keystone_service_endpoint', GitProvider(GIT_KEYSTONE_RESOURCE_URL, 'keystone_service_endpoint'), {'adminurl': 'http://{{ip}}:{{admin_port}}/v2.0', 'internalurl': 'http://{{ip}}:{{port}}/v2.0', 'publicurl': 'http://{{ip}}:{{port}}/v2.0', 'description': 'OpenStack Identity Service', 'type': 'identity'})[0]
#### ####
@ -100,14 +100,14 @@ def deploy():
signals.connect(node1, keystone_config1) signals.connect(node1, keystone_config1)
signals.connect(mariadb_service1, keystone_config1, {'ip': 'db_host', 'port': 'db_port'}) signals.connect(mariadb_service1, keystone_config1, {'ip': 'db_host', 'port': 'db_port'})
signals.connect(keystone_db_user, keystone_config1, {'db_name': 'db_name', 'new_user_name': 'db_user', 'new_user_password': 'db_password'}) signals.connect(keystone_db_user, keystone_config1, {'db_name': 'db_name', 'user_name': 'db_user', 'user_password': 'db_password'})
signals.connect(node1, keystone_service1) signals.connect(node1, keystone_service1)
signals.connect(keystone_config1, keystone_service1, {'config_dir': 'config_dir'}) signals.connect(keystone_config1, keystone_service1, {'config_dir': 'config_dir'})
signals.connect(node2, keystone_config2) signals.connect(node2, keystone_config2)
signals.connect(mariadb_service1, keystone_config2, {'ip': 'db_host', 'port': 'db_port'}) signals.connect(mariadb_service1, keystone_config2, {'ip': 'db_host', 'port': 'db_port'})
signals.connect(keystone_db_user, keystone_config2, {'db_name': 'db_name', 'new_user_name': 'db_user', 'new_user_password': 'db_password'}) signals.connect(keystone_db_user, keystone_config2, {'db_name': 'db_name', 'user_name': 'db_user', 'user_password': 'db_password'})
signals.connect(node2, keystone_service2) signals.connect(node2, keystone_service2)
signals.connect(keystone_config2, keystone_service2, {'config_dir': 'config_dir'}) signals.connect(keystone_config2, keystone_service2, {'config_dir': 'config_dir'})
@ -153,11 +153,11 @@ def deploy():
signals.connect(haproxy_service, glance_config, {'ip': 'keystone_ip'}) signals.connect(haproxy_service, glance_config, {'ip': 'keystone_ip'})
signals.connect(mariadb_service1, glance_config, {'ip': 'mysql_ip'}) signals.connect(mariadb_service1, glance_config, {'ip': 'mysql_ip'})
signals.connect(glance_db, glance_config, {'db_name': 'mysql_db'}) signals.connect(glance_db, glance_config, {'db_name': 'mysql_db'})
signals.connect(glance_db_user, glance_config, {'new_user_name': 'mysql_user', 'new_user_password': 'mysql_password'}) signals.connect(glance_db_user, glance_config, {'user_name': 'mysql_user', 'user_password': 'mysql_password'})
signals.connect(node2, glance_api_container) signals.connect(node2, glance_api_container)
signals.connect(glance_config, glance_api_container, {'config_dir': 'host_binds'}) signals.connect(glance_config, glance_api_container, {'config_dir': 'host_binds'})
signals.connect(glance_db_user, glance_api_container, {'new_user_password': 'db_password'}) signals.connect(glance_db_user, glance_api_container, {'user_password': 'db_password'})
signals.connect(glance_keystone_user, glance_api_container, {'user_password': 'keystone_password'}) signals.connect(glance_keystone_user, glance_api_container, {'user_password': 'keystone_password'})
signals.connect(glance_keystone_user, glance_api_container, {'admin_token': 'keystone_admin_token'}) signals.connect(glance_keystone_user, glance_api_container, {'admin_token': 'keystone_admin_token'})
signals.connect(haproxy_config, glance_api_container, {'ip': 'keystone_host'}) signals.connect(haproxy_config, glance_api_container, {'ip': 'keystone_host'})
@ -165,13 +165,6 @@ def deploy():
signals.connect(node2, glance_registry_container) signals.connect(node2, glance_registry_container)
signals.connect(glance_config, glance_registry_container, {'config_dir': 'host_binds'}) signals.connect(glance_config, glance_registry_container, {'config_dir': 'host_binds'})
signals.connect(mariadb_service1, glance_registry_container, {'ip': 'db_host'})
signals.connect(glance_db, glance_registry_container, {'db_name': 'db_name', 'login_password': 'db_root_password'})
signals.connect(glance_db_user, glance_registry_container, {'new_user_name': 'db_user', 'new_user_password': 'db_password'})
signals.connect(glance_keystone_user, glance_registry_container, {'tenant_name': 'keystone_admin_tenant', 'user_name': 'keystone_user', 'user_password': 'keystone_password'})
signals.connect(glance_keystone_user, glance_registry_container, {'admin_token': 'keystone_admin_token'})
signals.connect(haproxy_config, glance_registry_container, {'ip': 'keystone_host'})
# glance haproxy # glance haproxy
signals.connect(glance_api_container, haproxy_glance_api_config, {'ip': 'servers'}) signals.connect(glance_api_container, haproxy_glance_api_config, {'ip': 'servers'})
#signals.connect(glance_config, haproxy_glance_api_config, {'api_port': 'ports'}) #signals.connect(glance_config, haproxy_glance_api_config, {'api_port': 'ports'})
@ -186,18 +179,10 @@ def deploy():
signals.connect(haproxy_glance_api_config, glance_api_endpoint, {'listen_port': 'port'}) signals.connect(haproxy_glance_api_config, glance_api_endpoint, {'listen_port': 'port'})
has_errors = False errors = vr.validate_resources()
for r in locals().values(): if errors:
if not isinstance(r, resource.Resource): for r, error in errors:
continue print 'ERROR: %s: %s' % (r.name, error)
print 'Validating {}'.format(r.name)
errors = validation.validate_resource(r)
if errors:
has_errors = True
print 'ERROR: %s: %s' % (r.name, errors)
if has_errors:
sys.exit(1) sys.exit(1)

View File

@ -2,5 +2,5 @@
- hosts: [{{ ip }}] - hosts: [{{ ip }}]
sudo: yes sudo: yes
tasks: tasks:
- shell: docker stop {{ name }} - shell: docker stop {{ resource_name }}
- shell: docker rm {{ name }} - shell: docker rm {{ resource_name }}

View File

@ -2,7 +2,7 @@
sudo: yes sudo: yes
tasks: tasks:
- docker: - docker:
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: running state: running
net: host net: host

View File

@ -2,5 +2,5 @@
- hosts: [{{ ip }}] - hosts: [{{ ip }}]
sudo: yes sudo: yes
tasks: tasks:
- shell: docker stop {{ name }} - shell: docker stop {{ resource_name }}
- shell: docker rm {{ name }} - shell: docker rm {{ resource_name }}

View File

@ -3,7 +3,7 @@
sudo: yes sudo: yes
tasks: tasks:
- docker: - docker:
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: running state: running
net: host net: host

View File

@ -3,6 +3,6 @@
tasks: tasks:
- name: glance api container - name: glance api container
docker: docker:
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: absent state: absent

View File

@ -5,7 +5,7 @@
- docker: - docker:
command: /bin/bash -c "glance-manage db_sync && /usr/bin/glance-api" command: /bin/bash -c "glance-manage db_sync && /usr/bin/glance-api"
#command: /usr/bin/glance-api #command: /usr/bin/glance-api
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: running state: running
expose: expose:

View File

@ -3,6 +3,6 @@
tasks: tasks:
- name: glance registry container - name: glance registry container
docker: docker:
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: absent state: absent

View File

@ -5,7 +5,7 @@
- docker: - docker:
#command: /bin/bash -c "glance-manage db_sync && /usr/bin/glance-registry" #command: /bin/bash -c "glance-manage db_sync && /usr/bin/glance-registry"
command: /usr/bin/glance-registry command: /usr/bin/glance-registry
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: running state: running
net: host net: host

View File

@ -7,7 +7,7 @@ input:
value: value:
image: image:
schema: str! schema: str!
value: value: cgenie/centos-rdo-glance-registry
ports: ports:
schema: [{value: [{value: int}]}] schema: [{value: [{value: int}]}]
value: [] value: []
@ -24,35 +24,4 @@ input:
schema: str! schema: str!
value: [] value: []
db_host:
schema: str!
value:
db_root_password:
schema: str!
value:
db_name:
schema: str!
value:
db_password:
schema: str!
value:
db_user:
schema: str!
value:
keystone_admin_token:
schema: str!
value:
keystone_admin_tenant:
schema: str!
value:
keystone_user:
schema: str!
value:
keystone_password:
schema: str!
value:
keystone_host:
schema: str!
value:
tags: [resource/container] tags: [resource/container]

View File

@ -3,6 +3,6 @@
tasks: tasks:
- name: haproxy container - name: haproxy container
docker: docker:
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: absent state: absent

View File

@ -3,7 +3,7 @@
sudo: yes sudo: yes
tasks: tasks:
- docker: - docker:
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: running state: running
net: host net: host

View File

@ -5,5 +5,5 @@
- name: keystone container - name: keystone container
docker: docker:
image: {{ image }} image: {{ image }}
name: {{ name }} name: {{ resource_name }}
state: absent state: absent

View File

@ -4,7 +4,7 @@
- name: keystone container - name: keystone container
docker: docker:
command: /bin/bash -c "keystone-manage db_sync && /usr/bin/keystone-all" command: /bin/bash -c "keystone-manage db_sync && /usr/bin/keystone-all"
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: running state: running
expose: expose:

View File

@ -1,14 +1,10 @@
- hosts: [{{ ip }}] - hosts: [{{ ip }}]
sudo: yes sudo: yes
vars:
ip: {{ip}}
port: {{port}}
admin_port: {{admin_port}}
tasks: tasks:
- name: keystone service and endpoint - name: keystone service and endpoint
keystone_service: keystone_service:
token: {{admin_token}} token: {{admin_token}}
name: {{name}} name: {{resource_name}}
type: {{type}} type: {{type}}
description: {{description}} description: {{description}}
publicurl: {{publicurl}} publicurl: {{publicurl}}
@ -16,4 +12,4 @@
adminurl: {{adminurl}} adminurl: {{adminurl}}
region: "RegionOne" region: "RegionOne"
state: present state: present
endpoint: http://{{keystone_host}}:{{keystone_port}}/v2.0/ endpoint: http://{{keystone_host}}:{{keystone_admin_port}}/v2.0/

View File

@ -5,36 +5,39 @@ input:
keystone_host: keystone_host:
schema: str! schema: str!
value: value:
keystone_port: keystone_admin_port:
schema: int! schema: int!
value: value:
admin_token: admin_token:
schema: str! schema: str!
value: value:
port:
schema: int!
value:
admin_port:
schema: int!
value:
type: type:
schema: str! schema: str!
value: identity
description: description:
schema: str! schema: str!
value: OpenStack Identity Service name:
schema: str!
public_ip:
schema: str!
public_port:
schema: int!
publicurl: publicurl:
schema: str! schema: str!
value: http://{{ip}}:{{port}}/v2.0 value: http://{{public_ip}}:{{public_port}}/v2.0
internal_ip:
schema: str!
internal_port:
schema: int!
internalurl: internalurl:
schema: str! schema: str!
value: http://{{ip}}:{{port}}/v2.0 value: http://{{ip}}:{{port}}/v2.0
admin_ip:
schema: str!
admin_port:
schema: int!
adminurl: adminurl:
schema: str! schema: str!
value: http://{{ip}}:{{admin_port}}/v2.0 value: http://{{ip}}:{{admin_port}}/v2.0
adminurl:
schema: str!
value:
ip: ip:
schema: str! schema: str!
value: value:

View File

@ -3,6 +3,6 @@
tasks: tasks:
- name: mariadb container - name: mariadb container
docker: docker:
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: absent state: absent

View File

@ -3,7 +3,7 @@
tasks: tasks:
- name: mariadb container - name: mariadb container
docker: docker:
name: {{ name }} name: {{ resource_name }}
image: {{ image }} image: {{ image }}
state: running state: running
ports: ports:
@ -11,7 +11,7 @@
env: env:
MYSQL_ROOT_PASSWORD: {{ root_password }} MYSQL_ROOT_PASSWORD: {{ root_password }}
- shell: docker exec -t {{ name }} mysql -p{{ root_password }} -uroot -e "SELECT 1" - shell: docker exec -t {{ resource_name }} mysql -p{{ root_password }} -uroot -e "SELECT 1"
register: result register: result
until: result.rc == 0 until: result.rc == 0
retries: 30 retries: 30

View File

@ -3,7 +3,7 @@
tasks: tasks:
- name: mariadb user - name: mariadb user
mysql_user: mysql_user:
name: {{new_user_name}} name: {{user_name}}
state: absent state: absent
login_user: root login_user: root
login_password: {{login_password}} login_password: {{login_password}}

View File

@ -3,8 +3,8 @@
tasks: tasks:
- name: mariadb user - name: mariadb user
mysql_user: mysql_user:
name: {{ new_user_name }} name: {{ user_name }}
password: {{ new_user_password }} password: {{ user_password }}
priv: {{ db_name }}.*:ALL priv: {{ db_name }}.*:ALL
host: '%' host: '%'
state: present state: present

View File

@ -5,10 +5,10 @@ actions:
run: run.yml run: run.yml
remove: remove.yml remove: remove.yml
input: input:
new_user_password: user_password:
schema: str! schema: str!
value: value:
new_user_name: user_name:
schema: str! schema: str!
value: value:
db_name: db_name:

View File

@ -9,10 +9,10 @@ input:
schema: str! schema: str!
value: rabbitmq_service value: rabbitmq_service
management_port: management_port:
schema: str! schema: int!
value: 15672 value: 15672
port: port:
schema: str! schema: int!
value: 5672 value: 5672
ip: ip:
schema: str! schema: str!

View File

@ -33,6 +33,7 @@ from solar.core import resource as sresource
from solar.core.resource import assign_resources_to_nodes from solar.core.resource import assign_resources_to_nodes
from solar.core import signals from solar.core import signals
from solar.core.tags_set_parser import Expression from solar.core.tags_set_parser import Expression
from solar.core import virtual_resource as vr
from solar.interfaces.db import get_db from solar.interfaces.db import get_db
# NOTE: these are extensions, they shouldn't be imported here # NOTE: these are extensions, they shouldn't be imported here
@ -270,8 +271,10 @@ def init_cli_resource():
@click.argument('args') @click.argument('args')
def create(args, base_path, name): def create(args, base_path, name):
click.echo('create {} {} {}'.format(name, base_path, args)) click.echo('create {} {} {}'.format(name, base_path, args))
args = json.loads(args) args = json.loads(args) if args else {}
sresource.create(name, base_path, args) resources = vr.create(name, base_path, args)
for res in resources:
print res.name
@resource.command() @resource.command()
@click.option('--tag', default=None) @click.option('--tag', default=None)
@ -324,6 +327,19 @@ def init_cli_resource():
r = all[name] r = all[name]
r.update(args) r.update(args)
@resource.command()
def validate():
errors = vr.validate_resources()
for r, error in errors:
print 'ERROR: %s: %s' % (r.name, error)
@resource.command()
@click.argument('path')
def get_inputs(path):
with open(path) as f:
content = f.read()
print vr.get_inputs(content)
def run(): def run():
init_actions() init_actions()

View File

@ -30,9 +30,13 @@ class Ansible(BaseHandler):
return inventory_path return inventory_path
def _render_inventory(self, r): def _render_inventory(self, r):
inventory = '{0} ansible_ssh_host={1} ansible_connection=ssh ansible_ssh_user={2} ansible_ssh_private_key_file={3}' inventory = '{0} ansible_ssh_host={1} ansible_connection=ssh ansible_ssh_user={2} ansible_ssh_private_key_file={3} {4}'
host, user, ssh_key = r.args['ip'].value, r.args['ssh_user'].value, r.args['ssh_key'].value host, user, ssh_key = r.args['ip'].value, r.args['ssh_user'].value, r.args['ssh_key'].value
inventory = inventory.format(host, host, user, ssh_key) args = []
for arg in r.args:
args.append('{0}="{1}"'.format(arg, r.args[arg].value))
args = ' '.join(args)
inventory = inventory.format(host, host, user, ssh_key, args)
log.debug(inventory) log.debug(inventory)
return inventory return inventory

View File

@ -47,7 +47,7 @@ class BaseHandler(object):
return tpl.render(str=str, zip=zip, **args) return tpl.render(str=str, zip=zip, **args)
def _make_args(self, resource): def _make_args(self, resource):
args = {'name': resource.name} args = {'resource_name': resource.name}
args['resource_dir'] = resource.metadata['base_path'] args['resource_dir'] = resource.metadata['base_path']
args.update(resource.args) args.update(resource.args)
return args return args

View File

@ -8,7 +8,6 @@ import solar
from solar.core import actions from solar.core import actions
from solar.core import observer from solar.core import observer
from solar.core import signals from solar.core import signals
from solar import utils
from solar.core import validation from solar.core import validation
from solar.core.connections import ResourcesConnectionGraph from solar.core.connections import ResourcesConnectionGraph
@ -18,11 +17,12 @@ db = get_db()
class Resource(object): class Resource(object):
def __init__(self, name, metadata, args, tags=None): def __init__(self, name, metadata, args, tags=None, virtual_resource=None):
self.name = name self.name = name
self.metadata = metadata self.metadata = metadata
self.tags = tags or [] self.tags = tags or []
self.virtual_resource = virtual_resource
self.set_args_from_dict(args) self.set_args_from_dict(args)
@property @property
@ -60,6 +60,7 @@ class Resource(object):
args.update(new_args) args.update(new_args)
self.metadata['tags'] = self.tags self.metadata['tags'] = self.tags
self.metadata['virtual_resource'] = self.virtual_resource
for k, v in args.items(): for k, v in args.items():
if k not in self.metadata['input']: if k not in self.metadata['input']:
raise NotImplementedError( raise NotImplementedError(
@ -158,43 +159,13 @@ class Resource(object):
raise Exception('Uuups, action is not available') raise Exception('Uuups, action is not available')
def create(name, base_path, args, tags=[], connections={}):
from solar.core import resource_provider
if isinstance(base_path, resource_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)
)
base_meta_file = os.path.join(base_path, 'meta.yaml')
actions_path = os.path.join(base_path, 'actions')
meta = utils.yaml_load(base_meta_file)
meta['id'] = name
meta['version'] = '1.0.0'
meta['actions'] = {}
meta['actions_path'] = actions_path
meta['base_path'] = os.path.abspath(base_path)
if os.path.exists(actions_path):
for f in os.listdir(actions_path):
meta['actions'][os.path.splitext(f)[0]] = f
resource = Resource(name, meta, args, tags=tags)
signals.assign_connections(resource, connections)
return resource
def wrap_resource(raw_resource): def wrap_resource(raw_resource):
name = raw_resource['id'] name = raw_resource['id']
args = {k: v['value'] for k, v in raw_resource['input'].items()} args = {k: v['value'] for k, v in raw_resource['input'].items()}
tags = raw_resource.get('tags', []) tags = raw_resource.get('tags', [])
virtual_resource = raw_resource.get('virtual_resource', [])
return Resource(name, raw_resource, args, tags=tags) return Resource(name, raw_resource, args, tags=tags, virtual_resource=virtual_resource)
def load(resource_name): def load(resource_name):

View File

@ -0,0 +1,121 @@
# -*- coding: UTF-8 -*-
import os
from StringIO import StringIO
import yaml
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 signals
def create_resource(name, base_path, args, virtual_resource=None):
from solar.core import resource_provider
if isinstance(base_path, resource_provider.BaseProvider):
base_path = base_path.directory
base_meta_file = os.path.join(base_path, 'meta.yaml')
actions_path = os.path.join(base_path, 'actions')
metadata = utils.yaml_load(base_meta_file)
metadata['id'] = name
metadata['version'] = '1.0.0'
metadata['actions'] = {}
metadata['actions_path'] = actions_path
metadata['base_path'] = os.path.abspath(base_path)
if os.path.exists(actions_path):
for f in os.listdir(actions_path):
metadata['actions'][os.path.splitext(f)[0]] = f
tags = metadata.get('tags', [])
resource = resource_module.Resource(name, metadata, args, tags, virtual_resource)
return resource
def create_virtual_resource(vr_name, template):
resources = template['resources']
connections = []
created_resources = []
for resource in resources:
name = resource['id']
base_path = resource['from']
args = resource['values']
new_resources = create(name, base_path, args, vr_name)
created_resources += new_resources
if not is_virtual(base_path):
for key, arg in args.items():
if isinstance(arg, basestring) and '::' in arg:
emitter, src = arg.split('::')
connections.append((emitter, name, {src: key}))
db = resource_module.load_all()
for emitter, reciver, mapping in connections:
emitter = db[emitter]
reciver = db[reciver]
signals.connect(emitter, reciver, mapping)
return created_resources
def create(name, base_path, kwargs, virtual_resource=None):
if isinstance(base_path, resource_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)
)
if is_virtual(base_path):
template = _compile_file(name, base_path, kwargs)
yaml_template = yaml.load(StringIO(template))
resources = create_virtual_resource(name, yaml_template)
else:
resource = create_resource(name, base_path, kwargs, virtual_resource)
resources = [resource]
return resources
def validate_resources():
db = resource_module.load_all()
all_errors = []
for r in db.values():
if not isinstance(r, resource_module.Resource):
continue
errors = validation.validate_resource(r)
if errors:
all_errors.append((r, errors))
return all_errors
def _compile_file(name, path, kwargs):
with open(path) as f:
content = f.read()
inputs = get_inputs(content)
template = _get_template(name, content, kwargs, inputs)
return template
def get_inputs(content):
env = Environment()
ast = env.parse(content)
return meta.find_undeclared_variables(ast)
def _get_template(name, content, kwargs, inputs):
missing = []
for input in inputs:
if input not in kwargs:
missing.append(input)
if missing:
raise Exception('[{0}] Validation error. Missing data in input: {1}'.format(name, missing))
template = Template(content)
template = template.render(str=str, zip=zip, **kwargs)
return template
def is_virtual(path):
return os.path.isfile(path)

View File

@ -98,7 +98,6 @@ def stage_changes():
def execute(res, action): def execute(res, action):
return state.STATES.success
try: try:
actions.resource_action(res, action) actions.resource_action(res, action)
return state.STATES.success return state.STATES.success

90
templates/controller.yml Normal file
View File

@ -0,0 +1,90 @@
id: primary_controller
resources:
- id: mariadb_service
from: resources/mariadb_service
values:
port: 3306
root_password: mariadb
image: mariadb
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: rabbitmq_service
from: resources/rabbitmq_service
values:
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: keystone_base
from: templates/keystone_base.yml
values:
login_user: root
login_password: 'mariadb_service::root_password'
login_port: 'mariadb_service::port'
db_name: 'keystone'
user_password: 'keystone'
user_name: 'keystone'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: keystone_api_1
from: templates/keystone_api.yml
values:
idx: 1
image: 'kollaglue/centos-rdo-k-keystone'
config_dir: '/etc/solar/keystone_config_1'
db_password: 'keystone_db_user::user_password'
db_user: 'keystone_db_user::user_name'
db_port: 'keystone_db_user::login_port'
db_name: 'keystone_db_user::db_name'
db_host: 'mariadb_service::ip'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
# TODO: HAproxy
- id: openstack_base
from: templates/openstack_base.yml
values:
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
keystone_ip: 'keystone_service_1::ip'
keystone_admin_port: 'keystone_service_1::admin_port'
keystone_port: 'keystone_service_1::port'
admin_token: 'keystone_config_1::admin_token'
- id: glance_base
from: templates/glance_base.yml
values:
login_user: root
login_password: 'mariadb_service::root_password'
login_port: 'mariadb_service::port'
db_name: 'glance'
user_password: 'glance'
user_name: 'glance'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: glance_registry_1
from: templates/glance_registry.yml
values:
idx: 1
keystone_admin_port: 'keystone_service_1::admin_port'
keystone_ip: 'keystone_service_1::ip'
mysql_password: 'glance_db_user::user_password'
mysql_user: 'keystone_db_user::user_name'
mysql_db: 'keystone_db_user::db_name'
mysql_ip: 'mariadb_service::ip'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
tags: ['resources/controller', 'resource/primary_controller']

26
templates/glance_base.yml Normal file
View File

@ -0,0 +1,26 @@
id: glance_base
resources:
- id: glance_db
from: resources/mariadb_db
values:
db_name: {{db_name}}
login_user: '{{login_user}}'
login_password: '{{login_password}}'
login_port: '{{login_port}}'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: glance_db_user
from: resources/mariadb_user
values:
user_password: '{{user_password}}'
user_name: '{{user_name}}'
db_name: 'keystone_db::db_name'
login_user: 'keystone_db::login_user'
login_password: 'keystone_db::login_password'
login_port: 'keystone_db::login_port'
ip: 'keystone_db::ip'
ssh_user: 'keystone_db::ssh_user'
ssh_key: 'keystone_db::ssh_key'

View File

@ -0,0 +1,26 @@
id: glance_register_{{idx}}
resources:
- id: glance_config_{{idx}}
from: resources/glance_config
values:
keystone_admin_port: '{{keystone_admin_port}}'
keystone_ip: '{{keystone_ip}}'
mysql_password: '{{mysql_password}}'
mysql_user: '{{mysql_user}}'
mysql_db: '{{mysql_db}}'
mysql_ip: '{{mysql_ip}}'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: glance_registry_{{idx}}
from: resources/glance_registry_service
values:
ip: 'keystone_config_{{idx}}::ip'
ssh_user: 'keystone_config_{{idx}}::ssh_user'
ssh_key: 'keystone_config_{{idx}}::ssh_key'
tags: ['resources/keystone', 'resource/keystone_api']

View File

@ -0,0 +1,27 @@
id: keystone_api_{{idx}}
resources:
- id: keystone_config_{{idx}}
from: resources/keystone_config
values:
config_dir: '/etc/solar/keystone_{{idx}}'
db_host: '{{db_host}}'
db_port: '{{db_port}}'
db_name: '{{db_name}}'
db_user: '{{db_user}}'
db_password: '{{db_password}}'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: keystone_service_{{idx}}
from: resources/keystone_service
values:
image: 'kollaglue/centos-rdo-j-keystone'
config_dir: 'keystone_config_{{idx}}::config_dir'
ip: 'keystone_config_{{idx}}::ip'
ssh_user: 'keystone_config_{{idx}}::ssh_user'
ssh_key: 'keystone_config_{{idx}}::ssh_key'
tags: ['resources/keystone', 'resource/keystone_api']

View File

@ -0,0 +1,26 @@
id: keystone_base
resources:
- id: keystone_db
from: resources/mariadb_db
values:
db_name: {{db_name}}
login_user: '{{login_user}}'
login_password: '{{login_password}}'
login_port: '{{login_port}}'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: keystone_db_user
from: resources/mariadb_user
values:
user_password: '{{user_password}}'
user_name: '{{user_name}}'
db_name: 'keystone_db::db_name'
login_user: 'keystone_db::login_user'
login_password: 'keystone_db::login_password'
login_port: 'keystone_db::login_port'
ip: 'keystone_db::ip'
ssh_user: 'keystone_db::ssh_user'
ssh_key: 'keystone_db::ssh_key'

8
templates/nodes.yml Normal file
View File

@ -0,0 +1,8 @@
id: mariadb_service
resources:
- id: node1
from: resources/ro_node
values:
ip: '10.0.0.3'
ssh_key: '/vagrant/.vagrant/machines/solar-dev1/virtualbox/private_key'
ssh_user: 'vagrant'

View File

@ -0,0 +1,61 @@
id: openstack_base
resources:
- id: admin_tenant
from: resources/keystone_tenant
values:
tenant_name: admin
keystone_port: '{{keystone_admin_port}}'
keystone_host: '{{keystone_ip}}'
admin_token: '{{admin_token}}'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: admin_user
from: resources/keystone_user
values:
user_name: 'admin'
user_password: 'admin'
tenant_name: 'admin_tenant::tenant_name'
keystone_port: '{{keystone_admin_port}}'
keystone_host: '{{keystone_ip}}'
admin_token: '{{admin_token}}'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: keystone_service_endpoint
from: resources/keystone_service_endpoint
values:
{% raw %}
adminurl: 'http://{{admin_ip}}:{{admin_port}}/v2.0'
internalurl: 'http://{{internal_ip}}:{{internal_port}}/v2.0'
publicurl: 'http://{{public_ip}}:{{public_port}}/v2.0'
{% endraw %}
description: 'OpenStack Identity Service'
type: 'identity'
name: 'keystone'
admin_port: '{{keystone_admin_port}}'
public_port: '{{keystone_port}}'
internal_port: '{{keystone_port}}'
admin_ip: '{{ip}}'
public_ip: '{{ip}}'
internal_ip: '{{ip}}'
keystone_admin_port: '{{keystone_admin_port}}'
keystone_host: '{{keystone_ip}}'
admin_token: '{{admin_token}}'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'
- id: service_tenant
from: resources/keystone_tenant
values:
tenant_name: services
keystone_port: '{{keystone_admin_port}}'
keystone_host: '{{keystone_ip}}'
admin_token: '{{admin_token}}'
ip: '{{ip}}'
ssh_user: '{{ssh_user}}'
ssh_key: '{{ssh_key}}'