diff --git a/ansible/cloud_providers/ravello/Ansible_Ravello_module.adoc b/ansible/cloud_providers/ravello/Ansible_Ravello_module.adoc new file mode 100644 index 00000000000..de2dcc273de --- /dev/null +++ b/ansible/cloud_providers/ravello/Ansible_Ravello_module.adoc @@ -0,0 +1,224 @@ +:scrollbar: +:data-uri: +:toc2: + +== Requirements & Instructions on Using the Ansible Ravello Module + +:numbered: + +== Requirements + +. Install Ansible `http://docs.ansible.com/ansible/intro_installation.html` +. Install the Ravello SDK via **pip** ++ +NOTE: For manual setup instructions see `https://github.com/ravello/python-sdk` and for additional documentation see `http://ravello-sdk.readthedocs.io/en/ravello-sdk-1.4/` ++ +---- +pip install ravello-sdk +---- + +=== Test Ravello SDK + +. Clone the ravello-sdk locally to use the example scripts ++ +---- +cd +git clone https://github.com/ravello/python-sdk.git +---- ++ +. Change to the **examples** directory ++ +---- +cd python-sdk/examples +---- ++ +. Set up credentials file for Ravello using your username and password ++ +---- +./set-creds +Enter username: your_login@redhat.com +Enter a Password: +---- ++ +. Verify saved credentials ++ +NOTE: This will display your login into on the terminal however the password is hashed. ++ +---- +cat ~/.ravello_login + + +---- ++ +. Test the script to get all blueprints you have access to ++ +---- +./bp-get-all + +---- + +=== Test Capture of Ravello Environment Metadata to JSON + +. Test the script to get all applications you have access to ++ +---- +./app-get-all + +---- ++ +. Test the script to get all metadata for a specific application and write it to a JSON file ++ +NOTE: The option **-a** is for a full JSON dump of extended application metadata ++ +---- +./app-get-data -a myapp.json +---- + +== Using the Ravello Ansible Module + +=== Clone the Ansible Ravello Repository + +. Change to a directory of your chosing ++ +---- +git clone https://github.com/RedHatDemos/ansible-ravello.git +---- + +=== Create YAML Template + +. Within the cloned repository directory, create template from existing app: ++ +---- +./app-get-data -a 2>/dev/null|python -c 'import sys, yaml, json; yaml.safe_dump(json.load(sys.stdin), sys.stdout, default_flow_style=False)' > out.yaml +---- + +. Remove everything that is not in the *design:* section. This is at the beginning and end of the file. + +. Under *design:* remove all subsections except *vms:* + +. Remove any line with *applicationId:*, *creationTime:*, *loadingStatus:*, *loadingPercentage:*, *fqdn:*, *allocatedIp:*, *externalAccessState:*, *ipConfigLuid:*, and *useLuidForIpConfig:*. + +=== Deploy an Environment + +. This playbook will create a blueprint based on a set of virtual machines described in *app_template.yml*. It will then create an application from this blueprint and wait for it to start. + +. To use the default values just run the *deploy_environment.yml. ++ +---- +ansible-playbook deploy_environment.yml +---- + ++ +NOTE: It is likely there may be a conflict if the default names have already been used. Instead, specify a *unique_name* and optionally a *version* which will be used to make sure your blueprints and applications have unique names ++ +. Specify *unique_name* and *version* if desired: ++ +---- +ansible-playbook deploy_environment.yml -e "unique_name=vvaldez-demo version=1.6" +---- + +. It is also possible to load your own variables from a yaml file: ++ +---- +ansible-playbook deploy_environment.yml -e @vars.yml +---- + +. Contents of *vars.yml*: ++ +---- +unique_name=vvaldez-demo +version=1.6 +---- + +. To skip the blueprint creation phase, just provide an existing *blueprint_id*: ++ +---- +ansible-playbook deploy_environment.yml -e "blueprint_id=12345678" +---- + +. Example *deploy_environment.yml* playbook template provided in this repo: ++ +---- +--- +- hosts: localhost + tasks: + # Create app, based on blueprint, start it and wait for started + - local_action: + module: ravello_app + # Make sure you update the version number as the name must be unique + name: 'example_app-v1.0' + description: 'Example blueprint created by ansible' + app_template: '/home/user/ansible-ravello/app_template.yml' + state: design +---- ++ +[NOTE] +The *name* field must be unique. All blueprints must have a unique name. Typically this is achieved by changing the version number in the name. + +=== Create Blueprint From Template + +---- +ansible-playbook design.yml -vvv +---- + +---- +Using /etc/ansible/ansible.cfg as config file + [WARNING]: provided hosts list is empty, only localhost is available + + +PLAYBOOK: design.yml *********************************************************** +1 plays in design.yml + +PLAY [localhost] *************************************************************** + +TASK [setup] ******************************************************************* +Using module file /usr/lib/python2.6/site-packages/ansible/modules/core/system/setup.py +<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: prutledg +<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1481666189.73-18007598170313 `" && echo ansible-tmp-1481666189.73-18007598170313="` echo $HOME/.ansible/tmp/ansible-tmp-1481666189.73-18007598170313 `" ) && sleep 0' +<127.0.0.1> PUT /tmp/tmp7TPuB1 TO /home/prutledg/.ansible/tmp/ansible-tmp-1481666189.73-18007598170313/setup.py +<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/prutledg/.ansible/tmp/ansible-tmp-1481666189.73-18007598170313/ /home/prutledg/.ansible/tmp/ansible-tmp-1481666189.73-18007598170313/setup.py && sleep 0' +<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2.6 /home/prutledg/.ansible/tmp/ansible-tmp-1481666189.73-18007598170313/setup.py; rm -rf "/home/prutledg/.ansible/tmp/ansible-tmp-1481666189.73-18007598170313/" > /dev/null 2>&1 && sleep 0' +ok: [localhost] + +TASK [ravello_app] ************************************************************* +task path: /home/prutledg/ansible-ravello/design.yml:5 +Using module file /home/prutledg/ansible-ravello/library/ravello_app.py + ESTABLISH LOCAL CONNECTION FOR USER: prutledg + EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1481666190.57-63460892520707 `" && echo ansible-tmp-1481666190.57-63460892520707="` echo $HOME/.ansible/tmp/ansible-tmp-1481666190.57-63460892520707 `" ) && sleep 0' + PUT /tmp/tmp7TPuB1 TO /home/prutledg/.ansible/tmp/ansible-tmp-1481666190.57-63460892520707/ravello_app.py + EXEC /bin/sh -c 'chmod u+x /home/prutledg/.ansible/tmp/ansible-tmp-1481666190.57-63460892520707/ /home/prutledg/.ansible/tmp/ansible-tmp-1481666190.57-63460892520707/ravello_app.py && sleep 0' + EXEC /bin/sh -c '/usr/bin/python2.6 /home/prutledg/.ansible/tmp/ansible-tmp-1481666190.57-63460892520707/ravello_app.py; rm -rf "/home/prutledg/.ansible/tmp/ansible-tmp-1481666190.57-63460892520707/" > /dev/null 2>&1 && sleep 0' +changed: [localhost -> localhost] => { + "blueprint_id": "76743737", + "changed": true, + "invocation": { + "module_args": { + "app_template": "/home/prutledg/ansible-ravello/app_template.yml", + "application_ttl": -1, + "blueprint_description": null, + "blueprint_id": null, + "blueprint_name": null, + "cloud": null, + "description": "Example blueprint created by ansible", + "name": "example_app-v1.0", + "password": null, + "publish_optimization": "cost", + "region": null, + "service_name": "ssh", + "state": "design", + "url": null, + "username": null, + "wait": true, + "wait_timeout": 1200 + }, + "module_name": "ravello_app" + }, + "name": "example_app-v1.0" +} +---- + +=== Check for Blueprint + +. Log into Ravello and check if the blueprint exists. + +. The next steps would be to deploy the blueprint with this ansible module as a new application, inventory the app, and apply final playbook(s) to the resulting VMs then create final blueprint from that. diff --git a/ansible/cloud_providers/ravello/README.md b/ansible/cloud_providers/ravello/README.md new file mode 100644 index 00000000000..89673fdedd9 --- /dev/null +++ b/ansible/cloud_providers/ravello/README.md @@ -0,0 +1,12 @@ +# Synopsis +The Ansible Ravello module is intended to provide an easy way to interact with Ravello using the Ravello SDK to interact with the Ravello API. The goal is to use the automation capabilities of Ansible to easily deploy new applications, customize the applications and save the fully configured application back as a blueprint in Ravello allow for quick, scalable, pre-configured deployments. + +# Pre-reqs, Installation, Examples +Refer to: https://github.com/RedHatDemos/ansible-ravello/blob/master/Ansible_Ravello_module.adoc for installation dependencies and module usage. + +# Contributors +The main contributors for this project are:
+*Pat Rutledge* prutledge@redhat.com
+*Vinny Valdez* vvaldez@redhat.com
+*Nenad Peric* nperic@redhat.com
+*Brett Thurber* bthurber@redhat.com diff --git a/ansible/cloud_providers/ravello/app_template.yml b/ansible/cloud_providers/ravello/app_template.yml new file mode 100644 index 00000000000..9f2590a0b2d --- /dev/null +++ b/ansible/cloud_providers/ravello/app_template.yml @@ -0,0 +1,190 @@ +vms: +- name: "Bastion Host" + tag: "bastion" + description: "Bastion Host\nnohbac: true\n" + numCpus: 1 + memorySize: + unit: "GB" + value: 1 + hostnames: + - "bastion-REPL.rhpds.opentlc.com" + - "bastion.example.com" + hardDrives: + - index: 0 + imageName: "rhel-guest-image-7.3-35.x86_64" + boot: true + controller: "virtio" + name: "root disk" + size: + unit: "GB" + value: 40 + type: "DISK" + networkConnections: + - name: "eth0" + device: + index: 0 + deviceType: "virtio" + useAutomaticMac: false + mac: "2c:c2:60:14:42:52" + ipConfig: + autoIpConfig: + reservedIp: "192.168.1.10" + hasPublicIp: true + - name: "eth1" + device: + index: 1 + deviceType: "virtio" + useAutomaticMac: true + ipConfig: + autoIpConfig: + reservedIp: "192.168.2.10" + stopTimeOut: "300" + suppliedServices: + - external: true + ip: "192.168.1.10" + name: "ssh" + portRange: "22" + protocol: "SSH" + supportsCloudInit: true + keypairName: "opentlc-admin-backdoor" +- name: "App Server" + tag: "app_server" + description: "App Server" + numCpus: 2 + memorySize: + unit: "GB" + value: 4 + hostnames: + - "app-REPL.rhpds.opentlc.com" + - "app.example.com" + hardDrives: + - index: 0 + imageName: "rhel-guest-image-7.3-35.x86_64" + boot: true + controller: "virtio" + name: "root disk" + size: + unit: "GB" + value: 40 + type: "DISK" + networkConnections: + - name: "eth0" + device: + index: 0 + deviceType: "virtio" + useAutomaticMac: true + ipConfig: + autoIpConfig: + reservedIp: "192.168.1.20" + - name: "eth1" + device: + index: 1 + deviceType: "virtio" + useAutomaticMac: true + ipConfig: + autoIpConfig: + reservedIp: "192.168.2.20" + stopTimeOut: "300" + +- name: "Web Server" + tag: "web_server" + description: "Web Server" + numCpus: 2 + memorySize: + unit: "GB" + value: 2 + hostnames: + - "www-REPL.rhpds.opentlc.com" + - "www.example.com" + hardDrives: + - index: 0 + imageName: "rhel-guest-image-7.3-35.x86_64" + boot: true + controller: "virtio" + name: "root disk" + size: + unit: "GB" + value: 40 + type: "DISK" + - index: 1 + controller: "virtio" + name: "blank web root disk" + size: + unit: "GB" + value: 10 + type: "DISK" + networkConnections: + - name: "eth0" + device: + index: 0 + deviceType: "virtio" + useAutomaticMac: true + ipConfig: + autoIpConfig: + reservedIp: "192.168.1.30" + hasPublicIp: true + stopTimeOut: "300" + suppliedServices: + - ip: "192.168.1.30" + name: "http" + portRange: "80" + protocol: "HTTP" + - ip: "192.168.1.30" + name: "https" + portRange: "443" + protocol: "HTTPS" + - ip: "192.168.1.30" + name: "example TCP" + portRange: "8080" + protocol: "TCP" + - ip: "192.168.1.30" + name: "example UDP" + portRange: "901" + protocol: "UDP" + supportsCloudInit: true + keypairName: "opentlc-admin-backdoor" +- name: "DB Server" + tag: "db_server" + description: "DB Server" + numCpus: 4 + memorySize: + unit: "GB" + value: 4 + hostnames: + - "db-REPL.rhpds.opentlc.com" + - "db.example.com" + hardDrives: + - index: 0 + imageName: "rhel-guest-image-7.3-35.x86_64" + boot: true + controller: "virtio" + name: "root disk" + size: + unit: "GB" + value: 40 + type: "DISK" + - index: 1 + controller: "virtio" + name: "blank db disk" + size: + unit: "GB" + value: 20 + type: "DISK" + networkConnections: + - name: "eth0" + device: + index: 0 + deviceType: "virtio" + useAutomaticMac: true + ipConfig: + autoIpConfig: + reservedIp: "192.168.1.40" + - name: "eth1" + device: + index: 1 + deviceType: "virtio" + useAutomaticMac: true + ipConfig: + autoIpConfig: + reservedIp: "192.168.2.40" + stopTimeOut: "300" diff --git a/ansible/cloud_providers/ravello/app_template_short.yml b/ansible/cloud_providers/ravello/app_template_short.yml new file mode 100644 index 00000000000..e90f19bee35 --- /dev/null +++ b/ansible/cloud_providers/ravello/app_template_short.yml @@ -0,0 +1,49 @@ +vms: +- name: "Bastion Host" + tag: "bastion" + description: "Bastion Host\nnohbac: true\n" + numCpus: 1 + memorySize: + unit: "GB" + value: 1 + hostnames: + - "bastion-REPL.rhpds.opentlc.com" + - "bastion.example.com" + hardDrives: + - index: 0 + imageName: "rhel-guest-image-7.3-35.x86_64" + boot: true + controller: "virtio" + name: "root disk" + size: + unit: "GB" + value: 40 + type: "DISK" + networkConnections: + - name: "eth0" + device: + index: 0 + deviceType: "virtio" + useAutomaticMac: false + mac: "2c:c2:60:14:42:52" + ipConfig: + autoIpConfig: + reservedIp: "192.168.1.10" + hasPublicIp: true + - name: "eth1" + device: + index: 1 + deviceType: "virtio" + useAutomaticMac: true + ipConfig: + autoIpConfig: + reservedIp: "192.168.2.10" + stopTimeOut: "300" + suppliedServices: + - external: true + ip: "192.168.1.10" + name: "ssh" + portRange: "22" + protocol: "SSH" + supportsCloudInit: true + keypairName: "opentlc-admin-backdoor" diff --git a/ansible/cloud_providers/ravello/deploy_environment.yml b/ansible/cloud_providers/ravello/deploy_environment.yml new file mode 100644 index 00000000000..4712878be8d --- /dev/null +++ b/ansible/cloud_providers/ravello/deploy_environment.yml @@ -0,0 +1,10 @@ +--- +- hosts: localhost + roles: + - role: warm_up + - role: blueprint_design + when: not blueprint_id is defined + - role: application_create_from_blueprint + blueprint_id: "{{ design_results.blueprint_id }}" + - role: blueprint_create_from_application + application_name: "{{ app_results.app_name }}" diff --git a/ansible/cloud_providers/ravello/group_vars/all b/ansible/cloud_providers/ravello/group_vars/all new file mode 100644 index 00000000000..af54ef6e002 --- /dev/null +++ b/ansible/cloud_providers/ravello/group_vars/all @@ -0,0 +1,9 @@ +--- +unique_name: 'example' +version: '1.0' +wait_timeout: '1800' +blueprint_name: "{{ 'ansible-' + unique_name + '-v' + version }}" +blueprint_description: "{{ unique_name + ' blueprint created by ansible' }}" +application_name: "{{ 'ansible-' + unique_name + '-app-v' + version }}" +application_description: "{{ unique_name + ' application created by ansible' }}" +app_template: "app_template.yml" diff --git a/ansible/cloud_providers/ravello/inventory/ansible_tower_ravello_inventory.py b/ansible/cloud_providers/ravello/inventory/ansible_tower_ravello_inventory.py new file mode 100755 index 00000000000..6d0b86a2a21 --- /dev/null +++ b/ansible/cloud_providers/ravello/inventory/ansible_tower_ravello_inventory.py @@ -0,0 +1,218 @@ +#!/usr/bin/python + +''' +Ravello external inventory script +================================================== +Generates inventory that Ansible can understand by making an API request to Ravello. +Modeled after https://raw.githubusercontent.com/jameslabocki/ansible_api/master/python/ansible_tower_cloudforms_inventory.py + +Required: Ravello Python SDK https://github.com/ravello/python-sdk +Useful: https://www.ravellosystems.com/ravello-api-doc/ + +Notes: In my testing, with >200 applications and ~1,000 virtual machines this took 30 seconds to execute. + If the get_applications call in the Ravello Python SDK supported dumping design information this could be dramatically reduced. + +jlabocki redhat.com or @jameslabocki on twitter +''' + +import os +import re +import argparse +import ConfigParser +import requests +import json +from argparse import ArgumentParser +import base64 +import getpass +import logging +import logging.handlers +from ravello_sdk import * + +def get_credentials(): + with open(os.path.expanduser("~/.ravello_login"),"r") as pf: + username = pf.readline().strip() + encrypted_password = pf.readline().strip() + password = base64.b64decode(encrypted_password).decode() + return username,password + +def get_user_credentials(username): + + password = None + + if username: + password = getpass.getpass('Enter a Password: ') + else: + #read user credentials from .ravello_login file in user HOMEDIR + username,password = get_credentials() + + if not username or not password: + log.error('User credentials are not set') + print('Error: User credentials are not set') + return None,None + + return username,password + +def connect(username, password): + client = RavelloClient() + try: + client.login(username, password) + except Exception as e: + print('Error: Invalid user credentials, username {0}'.format(username)) + return None + return client + +def get_app_id(app_name,client): + app_id=0 + for app in client.get_applications(): + if app['name'].lower() == app_name.lower(): + app_id = app['id'] + break + return app_id + +class RavelloInventory(object): + + def _empty_inventory(self): + return {"_meta" : {"hostvars" : {}}} + + def __init__(self): + ''' Main execution path ''' + + # Inventory grouped by instance IDs, tags, security groups, regions, + # and availability zones + self.inventory = self._empty_inventory() + + # Index of hostname (address) to instance ID + self.index = {} + + # Read CLI arguments + self.read_settings() + self.parse_cli_args() + + # If --apps is set then run get_apps_all + #if self.args.apps is True: + # self.get_apps_all() + + # If --list is set then run get_app with ID of application + if self.args.list is not None: + self.get_app() + + def parse_cli_args(self): + ''' Command line argument processing ''' + + parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on Ravello') + parser.add_argument('--apps', action='store_false', + help='List all app names (default: False)') + parser.add_argument('--list', action='store', default=False, + help='Get the group(s) and hostname(s) from a specific application by specifying the app name') + self.args = parser.parse_args() + + def read_settings(self): + ''' Reads the settings from the ravello.ini file ''' + + config = ConfigParser.SafeConfigParser() + config_paths = [ + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ravello.ini'), + "/etc/ansible/ravello.ini", + ] + + env_value = os.environ.get('RAVELLO_INI_PATH') + if env_value is not None: + config_paths.append(os.path.expanduser(os.path.expandvars(env_value))) + + config.read(config_paths) + + # Get Auth from INI + INI=True + if config.has_option('ravello', 'username'): + self.ravello_username = config.get('ravello', 'username') + else: + self.ravello_username = "none" + INI=False + + if config.has_option('ravello', 'password'): + self.ravello_password = config.get('ravello', 'password') + else: + self.ravello_password = "none" + INI=False + + if INI is False: + self.ravello_username, self.ravello_password = get_user_credentials(None) + + if not self.ravello_username or not self.ravello_password: + print("ERROR: Could not get Ravello credentials from INI file or .ravello_login (SDK Auth)") + exit(1) + + + def get_apps_all(self): + #Connect to Ravello + client = connect(self.ravello_username, self.ravello_password) + if not client: + exit (1) + + apps = client.get_applications() + + names = [] + for app in apps: + #Only get the published apps + if app['published']: + myname = (json.dumps(app['name'])) + names.append(myname) + for name in names: + print name + + + def get_app(self): + #Connect to Ravello + myappname = self.args.list + client = connect(self.ravello_username, self.ravello_password) + if not client: + exit (1) + + apps = client.get_applications() + + myappid = "" + + for app in apps: + #Only get the published apps + if app['published']: + if str(app['name']) == myappname: + myappid = app['id'] + + #First, define empty lists for the the tags, groups, subgroups for tags/vms, and the formatted list for tower. + groups = {} + groups['_meta'] = {} + groups['_meta']['hostvars'] = {} + + app = client.get_application(myappid, aspect="deployment") + + if app['deployment']: + appname = app['name'] + vmsFlag = True if "vms" in app["deployment"] else False + if vmsFlag == True: + vms = app['deployment']['vms'] + for vm in vms: + #if 'externalFqdn' in vm: + # hostname = vm['externalFqdn'] + #else: + hostnames = vm['hostnames'] + hostname = hostnames[0] + desc = vm['description'] + for line in desc.splitlines(): + if re.match("^tag:", line): + t = line.split(':') + tag = t[1] + if tag in groups.keys(): + groups[tag]['hosts'].append(hostname) + else: + groups[tag] = {} + groups[tag]['hosts'] = {} + groups[tag]['hosts'] = [hostname] + if 'externalFqdn' in vm: + groups['_meta']['hostvars'][hostname] = { 'externalFqdn': vm['externalFqdn'] } + if tag == 'bastion' and 'externalFqdn' in vm: + groups['_meta']['hostvars'][hostname].update({ 'bastion': True }) + + print json.dumps(groups, indent=5) + +#Run the script +RavelloInventory() diff --git a/ansible/cloud_providers/ravello/inventory/ravello.ini b/ansible/cloud_providers/ravello/inventory/ravello.ini new file mode 100644 index 00000000000..84caa4e0365 --- /dev/null +++ b/ansible/cloud_providers/ravello/inventory/ravello.ini @@ -0,0 +1,11 @@ +# Ansible Ravello external inventory script settings +# Uncomment and add your credentials +# Alternative, use SDK to configure ~/.ravello_login + +[ravello] + +# Username for ravello +#username = yourusername + +# Password for ravello +#password = yourpassword diff --git a/ansible/cloud_providers/ravello/library/ravello_app.py b/ansible/cloud_providers/ravello/library/ravello_app.py new file mode 100755 index 00000000000..d455683fa54 --- /dev/null +++ b/ansible/cloud_providers/ravello/library/ravello_app.py @@ -0,0 +1,672 @@ +#!/usr/bin/python + +# (c) 2015, ravellosystems +# +# author zoza +# +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +###################################################################### + +import random, string + +try: + from ravello_sdk import * + HAS_RAVELLO_SDK = True +except ImportError: + HAS_RAVELLO_SDK = False + +except ImportError: + print "failed=True msg='ravello sdk required for this module'" + sys.exit(1) + +from ravello_cli import get_diskimage + +DOCUMENTATION = ''' +--- +module: ravello_app +short_description: Create/delete/start/stop an application in ravellosystems +description: + - Create/delete/start/stop an application in ravellosystems and wait for it (optionally) to be 'running' + - list state will return a fqdn list of exist application hosts with their external services + - blueprint state wil create a blueprint from an existing app (must provide blueprint_name) +options: + state: + description: + - Indicate desired state of the target. + default: present + choices: ['design', 'present', 'started', 'absent', 'stopped','list','blueprint'] + username: + description: + - ravello username + password: + description: + - ravello password + service_name: + description: + - Supplied Service name for list state + default: ssh + name: + description: + - application name + description: + description: + - application description + blueprint_id: + description: + - create app, based on this blueprint + #publish options + cloud: + description: + - cloud to publish + region: + description: + - region to publish + publish_optimization: + default: cost + choices: ['cost', 'performance'] + application_ttl: + description: + - application autostop in mins + default: -1 # never + wait + description: + - Wait for the app to be in state 'running' before returning. + default: True + choices: [ True, False ] + wait_timeout: + description: + - How long before wait gives up, in seconds. + default: 600 + blueprint_name: + description: + - Specify a name for a new blueprint based on existing app + blueprint_description: + description: + - Description of new blueprint + app_template: + description: + - Path to a YML file that defines an application infrastructure then creates a blueprint for further processing with follow-on playbooks. Must use state=design +''' + +EXAMPLES = ''' +# Create app, based on blueprint, start it and wait for started +- local_action: + module: ravello_app + username: user@ravello.com + password: password + name: 'my-application-name' + description: 'app desc' + blueprint_id: '2452' + wait: True + wait_timeout: 600 + state: present +# Create app, based on blueprint +- local_action: + module: ravello_app + username: user@ravello.com + password: password + name: 'my-application-name' + description: 'app desc' + publish_optimization: performance + cloud:AMAZON + region: Oregon + state: present +# List application example +- local_action: + module: ravello_app + name: 'my-application-name' + service_name: 'ssh' + state: list +# Delete application example +- local_action: + module: ravello_app + name: 'my-application-name' + state: absent +# Create blueprint from existing app +- local_action: + module: ravello_app + name: 'my-application-name' + blueprint_name: 'my-application-bp' + blueprint_description: 'Blueprint of app xyz' + state: blueprint +# Create blueprint based on app_template.yml +- local_action: + module: ravello_app + name: 'my-new-baseline' + description: 'My new baseline' + app_template: 'app_template.yml' + state: design + register: design_results +''' + +import os +import base64 +import getpass +import logging +import logging.handlers + +def get_credentials(): + with open(os.path.expanduser("~/.ravello_login"),"r") as pf: + username = pf.readline().strip() + encrypted_password = pf.readline().strip() + password = base64.b64decode(encrypted_password).decode() + return username,password + +def get_user_credentials(username): + + password = None + + if username: + password = getpass.getpass('Enter a Password: ') + else: + #read user credentials from .ravello_login file in user HOMEDIR + username,password = get_credentials() + + if not username or not password: + log.error('User credentials are not set') + print('Error: User credentials are not set') + return None,None + + return username,password + +def initlog(log_file): + logger = logging.getLogger() + logger.setLevel(logging.INFO) + logpath=os.path.join(os.getcwd(),log_file) + handler = logging.handlers.RotatingFileHandler(logpath, maxBytes=1048576, backupCount=10) + fmt = '%(asctime)s: %(filename)-20s %(levelname)-8s %(message)s' + handler.setFormatter(logging.Formatter(fmt)) + logger.addHandler(handler) + +def connect(username, password): + client = RavelloClient() + try: + client.login(username, password) + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) + log.error('Invalid user credentials, username {0}'.format(username)) + print('Error: Invalid user credentials, username {0}'.format(username)) + return None + return client + +def get_app_id(app_name,client): + app_id=0 + for app in client.get_applications(): + if app['app_name'].lower() == app_name.lower(): + app_id = app['id'] + break + if app_id == 0: + module.fail_json(msg = 'ERROR: Cloud not find app: %s' % app_name) + return app_id + +def get_blueprint_id(blueprint_name,client): + blueprint_id=0 + for blueprint in client.get_blueprints(): + if blueprint['name'].lower() == blueprint_name.lower(): + blueprint_id = blueprint['id'] + break + if blueprint_id == 0: + module.fail_json(msg = 'ERROR: Cloud not find blueprint: %s' % blueprint_name) + return blueprint_id + +def get_image_id(image_name,client): + image_id=0 + for image in client.get_images(): + if image['name'].lower() == image_name.lower(): + image_id = image['id'] + break + if image_id == 0: + module.fail_json(msg = 'ERROR: Cloud not find VM image named: %s' % image_name) + return image_id + +def get_image(image_id,client): + try: + image = client.get_image(image_id) + except Exception as e: + module.fail_json(msg = 'ERROR: Cloud not find VM image id: %s' % image_id) + return image + +def main(): + ch = logging.StreamHandler(log_capture_string) + ch.setLevel(logging.DEBUG) + ### Optionally add a formatter + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + ch.setFormatter(formatter) + ### Add the console handler to the logger + logger.addHandler(ch) + argument_spec=dict( + # for nested babu only + url=dict(required=False, type='str'), + state=dict(default='present', choices=['design', 'present', 'started', 'absent', 'stopped', 'list', 'test', 'blueprint','blueprint_delete','blueprint_location']), + username=dict(required=False, type='str'), + password=dict(required=False, type='str'), + name=dict(required=False, type='str'), + app_name=dict(required=False, type='str'), + description=dict(required=False, type='str'), + blueprint_id=dict(required=False, type='str'), + app_template=dict(required=False, default=None, type='path'), + cloud=dict(required=False, type='str'), + region=dict(required=False, type='str'), + publish_optimization=dict(default='cost', choices=['cost', 'performance']), + application_ttl=dict(default='-1', type='int'), + service_name=dict(default='ssh', type='str'), + blueprint_description=dict(required=False, type='str'), + blueprint_name=dict(required=False, type='str'), + wait=dict(type='bool', default=True ,choices=BOOLEANS), + wait_timeout=dict(default=1200, type='int') + ) + module = AnsibleModule( + argument_spec=argument_spec, + mutually_exclusive=[['blueprint', 'app_template']], + # We really really should support this... + # supports_check_mode = True + ) + if not HAS_RAVELLO_SDK: + module.fail_json(msg='ravello_sdk required for this module') + + # Get User credentials from Ansible (not too secure) or ENV variables (a little more secure) + username = module.params.get('username', os.environ.get('RAVELLO_USERNAME', None)) + password = module.params.get('password', os.environ.get('RAVELLO_PASSWORD', None)) + if username and password: + try: + client = RavelloClient(username, password, module.params.get('url')) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = 'ERROR: Failed to authenticate to Ravello using ansiblie provided credentials %s' % e,stdout='%s' % log_contents) + else: + #Get user credentials from SDK auth cache file (better) + try: + username, password = get_user_credentials(None) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = 'ERROR: Failed to retrieve credentials from Ravello SDK credentials cache %s' % e,stdout='%s' % log_contents) + if not username or not password: + module.fail_json(msg = 'ERROR: Unable to get any Ravello credentials!') + try: + client = connect(username, password) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = 'ERROR: Failed to authenticate to Ravello using Ravello SDK credentials cache %s' % e,stdout='%s' % log_contents) + + if module.params.get('state') == 'design': + create_app(client, module) + elif module.params.get('state') == 'present': + create_app_and_publish(client, module) + elif module.params.get('state') == 'absent': + action_on_app(module, client, client.delete_application, lambda: None, 'Deleted') + elif module.params.get('state') == 'started': + action_on_app(module, client, client.start_application, functools.partial(_wait_for_state,client,'STARTED',module), 'Started') + elif module.params.get('state') == 'stopped': + action_on_app(module, client, client.stop_application, functools.partial(_wait_for_state,client,'STOPPED',module), 'Stopped') + elif module.params.get('state') == 'list': + list_app(client, module) + elif module.params.get('state') == 'blueprint': + create_blueprint(module, client, client.create_blueprint) + elif module.params.get('state') == 'blueprint_delete': + action_on_blueprint(module, client, client.delete_blueprint) + elif module.params.get('state') == 'blueprint_location': + action_on_blueprint(module, client, client.get_blueprint_publish_locations) + elif module.params.get('state') == 'test': + module.exit_json(msg = 'Authentication to Ravello successful') + +def _wait_for_state(client, state, module): + if module.params.get('wait') == False: + return + wait_timeout = module.params.get('wait_timeout') + app_id = 0 + wait_till = time.time() + wait_timeout + while wait_till > time.time(): + if app_id > 0: + app = client.get_application(app_id) + else: + app = client.get_application_by_name(module.params.get('app_name')) + app_id = app['id'] + states = list(set((vm['state'] for vm in app.get('deployment', {}).get('vms', [])))) + if "ERROR" in states: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = 'Vm got ERROR state',stdout='%s' % log_contents) + if len(states) == 1 and states[0] == state: + return + time.sleep(10) + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = 'Timed out waiting for async operation to complete.', stdout='%s' % log_contents) + +def is_wait_for_external_service(supplied_service,module): + return supplied_service['name'].lower() == module.params.get('service_name').lower() and supplied_service['external'] == True + +def get_list_app_vm_result(app, vm, module): + + for supplied_service in vm['suppliedServices']: + if is_wait_for_external_service(supplied_service, module): + for network_connection in vm['networkConnections']: + if network_connection['ipConfig']['id'] == supplied_service['ipConfigLuid']: + dest = network_connection['ipConfig'].get('fqdn') + port = int(supplied_service['externalPort'].split(",")[0].split("-")[0]) + return (dest,port) + +def list_app(client, module): + try: + app_name = module.params.get("app_name") + app = client.get_application_by_name(app_name) + + results = [] + + for vm in app['deployment']['vms']: + if vm['state'] != "STARTED": + continue + (dest,port) = get_list_app_vm_result(app, vm, module) + results.append({'host': dest, 'port': port}) + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.exit_json(changed=True, app_name='%s' % app_name, results='%s' % results,stdout='%s' % log_contents) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = '%s' % e,stdout='%s' % log_contents) + +def action_on_app(module, client, runner_func, waiter_func, action): + try: + app_name = module.params.get("app_name") + app = client.get_application_by_name(app_name) + runner_func(app['id']) + waiter_func() + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.exit_json(changed=True, app_name='%s application: %s' %(action, app_name),stdout='%s' % log_contents) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = '%s' % e,stdout='%s' % log_contents) + +def create_blueprint(module, client, runner_func): + app_name = module.params.get("app_name") + app = client.get_application_by_name(app_name) + blueprint_name = module.params.get("blueprint_name") + blueprint_description = module.params.get("blueprint_description") + blueprint_dict = {"applicationId":app['id'], "blueprintName":blueprint_name, "offline": True, "description":blueprint_description } + try: + blueprint_id=((runner_func(blueprint_dict))['_href'].split('/'))[2] + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.exit_json(changed=True, app_name='%s' % app_name, blueprint_name='%s' % blueprint_name, blueprint_id='%s' % blueprint_id) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = '%s' % e,stdout='%s' % log_contents) + +def action_on_blueprint(module, client, runner_func): + if module.params.get("blueprint_id"): + blueprint_id = module.params.get("blueprint_id") + elif module.params.get("blueprint_name"): + blueprint_name = module.params.get("blueprint_name") + blueprint_id = get_blueprint_id(blueprint_name, client) + try: + output = runner_func(blueprint_id) + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.exit_json(changed=True, stdout='%s' % log_contents, blueprint_id='%s' % blueprint_id, output='%s' % output) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = '%s' % e,stdout='%s' % log_contents) + +def create_app(client, module): + app_name = module.params.get("app_name") + cap = client.get_applications({'name': app_name}) + if cap: + module.fail_json(msg='ERROR: Application %s already exists!' % app_name, changed=False) + blueprint_name = app_name + "-bp" + bp = client.get_blueprints({'name': blueprint_name}) + if bp: + module.fail_json(msg='ERROR: Blueprint %s already exists!' % blueprint_name, changed=False) + app_description = module.params.get("description") + if not module.params.get("app_template"): + module.fail_json(msg='Must supply an app_template for design state.', changed=False) + app_template = module.params.get("app_template") + with open(app_template, 'r') as data: + try: + read_app = yaml.load(data) + except yaml.YAMLError as exc: + print(exc) + rand_str = lambda n: ''.join([random.choice(string.lowercase) for i in xrange(n)]) + new_app = {} + new_app['name'] = "tmp-app-build-" + rand_str(10) + new_app['description'] = app_description + new_app['design'] = {} + new_app['design']['vms'] = [] + for vm in read_app['vms']: + pubip = False + if not 'description' in vm: + vm['description'] = "" + if 'tag' in vm: + vm['description'] = vm['description'] + "\ntag:" + vm['tag'] + "\n" + if not 'numCpus' in vm: + module.fail_json(msg = 'ERROR numCpus not specified for VM!') + new_vm = {'name': vm['name'], + 'description': vm['description'], + 'baseVmId': 0, + 'os': 'linux_manuel', + 'numCpus': vm['numCpus'] + } + if 'hostnames' in vm: + new_vm['hostnames'] = vm['hostnames'] + if not 'memorySize' in vm: + module.fail_json(msg = 'ERROR memorySize subsection not specified for VM!') + else: + new_vm['memorySize'] = { 'unit': vm['memorySize']['unit'], + 'value': vm['memorySize']['value'] + } + if 'keypairName' in vm: + new_vm['keypairName'] = vm['keypairName'] + if 'supportsCloudInit' in vm: + new_vm['supportsCloudInit'] = vm['supportsCloudInit'] + if 'stopTimeOut' in vm: + new_vm['stopTimeOut'] = vm['stopTimeOut'] + else: + new_vm['stopTimeOut'] = 300 + if 'allowNested' in vm: + new_vm['allowNested'] = vm['allowNested'] + if 'bootOrder' in vm: + new_vm['bootOrder'] = vm['bootOrder'] + else: + new_vm['bootOrder'] = ['DISK', 'CDROM'] + if not 'hardDrives' in vm: + module.fail_json(msg = 'ERROR no hardDrives subsection defined in template!') + drives = new_vm['hardDrives'] = [] + for hd in vm['hardDrives']: + if not 'index' in hd: + module.fail_json(msg = 'You must specify an index for all HDs!') + if not 'type' in hd: + hd['type'] = "DISK" + if hd['type'] != "DISK" and hd['type'] != "CDROM": + module.fail_json(msg = 'For HD type specify DISK or CDROM!') + if not 'controller' in hd: + hd['controller'] = "virtio" + if hd['controller'] != "virtio" and hd['controller'] != "ide": + module.fail_json(msg = 'For HD controller specify virtio or ide!') + if not 'boot' in hd: + hd['boot'] = False + if not 'name' in hd: + hd['name'] = "Disk ", hd['index'] + new_drive = { 'index': hd['index'], + 'type': hd['type'], + 'boot': hd['boot'], + 'controller': hd['controller'], + 'name': hd['name'], + } + if not 'size' in hd: + module.fail_json(msg = 'ERROR HD size not specified for VM!') + else: + if not 'unit' in hd['size']: + module.fail_json(msg = 'ERROR HD size unit not defined') + if not 'value' in hd['size']: + module.fail_json(msg = 'ERROR HD size value not defined') + if hd['size']['unit'] != "GB" and hd['size']['unit'] != "MB": + module.fail_json(msg = 'ERROR HD size unit must be GB or MB') + if not int(hd['size']['value']): + module.fail_json(msg = 'ERROR HD size value must be an int') + new_drive['size'] = { 'unit': hd['size']['unit'], + 'value': hd['size']['value'] + } + image = {} + if 'baseDiskImageId' in hd: + image = get_diskimage(client, hd['baseDiskImageId']) + if image is None: + module.fail_json(msg = 'FATAL ERROR nonexistent baseDiskImageId %s specified!' % hd['baseDiskImageId']) + elif 'imageName' in hd: + image = get_diskimage(client, hd['imageName']) + if image is None: + module.fail_json(msg = 'FATAL ERROR nonexistent imageName %s specified!' % hd['imageName']) + if 'baseDiskImageId' in hd or 'imageName' in hd: + if hd['size']['value'] < image['size']['value']: + module.fail_json(msg = 'ERROR HD size value (%s) is smaller than the image (%s)' % (hd['size']['value'], image['size']['value'])) + else: + new_drive['baseDiskImageId'] = image['id'] + #else: + # new_drive['baseDiskImageId'] = 0 + drives.append(new_drive) + if not 'networkConnections' in vm: + module.fail_json(msg = 'FATAL ERROR networkConnections subsection not configured in template!') + connections = new_vm['networkConnections'] = [] + for nic in vm['networkConnections']: + if not 'device' in nic: + module.fail_json(msg = 'FATAL ERROR device subsection not configured in networkConnection!') + if not 'ipConfig' in nic: + module.fail_json(msg = 'FATAL ERROR ipConfig subsection not configured in networkConnection!') + if not 'index' in nic['device']: + module.fail_json(msg = 'You must specify an index for all NICs!') + if not 'name' in nic['device']: + nic['device']['name'] = "Nic ", nic['device']['index'] + if not 'deviceType' in nic['device']: + nic['device']['deviceType'] = "virtio" + if nic['device']['deviceType'] != "virtio" and nic['device']['deviceType'] != "e1000": + module.fail_json(msg = 'For NIC device deviceType specify virtio or e1000!') + new_nic = { 'name': nic['name'] } + new_nic['device'] = { 'index': nic['device']['index'], + 'deviceType': nic['device']['deviceType'] + } + if 'useAutomaticMac' in nic['device']: + if nic['device']['useAutomaticMac'] == False: + new_nic['device']['useAutomaticMac'] = False + if 'mac' in nic['device']: + new_nic['device']['mac'] = nic['device']['mac'] + else: + module.fail_json(msg = 'ERROR useAutomaticMac set to False but no static mac set for VM %s NIC index %s!' % (new_vm['name'], new_nic['device']['index'])) + else: + new_nic['device']['useAutomaticMac'] = True + new_nic['ipConfig'] = {} + if 'autoIpConfig' in nic['ipConfig']: + if 'reservedIp' in nic['ipConfig']['autoIpConfig']: + new_nic['ipConfig']['autoIpConfig'] = { 'reservedIp': nic['ipConfig']['autoIpConfig']['reservedIp'] } + elif 'staticIpConfig' in nic['ipConfig']: + if not 'ip' in nic['ipConfig']['staticIpConfig']: + module.fail_json(msg = 'FATAL ERROR ipConfig/staticIpConfig is missing ip!') + if not 'mask' in nic['ipConfig']['staticIpConfig']: + module.fail_json(msg = 'FATAL ERROR ipConfig/staticIpConfig is missing mask!') + new_nic['ipConfig']['staticIpConfig'] = { 'ip': nic['ipConfig']['staticIpConfig']['ip'], + 'mask': nic['ipConfig']['staticIpConfig']['mask'] + } + if 'gateway' in nic['ipConfig']['staticIpConfig']: + new_nic['ipConfig']['staticIpConfig']['gateway'] = nic['ipConfig']['staticIpConfig']['gateway'] + if 'dns' in nic['ipConfig']['staticIpConfig']: + new_nic['ipConfig']['staticIpConfig']['dns'] = nic['ipConfig']['staticIpConfig']['dns'] + if 'hasPublicIp' in nic['ipConfig']: + new_nic['ipConfig']['hasPublicIp'] = True + pubip = True + connections.append(new_nic) + if pubip and 'suppliedServices' in vm: + services = new_vm['suppliedServices'] = [] + for svc in vm['suppliedServices']: + if not 'name' in svc: + module.fail_json(msg = 'FATAL ERROR supplied service missing name!') + if not 'ip' in svc: + module.fail_json(msg = 'FATAL ERROR supplied service missing ip!') + if not 'portRange' in svc: + module.fail_json(msg = 'FATAL ERROR supplied service missing portRange!') + new_svc = { 'external': True, + 'name': svc['name'], + 'ip': svc['ip'], + 'portRange': svc['portRange'] + } + if 'protocol' in svc: + new_svc['protocol'] = svc['protocol'] + services.append(new_svc) + new_app['design']['vms'].append(new_vm) + try: + created_app = client.create_application(new_app) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = '%s' % e,stdout='%s' % log_contents, jsonout='%s' % new_app) + appID = created_app['id'] + blueprint_dict = {"applicationId":appID, "blueprintName":blueprint_name, "offline": False, "description":app_description } + try: + blueprint_id=((client.create_blueprint(blueprint_dict))['_href'].split('/'))[2] + client.delete_application(created_app) + module.exit_json(changed=True, app_name='%s' % app_name, blueprint_name='%s' % blueprint_name, blueprint_id='%s' % blueprint_id) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = '%s' % e,stdout='%s' % log_contents) + +def create_app_and_publish(client, module): + #validation + if not module.params.get("blueprint_id"): + module.fail_json(msg='Must supply a blueprint_id', changed=False) + if 'performance' == module.params.get("publish_optimization"): + if not module.params.get("cloud"): + module.fail_json(msg='Must supply a cloud when publish optimization is performance', changed=False) + if not module.params.get("region"): + module.fail_json(msg='Must supply a region when publish optimization is performance', changed=False) + app = {'name': module.params.get("app_name"), 'description': module.params.get("description",''), 'baseBlueprintId': module.params.get("blueprint_id")} + app = client.create_application(app) + req = {} + if 'performance' == module.params.get("publish_optimization"): + req = {'id': app['id'] ,'preferredCloud': module.params.get("cloud"),'preferredRegion': module.params.get("region"), 'optimizationLevel': 'PERFORMANCE_OPTIMIZED'} + ttl=module.params.get("application_ttl") + if ttl != -1: + ttl =ttl * 60 + exp_req = {'expirationFromNowSeconds': ttl} + client.set_application_expiration(app,exp_req) + client.publish_application(app, req) + _wait_for_state(client,'STARTED',module) + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.exit_json(changed=True, app_name='%s' % module.params.get("app_name"),stdout='%s' % log_contents, app_id='%s' % app['id']) + +# import module snippets +import ansible +import os +import functools +import logging +import io +import datetime +import sys +import yaml +import json + +logger = logging.getLogger() +logger.setLevel(logging.DEBUG) +log_capture_string = io.BytesIO() + +from ansible.module_utils.basic import * + +main() diff --git a/ansible/cloud_providers/ravello/roles/application_create_from_blueprint/tasks/main.yml b/ansible/cloud_providers/ravello/roles/application_create_from_blueprint/tasks/main.yml new file mode 100644 index 00000000000..dc06c7737cb --- /dev/null +++ b/ansible/cloud_providers/ravello/roles/application_create_from_blueprint/tasks/main.yml @@ -0,0 +1,40 @@ +--- +- name: display variables for create application based on deployed blueprint and wait for start + debug: + var: "{{ item }}" + verbosity: 1 + with_items: + - application_name + - application_description + - blueprint_id + - wait_timeout + +- name: create application based on deployed blueprint and wait for start + local_action: + module: ravello_app + app_name: "{{ application_name }}" + description: "{{ application_description }}" + state: present + blueprint_id: "{{ blueprint_id }}" + wait_timeout: "{{ wait_timeout }}" + register: app_results + +- debug: + var: "{{ item }}" + verbosity: 1 + with_items: + - app_results.app_name + - app_results.app_id + +- name: delete blueprint used to create application + local_action: + blueprint_name: "{{ design_results.app_name + '-bp' }}" + blueprint_id: "{{ design_results.blueprint_id }}" + app_name: "{{ app_results.app_name }}" + module: ravello_app + state: blueprint_delete + register: bp_delete_results + +- debug: + var: bp_delete_results + verbosity: 1 diff --git a/ansible/cloud_providers/ravello/roles/blueprint_create_from_application/tasks/main.yml b/ansible/cloud_providers/ravello/roles/blueprint_create_from_application/tasks/main.yml new file mode 100644 index 00000000000..5dd72cfee37 --- /dev/null +++ b/ansible/cloud_providers/ravello/roles/blueprint_create_from_application/tasks/main.yml @@ -0,0 +1,33 @@ +--- +- name: display variables for create blueprint from application + debug: + var: "{{ item }}" + verbosity: 1 + with_items: + - application_name + - blueprint_name + - blueprint_description + +- name: stop application + local_action: + module: ravello_app + app_name: "{{ application_name }}" + state: stopped + register: app_stop_results + +- debug: + var: app_stop_results + verbosity: 1 + +- name: create blueprint from application + local_action: + module: ravello_app + app_name: "{{ application_name }}" + blueprint_name: "{{ blueprint_name }}" + blueprint_description: "{{ 'blueprint created via ansible from ' + application_name }}" + state: blueprint + register: bp_create_results + +- debug: + var: bp_create_results + verbosity: 1 diff --git a/ansible/cloud_providers/ravello/roles/blueprint_design/tasks/main.yml b/ansible/cloud_providers/ravello/roles/blueprint_design/tasks/main.yml new file mode 100644 index 00000000000..67df4bf741e --- /dev/null +++ b/ansible/cloud_providers/ravello/roles/blueprint_design/tasks/main.yml @@ -0,0 +1,24 @@ +--- +- name: display variables for create blueprint based on {{ app_template }} + debug: + var: "{{ item }}" + verbosity: 1 + with_items: + - blueprint_name + - blueprint_description + +- name: create blueprint based on {{ app_template }} + local_action: + module: ravello_app + app_name: "{{ blueprint_name }}" + description: "{{ blueprint_description }}" + app_template: '{{ app_template}}' + state: design + register: design_results + +- debug: + var: "{{ item }}" + verbosity: 1 + with_items: + - design_results.name + - design_results.blueprint_id diff --git a/ansible/cloud_providers/ravello/roles/warm_up/tasks/main.yml b/ansible/cloud_providers/ravello/roles/warm_up/tasks/main.yml new file mode 100644 index 00000000000..347c95f6a26 --- /dev/null +++ b/ansible/cloud_providers/ravello/roles/warm_up/tasks/main.yml @@ -0,0 +1,24 @@ +--- +- name: display variables + debug: + var: "{{ item }}" + verbosity: 1 + with_items: + - unique_name + - version + - application_name + - application_description + - blueprint_name + - blueprint_id + - wait_timeout + +- name: test login + local_action: + module: ravello_app + app_name: "{{ application_name }}" + state: test + register: test_results + +- debug: + var: test_results + verbosity: 1 diff --git a/ansible/cloud_providers/ravello/save_environment.yml b/ansible/cloud_providers/ravello/save_environment.yml new file mode 100644 index 00000000000..83e3729fdd2 --- /dev/null +++ b/ansible/cloud_providers/ravello/save_environment.yml @@ -0,0 +1,12 @@ +# Create blueprint from existing app +--- + - hosts: localhost + tasks: + - local_action: + module: ravello_app + name: 'ansible-brett-demo-version1.1-app-v1.0' +# app_name: 'brett-demo-version1.1' +# state: 'stopped' + blueprint_name: 'test-brett-bp-save' + blueprint_description: 'Blueprint of app xyz' + state: blueprint diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/README.md b/ansible/configs/RHCLS-ScalableInfra-demo/README.md new file mode 100644 index 00000000000..b8f7d9fcf41 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/README.md @@ -0,0 +1,10 @@ +# RHCLS_ScalableInfrastructure + +This is a set of playbooks that can be used for deploying Red Hat Cloud Suite's Scalable Infrastructure demonstration. The Scalable Infrastructure demonstration. + +=== Overview +This is demonstration of how Red Hat is delivering scalable infrastructure with the capabilities that enterprises demand. Red Hat OpenStack Platform delivers scale-out private cloud capabilities with a stable lifecycle and large ecosystem of supported hardware platforms. Many organizations are building their next generation cloud infrastructures on OpenStack because it provides an asynchronous architecture and is API centric allowing for greater scale and greater efficiency in platform management. OpenStack does not, however, provide functionality such as chargeback, reporting, and policy driven automation for tenant workloads and those projects that aspire to do so are generally focused solely on OpenStack. This is not realistic in an increasingly hybrid world – and enterprises that are serious about OpenStack need these capabilities. By using Red Hat CloudForms together with Red Hat OpenStack Platform it’s possible to provide capabilities such as reporting, chargeback, and auditing of tenant workloads across a geographically diverse deployment. In the demo we demonstrate how chargeback across a multi-site OpenStack deployment works. + +=== Structure + * ./env holds playbooks for creating environments. For example, creating a blueprint in Ravello or heatstack on OpenStack. + * ./cfg holds playbooks for configuring the demonstration on the created environments. diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/bastion b/ansible/configs/RHCLS-ScalableInfra-demo/bastion new file mode 100644 index 00000000000..333483a9b80 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/bastion @@ -0,0 +1,159 @@ +services + proc-sys-fs-binfmt_misc.automount loaded active waiting Arbitrary Executable File Formats File System Automount Point + sys-devices-pci0000:00-0000:00:01.1-ata1-host0-target0:0:0-0:0:0:0-block-sda.device loaded active plugged LVM PV BXfIcw-90nD-CFEf-nF8v-QSpB-zfTN-ftv2dc on /dev/sda + sys-devices-pci0000:00-0000:00:03.0-virtio0-net-eth0.device loaded active plugged Virtio network device + sys-devices-pci0000:00-0000:00:04.0-virtio1-block-vda-vda1.device loaded active plugged /sys/devices/pci0000:00/0000:00:04.0/virtio1/block/vda/vda1 + sys-devices-pci0000:00-0000:00:04.0-virtio1-block-vda.device loaded active plugged /sys/devices/pci0000:00/0000:00:04.0/virtio1/block/vda + sys-devices-pci0000:00-0000:00:05.0-virtio2-block-vdb.device loaded active plugged /sys/devices/pci0000:00/0000:00:05.0/virtio2/block/vdb + sys-devices-platform-floppy.0-block-fd0.device loaded active plugged /sys/devices/platform/floppy.0/block/fd0 + sys-devices-platform-serial8250-tty-ttyS1.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS1 + sys-devices-platform-serial8250-tty-ttyS2.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS2 + sys-devices-platform-serial8250-tty-ttyS3.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS3 + sys-devices-pnp0-00:05-tty-ttyS0.device loaded active plugged /sys/devices/pnp0/00:05/tty/ttyS0 + sys-devices-virtual-block-dm\x2d0.device loaded active plugged /sys/devices/virtual/block/dm-0 + sys-devices-virtual-block-dm\x2d1.device loaded active plugged /sys/devices/virtual/block/dm-1 + sys-devices-virtual-block-dm\x2d2.device loaded active plugged /sys/devices/virtual/block/dm-2 + sys-devices-virtual-net-virbr0.device loaded active plugged /sys/devices/virtual/net/virbr0 + sys-devices-virtual-net-virbr0\x2dnic.device loaded active plugged /sys/devices/virtual/net/virbr0-nic + sys-module-configfs.device loaded active plugged /sys/module/configfs + sys-subsystem-net-devices-eth0.device loaded active plugged Virtio network device + sys-subsystem-net-devices-virbr0.device loaded active plugged /sys/subsystem/net/devices/virbr0 + sys-subsystem-net-devices-virbr0\x2dnic.device loaded active plugged /sys/subsystem/net/devices/virbr0-nic + -.mount loaded active mounted / + dev-hugepages.mount loaded active mounted Huge Pages File System + dev-mqueue.mount loaded active mounted POSIX Message Queue File System + exports-cinder-newyork.mount loaded active mounted /exports/cinder/newyork + exports-cinder-paris.mount loaded active mounted /exports/cinder/paris + exports-cinder-tokyo.mount loaded active mounted /exports/cinder/tokyo + proc-fs-nfsd.mount loaded active mounted NFSD configuration filesystem + run-user-1673106860.mount loaded active mounted /run/user/1673106860 + sys-kernel-config.mount loaded active mounted Configuration File System + sys-kernel-debug.mount loaded active mounted Debug File System + var-lib-nfs-rpc_pipefs.mount loaded active mounted RPC Pipe File System + brandbot.path loaded active waiting Flexible branding + cups.path loaded active waiting CUPS Printer Service Spool + systemd-ask-password-plymouth.path loaded active waiting Forward Password Requests to Plymouth Directory Watch + systemd-ask-password-wall.path loaded active waiting Forward Password Requests to Wall Directory Watch + session-2.scope loaded active running Session 2 of user bthurber-redhat.com + abrt-ccpp.service loaded active exited Install ABRT coredump hook + abrt-oops.service loaded active running ABRT kernel log watcher + abrtd.service loaded active running ABRT Automated Bug Reporting Tool + alsa-state.service loaded active running Manage Sound Card State (restore and store) + atd.service loaded active running Job spooling tools + auditd.service loaded active running Security Auditing Service + avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack + blk-availability.service loaded active exited Availability of block devices + chronyd.service loaded active running NTP client/server + cloud-config.service loaded active exited Apply the settings specified in cloud-config + cloud-final.service loaded active exited Execute cloud user/final scripts + cloud-init-local.service loaded active exited Initial cloud-init job (pre-networking) + cloud-init.service loaded active exited Initial cloud-init job (metadata service crawler) + crond.service loaded active running Command Scheduler + cups.service loaded active running CUPS Printing Service + dbus.service loaded active running D-Bus System Message Bus + getty@tty1.service loaded active running Getty on tty1 + gssproxy.service loaded active running GSSAPI Proxy Daemon + irqbalance.service loaded active running irqbalance daemon + iscsi-shutdown.service loaded active exited Logout off all iSCSI sessions on shutdown + kdump.service loaded active exited Crash recovery kernel arming + kmod-static-nodes.service loaded active exited Create list of required static device nodes for the current kernel + ksm.service loaded active exited Kernel Samepage Merging + ksmtuned.service loaded active running Kernel Samepage Merging (KSM) Tuning Daemon + libstoragemgmt.service loaded active running libstoragemgmt plug-in server daemon + libvirtd.service loaded active running Virtualization daemon + lvm2-lvmetad.service loaded active running LVM2 metadata daemon + lvm2-monitor.service loaded active exited Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling + lvm2-pvscan@8:0.service loaded active exited LVM2 PV scan on device 8:0 + ModemManager.service loaded active running Modem Manager + netcf-transaction.service loaded active exited Rollback uncommitted netcf network config change transactions + network.service loaded active exited LSB: Bring up/down networking + NetworkManager.service loaded active running Network Manager + nfs-config.service loaded active exited Preprocess NFS configuration + nfs-idmapd.service loaded active running NFSv4 ID-name mapping service + nfs-mountd.service loaded active running NFS Mount Daemon + nfs-server.service loaded active exited NFS server and services + oddjobd.service loaded active running privileged operations for unprivileged applications +● ovirt-guest-agent.service loaded failed failed oVirt Guest Agent + polkit.service loaded active running Authorization Manager + postfix.service loaded active running Postfix Mail Transport Agent + rhel-dmesg.service loaded active exited Dump dmesg to /var/log/dmesg + rhel-domainname.service loaded active exited Read and set NIS domainname from /etc/sysconfig/network + rhel-import-state.service loaded active exited Import network configuration from initramfs + rhel-readonly.service loaded active exited Configure read-only root support + rhnsd.service loaded active running LSB: Starts the Spacewalk Daemon + rngd.service loaded active running Hardware RNG Entropy Gatherer Daemon + rpc-statd.service loaded active running NFS status monitor for NFSv2/3 locking. + rpcbind.service loaded active running RPC bind service + rsyslog.service loaded active running System Logging Service + serial-getty@ttyS0.service loaded active running Serial Getty on ttyS0 + smartd.service loaded active running Self Monitoring and Reporting Technology (SMART) Daemon + sshd.service loaded active running OpenSSH server daemon + sssd.service loaded active running System Security Services Daemon + sysstat.service loaded active exited Resets System Activity Logs + systemd-journal-flush.service loaded active exited Flush Journal to Persistent Storage + systemd-journald.service loaded active running Journal Service + systemd-logind.service loaded active running Login Service + systemd-random-seed.service loaded active exited Load/Save Random Seed + systemd-remount-fs.service loaded active exited Remount Root and Kernel File Systems + systemd-sysctl.service loaded active exited Apply Kernel Variables + systemd-tmpfiles-setup-dev.service loaded active exited Create Static Device Nodes in /dev + systemd-tmpfiles-setup.service loaded active exited Create Volatile Files and Directories + systemd-udev-settle.service loaded active exited udev Wait for Complete Device Initialization + systemd-udev-trigger.service loaded active exited udev Coldplug all Devices + systemd-udevd.service loaded active running udev Kernel Device Manager + systemd-update-utmp.service loaded active exited Update UTMP about System Boot/Shutdown + systemd-user-sessions.service loaded active exited Permit User Sessions + systemd-vconsole-setup.service loaded active exited Setup Virtual Console + tuned.service loaded active running Dynamic System Tuning Daemon + wpa_supplicant.service loaded active running WPA Supplicant daemon + -.slice loaded active active Root Slice + system-getty.slice loaded active active system-getty.slice + system-lvm2\x2dpvscan.slice loaded active active system-lvm2\x2dpvscan.slice + system-serial\x2dgetty.slice loaded active active system-serial\x2dgetty.slice + system.slice loaded active active System Slice + user-1673106860.slice loaded active active user-1673106860.slice + user.slice loaded active active User and Session Slice + avahi-daemon.socket loaded active running Avahi mDNS/DNS-SD Stack Activation Socket + cups.socket loaded active running CUPS Printing Service Sockets + dbus.socket loaded active running D-Bus System Message Bus Socket + dm-event.socket loaded active listening Device-mapper event daemon FIFOs + iscsid.socket loaded active listening Open-iSCSI iscsid Socket + iscsiuio.socket loaded active listening Open-iSCSI iscsiuio Socket + lvm2-lvmetad.socket loaded active running LVM2 metadata daemon socket + lvm2-lvmpolld.socket loaded active listening LVM2 poll daemon socket + rpcbind.socket loaded active running RPCbind Server Activation Socket + systemd-initctl.socket loaded active listening /dev/initctl Compatibility Named Pipe + systemd-journald.socket loaded active running Journal Socket + systemd-shutdownd.socket loaded active listening Delayed Shutdown Socket + systemd-udevd-control.socket loaded active running udev Control Socket + systemd-udevd-kernel.socket loaded active running udev Kernel Socket + basic.target loaded active active Basic System + cloud-config.target loaded active active Cloud-config availability + cryptsetup.target loaded active active Encrypted Volumes + getty.target loaded active active Login Prompts + local-fs-pre.target loaded active active Local File Systems (Pre) + local-fs.target loaded active active Local File Systems + multi-user.target loaded active active Multi-User System + network-online.target loaded active active Network is Online + network.target loaded active active Network + nfs-client.target loaded active active NFS client services + nss-lookup.target loaded active active Host and Network Name Lookups + nss-user-lookup.target loaded active active User and Group Name Lookups + paths.target loaded active active Paths + remote-fs-pre.target loaded active active Remote File Systems (Pre) + remote-fs.target loaded active active Remote File Systems + rpcbind.target loaded active active RPC Port Mapper + slices.target loaded active active Slices + sockets.target loaded active active Sockets + swap.target loaded active active Swap + sysinit.target loaded active active System Initialization + timers.target loaded active active Timers + systemd-tmpfiles-clean.timer loaded active waiting Daily Cleanup of Temporary Directories + unbound-anchor.timer loaded active waiting daily update of the root trust anchor for DNSSEC + + +/etc/exports +/exports/cinder/tokyo *(rw,fsid=0,no_subtree_check,sync,no_root_squash) +/exports/cinder/paris *(rw,fsid=0,no_subtree_check,sync,no_root_squash) +/exports/cinder/newyork *(rw,fsid=0,no_subtree_check,sync,no_root_squash) + diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/README b/ansible/configs/RHCLS-ScalableInfra-demo/examples/README new file mode 100644 index 00000000000..b3c88cc2913 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/README @@ -0,0 +1,164 @@ +These are sample scripts showing how to use Ravello Python SDK to connect and Ravello environment. The scripts require Python and Ravello Python SDK to be installed. + +All scripts accept -u parameter and prompt for password. If you want to run scripts in a batch mode you can use set-creds script to store user credentials in an encrypted file. Set-creds script prompts to enter user credentials and, encrypts user password and stores user credentials in .ravello_login file in the user home directory. After that you can run scripts without specifying user credentials. If you want to run a script and connect to Ravello with a user different from the one that is stores in .ravello_login file use -u option. + +To get help and usage information run scripts with "-h" option. + +Scripts that manage/create applications, VMs, ephemeral tokens write to ravello.log log file created in the working directory. + +Here is a list of scripts and usage examples: + + +app-create - creates a new application from blueprint +Example: + app-create -b "Openstack-bp" -n "my app1" -p -c Amazon -r Virginia + Creates an application "my app1" from blueprint "Openstack-bp" and publishes the application (if -p flag is used) on Amazon/Virginia Cloud. The application won't be started automatically unless you add "-s yes" flag. + + app-create -b "Openstack-bp" -n "my app2" -p -s yes -t 60 + Creates an application "my app1" from blueprint "Openstack-bp", publishes the application using the default COST_OPTIMIZED cloud and starts it setting expiration time to 60 minutes. + + app-create -b "Openstack-bp" -n "my app3" + Creates an application "my app1" from blueprint "Openstack-bp" but does not publish it. + + +etoken-create - creates ephemeral access token and sets permissions + +Examples: + etoken-create -n bench -d "Ephemeral token to grant access to my app" "Access token1" -p READ UPDATE EXECUTE + Creates an ephemeral access token "Access token1" with description specified by -d parameter and sets permissions to READ, UPDATE and EXECUTE + + etoken-create -n bench -d "Ephemeral token to grant access to my app" "Access token2" -t 120 + Creates an ephemeral access token "Access token2" and sets token expiration time to 120 minutes. Token permissions by default are set to READ, EXECUTE unless they are explicitly specified by -p flag. + + + +app-get-all - returns information about all applications in the user account in format: Application name, ID, creation date, owner, if-published, Cloud + +Example: + app-get-all + Returns information about all applications in the above format + + app-get-all -u + Returns information about all applications in the Ravello user account specified by -u option. When -u option is used the script prompts to enter password. + + +app-get-data - returns the application data + +Example: + app-get-data "My app1" + + Here is an example of the output showing the application summary: + name: My App1 + id: 67207922 + owner: John Kave + publishOptimization: PERFORMANCE_OPTIMIZED + cloud: Amazon + regionName: Virginia + totalActiveVms: 0 + totalStoppedVms: 3 + totalErrorVms: 0 + + app-get-data -i 67207922 + Similar to the above it prints application summary, but as a parameter it accepts application ID instead of application name. + + app-get-data "My app1" -o app1.txt + In addition to application summary it stores the application JSON file info app1.txt file including the application properties, list of VMs, the application network, and so on. + + app-get-data "My app1" -a + Prints application JSON file to the standard output + + +app-get-state - returns the application state. Application states are STARTED, STARTING, STOPPED, STOPPING, et + +Example: + app-get-state "My App1" + Returns the application state of "My App1" + + app-get-state -i 67207922 + Returns the application state of an application with ID 67207922 + + +app-start - starts the application and sets the expiration time. The script checks the state of the application prior to starting it. If the application is already in a transition state (STARTING|STOPPING) or in an ERROR state the script cancels the command. + +Example: + app-start "My app1" + Starts "My app1" application and sets the expiration time to 2 hours (default) + + app-start "My app1" -e 60 + Starts "My app1" application and sets the expiration time to 60 min + + app-start -i 67207922 + Starts an application with application ID 67207922 and sets the expiration time to 2 hours (default) + +app-stop - stops the application if it is in STARTED state. The script checks the state of the application prior to starting it. If the application is already in a transition state (STARTING|STOPPING) or in an ERROR state the script cancels the command. + +Example: + app-stop "My app1" + Stops "My app1" application + + app-stop -i 67207922 + Stops an application with application ID 67207922 + + +app-get-id - returns application ID + +Example: + app-get-id "My app1" + Returns ID of the application "My App1" + + +app-get-vms - returns information about application VMs including VM name, ID and state + +Example: + app-get-vms "My app1" + Returns VM summary information. Here is an example of the output: + Name: WebServer1 ID: 849341096919040 State: STOPPED + Name: WebServer2 ID: 1426184860598272 State: STOPPED + Name: LoadBalancer ID: 4773896427405312 State: STOPPED + + app-get-vms "My app1" -o app1.txt + Returns VM summary information and prints a complete VM JSON data to app1.txt file + + app-get-vms -i 67207922 -o app1.txt + Similar to the above but uses application ID instead of application name + +app-update - updates the application loading data from a provided JSON file. If you need to change the application JSON file manually first use app-get-data script with -o option to dump the application JSON data into a file. Then you can modify the file and use app-update to update the application. Certain fields are not allowed to be modified manually. + +Example: + app-update -f app.txt + Updates an application from the input JSON file app.txt + + +app-mgmt - manages application VMs. Available commands: start, stop, restart, poweroff, redeploy, repair, resetDisks. + +Example: + vm-mgmt -a "MyApp1" -v "WebServer1" start + Starts VM "WebServer1 from the application MyApp1". The script checks the state of the VM prior to starting it. If the VM is already in a transition state (STARTING|STOPPING|RESTARTING) or in an ERROR state the script cancels the command. If the VM is already started, the script skips the command and exits. + + vm-mgmt -a "MyApp1" -v "WebServer1" stop + Stops VM "WebServer1" from the application MyApp1". The script checks the state of the VM prior to stopping it. If the VM is already in a transition state (STARTING|STOPPING|RESTARTING) or in an ERROR state the script cancels the command. If the VM is already stopped, the script skips the command and exits. + + vm-mgmt -a "MyApp1" -v "WebServer1" stop + Restarts VM "WebServer1". The script checks the state of the VM prior to restarting it. If the VM is already in a transition state (STARTING|STOPPING|RESTARTING) or in an ERROR state the script cancels the command. + + vm-mgmt -n 67207922 -v "WebServer1" stop + Same as the above only using the application ID instead of the application name + + +bp-get-all - returns information about all blue prints in the user account in format: Blueprint name, ID, creation date, owner, description + +Example: + bp-get-all + Returns list of all blueprints in the user account + + app-get-all -u + Returns list of all applications in Ravello user specified by -u option. When -u option is used the script prompts to enter password. + + +app-get-billing - returns billing information of all application for a given time period + +Example: + app-get-billing -m 12 -y 2015 + Returns list of applications and their cost in December 2015 + + diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/ansible/library/ravello_app.py b/ansible/configs/RHCLS-ScalableInfra-demo/examples/ansible/library/ravello_app.py new file mode 100644 index 00000000000..52a762a2645 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/ansible/library/ravello_app.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +#test +# (c) 2015, ravellosystems +# +# author zoza +# +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +###################################################################### + + +try: + from ravello_sdk import * + +except ImportError: + print "failed=True msg='ravello sdk required for this module'" + sys.exit(1) + + + +DOCUMENTATION = ''' +--- +module: ravello_app +short_description: Create/delete/start/stop an application in ravellosystems +description: + - Create/delete/start/stop an application in ravellosystems and wait for it (optionally) to be 'running' + - list state will return a fqdn list of exist application hosts with their external services +options: + state: + description: + - Indicate desired state of the target. + default: present + choices: ['present', 'started', 'absent', 'stopped','list'] + username: + description: + - ravello username + password: + description: + - ravello password + + service_name: + description: + - Supplied Service name for list state + default: ssh + + name: + description: + - application name + description: + description: + - application description + blueprint_id: + description: + - create app, based on this blueprint + + #publish options + cloud: + description: + - cloud to publish + region: + description: + - region to publish + publish_optimization: + default: cost + choices: ['cost', 'performance'] + + application_ttl: + description: + - application autostop in mins + default: -1 # never + wait + description: + - Wait for the app to be in state 'running' before returning. + default: True + choices: [ True, False ] + wait_timeout: + description: + - How long before wait gives up, in seconds. + default: 600 +''' + +EXAMPLES = ''' +# Create app, based on blueprint, start it and wait for started +- local_action: + module: ravello_app + username: user@ravello.com + password: password + name: 'my-application-name' + description: 'app desc' + blueprint_id: '2452' + wait: True + wait_timeout: 600 + state: present + +# Create app, based on blueprint +- local_action: + module: ravello_app + username: user@ravello.com + password: password + name: 'my-application-name' + description: 'app desc' + publish_optimization: performance + cloud:AMAZON + region: Oregon + state: present + +# List application example +- local_action: + module: ravello_app + name: 'my-application-name' + service_name: 'ssh' + state: list + +# Delete application example +- local_action: + module: ravello_app + name: 'my-application-name' + state: absent + +# Delete application example from matryoshka (nested) +- local_action: + module: ravello_app + url: 'https://matryoshka.com/api/v1' or https://matryoshka.com/services + name: 'my-application-name' + state: absent +''' + +# import module snippets +from ansible.module_utils.basic import * +import ansible +import os +import functools +import logging +import io +import datetime +import sys + +logger = logging.getLogger() +logger.setLevel(logging.DEBUG) +log_capture_string = io.BytesIO() + +def main(): + + ch = logging.StreamHandler(log_capture_string) + ch.setLevel(logging.DEBUG) + ### Optionally add a formatter + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + ch.setFormatter(formatter) + + ### Add the console handler to the logger + logger.addHandler(ch) + module = AnsibleModule( + argument_spec=dict( + # for nested babu only + url=dict(required=False, type='str'), + + state=dict(default='present', choices=['present', 'started', 'absent', 'stopped', 'list', 'blueprint']), + + username=dict(required=False, type='str'), + password=dict(required=False, type='str'), + + name=dict(required=True, type='str'), + description=dict(required=False, type='str'), + blueprint_id=dict(required=False, type='str'), + + cloud=dict(required=False, type='str'), + region=dict(required=False, type='str'), + publish_optimization=dict(default='cost', choices=['cost', 'performance']), + application_ttl=dict(default='-1', type='int'), + + service_name=dict(default='ssh', type='str'), + + blueprint_description=dict(required=False, type='str'), + blueprint_name=dict(required=False, type='str'), + + wait=dict(type='bool', default=True ,choices=BOOLEANS), + wait_timeout=dict(default=1200, type='int') + ) + ) + try: + username = module.params.get('username', os.environ.get('RAVELLO_USERNAME', None)) + password = module.params.get('password', os.environ.get('RAVELLO_PASSWORD', None)) + + client = RavelloClient(username, password, module.params.get('url')) + + if module.params.get('state') == 'present': + create_app_and_publish(client, module) + elif module.params.get('state') == 'absent': + action_on_app(module, client, client.delete_application, lambda: None, 'Deleted') + elif module.params.get('state') == 'started': + action_on_app(module, client, client.start_application, functools.partial(_wait_for_state,client,'STARTED',module), 'Started') + elif module.params.get('state') == 'stopped': + action_on_app(module, client, client.stop_application, functools.partial(_wait_for_state,client,'STOPPED',module), 'Stopped') + elif module.params.get('state') == 'list': + list_app(client, module) + elif module.params.get('state') == 'blueprint': + action_on_blueprint(module, client, client.create_blueprint) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = '%s' % e,stdout='%s' % log_contents) + +def _wait_for_state(client, state, module): + + if module.params.get('wait') == False: + return + + wait_timeout = module.params.get('wait_timeout') + app_id = 0 + wait_till = time.time() + wait_timeout + while wait_till > time.time(): + if app_id > 0: + app = client.get_application(app_id) + else: + app = client.get_application_by_name(module.params.get('name')) + app_id = app['id'] + + states = list(set((vm['state'] for vm in app.get('deployment', {}).get('vms', [])))) + if "ERROR" in states: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = 'Vm got ERROR state',stdout='%s' % log_contents) + if len(states) == 1 and states[0] == state: + return + time.sleep(10) + + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = 'Timed out waiting for async operation to complete.', stdout='%s' % log_contents) + +def is_wait_for_external_service(supplied_service,module): + return supplied_service['name'].lower() == module.params.get('service_name').lower() and supplied_service['external'] == True + +def get_list_app_vm_result(app, vm, module): + + for supplied_service in vm['suppliedServices']: + if is_wait_for_external_service(supplied_service, module): + for network_connection in vm['networkConnections']: + if network_connection['ipConfig']['id'] == supplied_service['ipConfigLuid']: + dest = network_connection['ipConfig'].get('fqdn') + port = int(supplied_service['externalPort'].split(",")[0].split("-")[0]) + return (dest,port) + +def list_app(client, module): + try: + app_name = module.params.get("name") + app = client.get_application_by_name(app_name) + + results = [] + + for vm in app['deployment']['vms']: + if vm['state'] != "STARTED": + continue + (dest,port) = get_list_app_vm_result(app, vm, module) + results.append({'host': dest, 'port': port}) + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.exit_json(changed=True, name='%s' % app_name, results='%s' % results,stdout='%s' % log_contents) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = '%s' % e,stdout='%s' % log_contents) + +def action_on_blueprint(module, client, runner_func): + try: + app_name = module.params.get("name") + app = client.get_application_by_name(app_name) + blueprint_name = module.params.get("blueprint_name") + blueprint_description = module.params.get("blueprint_description") + blueprint_dict = {"applicationId":app['id'], "blueprintName":blueprint_name, "offline": True, "description":blueprint_description } + blueprint_id=((runner_func(blueprint_dict))['_href'].split('/'))[2] + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.exit_json(changed=True, name='%s' % app_name, blueprint_id='%s' % blueprint_id) + + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = '%s' % e,stdout='%s' % log_contents) + +def action_on_app(module, client, runner_func, waiter_func, action): + try: + app_name = module.params.get("name") + app = client.get_application_by_name(app_name) + runner_func(app['id']) + waiter_func() + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.exit_json(changed=True, name='%s application: %s' %(action, app_name),stdout='%s' % log_contents) + except Exception, e: + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.fail_json(msg = '%s' % e,stdout='%s' % log_contents) + +def create_app_and_publish(client, module): + #validation + if not module.params.get("blueprint_id"): + module.fail_json(msg='Must supply a blueprint_id', changed=False) + if 'performance' == module.params.get("publish_optimization"): + if not module.params.get("cloud"): + module.fail_json(msg='Must supply a cloud when publish optimization is performance', changed=False) + if not module.params.get("region"): + module.fail_json(msg='Must supply a region when publish optimization is performance', changed=False) + + app = {'name': module.params.get("name"), 'description': module.params.get("description",''), 'baseBlueprintId': module.params.get("blueprint_id")} + app = client.create_application(app) + + req = {} + if 'performance' == module.params.get("publish_optimization"): + req = {'id': app['id'] ,'preferredCloud': module.params.get("cloud"),'preferredRegion': module.params.get("region"), 'optimizationLevel': 'PERFORMANCE_OPTIMIZED'} + + ttl=module.params.get("application_ttl") + if ttl != -1: + ttl =ttl * 60 + exp_req = {'expirationFromNowSeconds': ttl} + client.set_application_expiration(app,exp_req) + + client.publish_application(app, req) + + _wait_for_state(client,'STARTED',module) + log_contents = log_capture_string.getvalue() + log_capture_string.close() + module.exit_json(changed=True, name='Created and published application: %s .' % module.params.get("name"),stdout='%s' % log_contents) + +main() diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/ansible/test.yml b/ansible/configs/RHCLS-ScalableInfra-demo/examples/ansible/test.yml new file mode 100644 index 00000000000..cc8ab8d4ccf --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/ansible/test.yml @@ -0,0 +1,21 @@ +--- +- name: test revello_app module + hosts: localhost + gather_facts: no + tasks: + - debug: + var: rev_username + - debug: + var: rev_password + - name: create revello app without a blueprint + local_action: + module: ravello_app + username: "{{ rev_username }}" + password: "{{ rev_password }}" + name: 'ansible-revello_app' + description: 'a test revello app using ansible' + publish_optimization: cost + #cloud: AMAZON + #region: Oregon + state: present + blueprint_id: 0 diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-create b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-create new file mode 100755 index 00000000000..f85498726ad --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-create @@ -0,0 +1,227 @@ +#!/usr/bin/env python +# A Ravello SDK example for creating and publishing applications from a blueprint +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +import json +from argparse import ArgumentParser +from common import * + +log = logging.getLogger('main') + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-b", dest="bp_name",default=None,help='blueprint name the application is created from') + parser.add_argument("-i", dest="bp_id",default=0,help='blueprint name the application is created from') + parser.add_argument("-n", dest="app_name",default=None,help='application name') + parser.add_argument("-d", dest="app_desc",default=None,help='application description') + parser.add_argument("-p", dest="publish",default=False,action="store_true",help='publish application') + parser.add_argument("-c", dest="cloud_name",default=None,help='preferred cloud name: AMAZON or GOOGLE') + parser.add_argument("-r", dest="cloud_region",default=None,help='preferred cloud region. On AMAZON the following regions are avaible: Virginia, Oregon, Singapore, Ireland, Sydney, Tokyo, Sao Paulo. On GOOGLE the following regions are available: us-central1, europe-west1') + parser.add_argument("-o", dest="optimization",help='optimization level: COST_OPTIMIZED or PERFORMANCE_OPTIMIZED, when using COST_OPTIMIZED optimization level leave cloud name and region empty') + parser.add_argument("-s", dest="start",default=False,action="store_true",help='start VMs') + parser.add_argument("-t", dest="exp_time",default=False,type=int,help='application expiration time in minutes, use in combination with -s') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + parser.add_argument("-l", dest="log_file", default='ravello.log',help='logfile name') + + return parser + +def validate_param(args): + if not args.bp_name and not args.bp_id: # Blue print name or ID must be provided + log.error("Invalid parameters, either blueprint name or blueprint ID must be provided") + print("Error: Invalid parameters, either blueprint name or blueprint ID must be provided") + return False + + if not args.app_name: + log.error("Invalid parameters, application name must be provided") + print("Error: Invalid parameters, application name must be provided") + return False + + if args.cloud_region and not args.cloud_name: + log.error("Invalid parameters, cloud region is specifed wthout cloud name. Use -c option to specify the cloud name") + print("Error: Invalid parameters, cloud region is specifed wthout cloud name. Use -c option to specify the cloud name") + return False + + if args.cloud_name: + args.cloud_name = args.cloud_name.upper() + if args.cloud_region: + args.cloud_region = args.cloud_region.lower().capitalize() + + return True + +def get_bp_data(bp_id,bp_name,client): + found_pb = None + if bp_id == 0: # If blueprint ID is unknown find the blueprint by name + for bp in client.get_blueprints(): + if bp['name'].lower() == bp_name.lower(): + found_pb = bp + break + else: + for bp in client.get_blueprints(): + if bp['id'] == bp_id: + found_bp = bp + break + return found_pb + +def create_app(app_name,app_desc,bp_id,client): + new_app=None + if (app_name and bp_id!=0): + app={'name':app_name,'description':app_desc,'baseBlueprintId':bp_id} + log.info("Creating a new application {}".format(app_name)) + print("Creating a new application", app_name) + print(app) + new_app = client.create_application(app) + return new_app + +def publish_app(app,cloud_name,cloud_region,optimization_level,start,exp_time,client): + if app: + if cloud_name: + if optimization_level=='COST_OPTIMIZED': + log.warning('Cloud name is specified. Changing optimization level to PERFORMANCE_OPTIMIZED') + print('Cloud name is specified. Changing optimization level to PERFORMANCE_OPTIMIZED') + optimization_level = 'PERFORMANCE_OPTIMIZED' + + elif not optimization_level: + optimization_level = 'COST_OPTIMIZED' + + + param = {'preferredCloud':cloud_name, 'preferredRegion':cloud_region, 'optimizationLevel':optimization_level, 'startAllVms':start} + + log.info("Publishing application {0}".format(app['name'])) + print("Publishing application {0}".format(app['name'])) + log.info(param) + print(param) + + client.publish_application(app,param) + + if start and exp_time: # Set the application expiration time + log.info("Setting the application expiration time to {0} min".format(exp_time)) + print("Setting the application expiration time to {0} min".format(exp_time)) + exp = {'expirationFromNowSeconds': 60*exp_time} + client.set_application_expiration(app['id'], exp) + +def validate_cloud(app_id,cloud_name,cloud_region,client): + + cloud_locations = client.get_application_publish_locations(app_id) + available_regions = [] + found = False + for loc in cloud_locations: + if loc['cloudName'] == cloud_name and (loc['regionName'] == cloud_region or not cloud_region): + found = True + break + cloud_location = loc['cloudName']+'/'+loc['regionName'] + available_regions.append(cloud_location) + + if found: #The app can be published in the specified cloud location + return True + elif not cloud_name and len(available_regions)>0: #Cloud name/region was not specified but there are cloud locations the app can be published + return True + else: #There is no avalable cloud locations where the app can be published + log.error("Invalid cloud region {0}/{1}".format(cloud_name,cloud_region)) + log.info("Available cloud/region locations: {}".format(", ".join(available_regions))) + print("Error: Invalid cloud region {0}/{1}".format(cloud_name,cloud_region)) + print("Available cloud/region locations:") + print (", ".join(available_regions)) + return False + +def delete_app_if_exists(app_name,client,prompt_user): + + app_id = get_app_id(app_name,client) + + if app_id > 0: #Application found + resp = input("Application {0} already exists, do you want to delete it [yes/no]:".format(app_name)) + if resp.lower() == "yes": + log.info("Deleting application {}".format(app_name)) + print("Deleting application",app_name) + client.delete_application(app_id) + return True + else: + log.info("Application {} already exists, exiting...".format(app_name)) + print("Application {} already exists, exiting...".format(app_name)) + return False + #Application not found + return True + +def display_app(app_id,client): + if app_id: + app = client.get_application(app_id) + print() + print ("name: ",app['name']) + print ("id: ",app['id']) + print ("owner: ",app['owner']) + +# Check if this is a published app + app_state = application_state(app) + if app_state != None: #Published app + print ("cloud: ",app['deployment']['cloud']) + print ("publishOptimization: ",app['deployment']['publishOptimization']) + print ("cloud: ",app['deployment']['cloud']) + print ("regionName: ",app['deployment']['regionId']) + print ("totalActiveVms: ",app['deployment']['totalActiveVms']) + print ("totalErrorVms: ",app['deployment']['totalErrorVms']) + print ("Application state: ", app_state) + else: + print("Application {0} is not published".format(app['name'])) +def main(): + parser = mkparser() + args = parser.parse_args() + + if not validate_param(args): + parser.print_help() + exit(1) + + initlog(args.log_file) + + #Get user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + #Check if application with this name already exists and delete it + if not delete_app_if_exists(args.app_name,client,True): + exit(0) #Cancelled by user + + #Get Blue Print ID + bp = get_bp_data(args.bp_id,args.bp_name,client) + + if bp: + #Create application + new_app = create_app(args.app_name,args.app_desc,bp['id'],client) + + if new_app and args.publish: #Validate cloud and publish application + if validate_cloud(new_app['id'],args.cloud_name,args.cloud_region,client): + publish_app(new_app,args.cloud_name,args.cloud_region,args.optimization,args.start,args.exp_time,client) + if new_app: + display_app(new_app['id'],client) + + else: + log.error("Blueprint {} not found".format(args.bp_name)) + print("Error: Blueprint {} not found".format(args.bp_name)) + exit(1) + + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-all b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-all new file mode 100755 index 00000000000..748476fbecf --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-all @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# A Ravello SDK example showing all applications in a user account in format: +# Application name, ID, Creation Time, Owner, If published, Cloud/Region +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +import datetime +import json +from argparse import ArgumentParser +from ravello_sdk import * +from common import * + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + return parser + +def print_apps(apps): + for app in apps: + creation_time = datetime.datetime.fromtimestamp(app['creationTime']/1000).strftime('%Y-%m-%d %H:%M') + if app['published']: + print('Application name: {0:<50} ID: {1:<10} Creation Date: {2:<20} Owner: {3:<25} Published: yes Cloud: {4:<10}'.format(app['name'].encode('utf-8'),app['id'],creation_time,app['ownerDetails']['name'],app['deployment']['cloudId'])) + else: + print('Application name: {0:<50} ID: {1:<10} Creation Date: {2:<20} Owner: {3:<25} Published: no'.format(app['name'].encode('utf-8'),app['id'],creation_time,app['ownerDetails']['name'],app['published'])) + + +def main(): + parser = mkparser() + args = parser.parse_args() + + #Set user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + #Get List of application + apps = client.get_applications() + + #Display application info + print_apps(apps) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-billing b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-billing new file mode 100755 index 00000000000..cf5149dbc3e --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-billing @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# A Ravello SDK example showing list of all applications and their cost in a specific month/year +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +import datetime +import json +import datetime +from argparse import ArgumentParser +from common import * + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-m", dest="month",default=None,type=int,choices = range(1,13), help='month of billing') + parser.add_argument("-y", dest="year",default=None,type=int,help='year of billing') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + return parser + +def set_billing_period(args): + + month = args.month + year = args.year + now = datetime.datetime.now() + + if not month: + month = now.month + + if not year: + year = now.year + + return month, year + +def print_billing_info(bi): + for app in bi[1:]: + price = 0 + for charge in app['charges']: + price += charge['summaryPrice'] + + print('Application name: {0:<50} Owner: {1:<25} Price: {2:8.2f}'.format(app['appName'].encode('utf-8'),app['owner'],price)) + +def main(): + parser = mkparser() + args = parser.parse_args() + + #Set user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + month,year = set_billing_period(args) + + #Get List of applications with billing info + bi = client.get_billing_for_month(year,month) + + + #Display billing info + print_billing_info(bi) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-data b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-data new file mode 100755 index 00000000000..86a2fc75e28 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-data @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# A Ravello SDK example for getting application data +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +import json +from argparse import ArgumentParser +from common import * + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-i", dest="id",default=0,type=int,help='application ID') + parser.add_argument("-a", dest="all",action="store_true", default=False,help='get extended application data') + parser.add_argument("-o", dest="out_file",default=None,help='output file') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + parser.add_argument("name",nargs='?',default=None,help='application name') + return parser + +def validate_param(args): + if args.id == 0 and not args.name: # Neither app ID nor app name are provided + print("Error: Invalid parameters, either application name or ID must be provided") + return False + return True + +def get_app_data(args,client): + app_id = args.id + app_name = args.name + appx = None + if app_id == 0: # If app ID is unknown look for the app name + for app in client.get_applications(): + if app['name'].lower() == app_name.decode('utf-8').lower(): + appx = app + break + else: + for app in client.get_applications(): + if app['id'] == app_id: + appx = app + break + return appx + +def get_app_data_ex(app_id,client): + app = None + if app_id != 0: + app = client.get_application(app_id, aspect="design") + + return app + +def print_app(app): + if(app): + print ("name: ",app['name']) + print ("id: ",app['id']) + print ("owner: ",app['owner']) + print ("publishOptimization: ",app['deployment']['publishOptimization']) + print ("cloud: ",app['deployment']['cloud']) + print ("regionName: ",app['deployment']['regionName']) + print ("totalActiveVms: ",app['deployment']['totalActiveVms']) + print ("totalStoppedVms: ",app['deployment']['totalStoppedVms']) + print ("totalErrorVms: ",app['deployment']['totalErrorVms']) + +def print_app_ex(app,out_file): + if app: + print (json.dumps(app, indent=5)) + if out_file: + with open(out_file,'w') as f: + f.write(json.dumps(app,indent=5)) +# json.dump(app,f) + +def main(): + parser = mkparser() + args = parser.parse_args() + + if not validate_param(args): + parser.print_help() + exit(1) + + + #Get user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + app = get_app_data(args,client) + + if args.all and app: # Get all application data + + appx = get_app_data_ex(app['id'],client) + print_app_ex(appx,args.out_file) + + else: # Print application summary + print_app(app) + + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-id b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-id new file mode 100755 index 00000000000..6ef1b722118 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-id @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# A Ravello SDK example for getting an application ID +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +from argparse import ArgumentParser +from common import * + +def usage(): + print("get-app-id.py ") + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-i", dest="id",default=0,type=int,help='application ID') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + parser.add_argument("app_name",default=None,help='application name') + return parser + +def connect(username, password): + client = RavelloClient() + try: + client.login(username, password) + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) + print('Error: Invalid user credentials, username {0}'.format(username)) + return None + return client + +def main(): + parser = mkparser() + args = parser.parse_args() + + #Get user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + app_id = get_app_id(args.app_name,client) + + if app_id: + print(app_id) + else: + print("Error: Application {} not found".format(args.app_name)) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) + diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-state b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-state new file mode 100755 index 00000000000..9137df744be --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-state @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# A Ravello SDK example for getting an application state +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +from argparse import ArgumentParser +from common import * + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-i", dest="id",default=0,type=int,help='application ID') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + parser.add_argument("name",nargs='?',default=None,help='application name') + return parser + +def validate_param(args): + if args.id == 0 and not args.name: # Neither app ID nor app name are provided + print("Error: Invalid parameters, either application name or ID must be provided") + return False + return True + +def initapp(args,client): + app_id = args.id + app_name = args.name + if app_id == 0: # If app ID is unknown find the app based on the app name + for app in client.get_applications(): + if app['name'].lower() == app_name.lower(): + app_id = app['id'] + break + + try: # Check is this is a valid app ID + app = client.get_application(app_id) + app_name = app['name'] + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) + print('Error: invalid application ID', app_id) + exit(1) + + return app + + +def main(): + parser = mkparser() + args = parser.parse_args() + + if not validate_param(args): + parser.print_help() + exit(1) + + + #Get user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + app = initapp(args,client) + + if(app): + print(application_state(app)) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-vms b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-vms new file mode 100755 index 00000000000..1de25950366 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-get-vms @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# A Ravello SDK example for getting application VM data +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +import json +from argparse import ArgumentParser +from common import * + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-i", dest="app_id",default=0,type=int,help='application ID') + parser.add_argument("-o", dest="out_file",default=None,help='output file') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + parser.add_argument("app_name",nargs='?',default=None,help='application name') + return parser + +def validate_param(args): + if args.app_id == 0 and not args.app_name: # Neither app ID nor app name are provided + print("Error: Invalid parameters, either application name or ID must be provided") + return False + return True + +def get_vms(app_id, client): + vms = client.get_vms(app_id,level='deployment') + return vms + +def print_vms(vms,out_file): + if vms: + for vm in vms: + print('Name: {0:<40} ID: {1:<20} State: {2}'.format(vm['name'].encode('utf-8'),vm['id'], vm['state'])) + +# print (json.dumps(vms, indent=5)) + + if out_file: + with open(out_file,'w') as f: + for vm in vms: + f.write(json.dumps(vms,indent=5)) + +def main(): + parser = mkparser() + args = parser.parse_args() + + if not validate_param(args): + parser.print_help() + exit(1) + + + #Get user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + app_id = args.app_id + + if app_id == 0: + app_id = get_app_id(args.app_name,client) + + if app_id: + vms = get_vms(app_id,client) + print_vms(vms,args.out_file) + + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-start b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-start new file mode 100755 index 00000000000..238dc506f46 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-start @@ -0,0 +1,127 @@ +#!/usr/bin/env python +# A Ravello SDK example for starting an application +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +from argparse import ArgumentParser +from common import * + +log = logging.getLogger('main') + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-i", dest="id",default=0,type=int,help='application ID') + parser.add_argument("-l", dest="log_file", default='ravello.log',help='logfile name') + parser.add_argument("-e", dest="exp_time",default=120,type=int,help='expiration time in minutes') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + parser.add_argument("name",nargs='?',default=None,help='application name') + return parser + +def validate_param(args): + if args.id == 0 and not args.name: # Neither app ID nor app name are provided + log.error("Invalid parameters, either application name or ID must be provided") + print("Error: Invalid parameters, either application name or ID must be provided") + return False + return True + +def initapp(args,client): + app_id = args.id + app_name = args.name + if app_id == 0: # If app ID is unknown find the app based on the app name + for app in client.get_applications(): + if app['name'].lower() == app_name.decode('utf-8').lower(): + app_id = app['id'] + break + + try: # Check is this is a valid app ID + app = client.get_application(app_id) + app_name = app['name'] + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) + print('Error: invalid application ID', app_id) + exit(1) + + return app + +def start(app,app_time,client): + + status = application_state(app) + + app_name = app['name'].encode('utf-8') + + if status == 'STARTED': + log.info('Application {0} is in already in {1} state, no action needed'.format(app_name,status)) + print('Application {0} is in already in {1} state, no action needed'.format(app_name,status)) + exp = {'expirationFromNowSeconds': 60*app_time} + client.set_application_expiration(app['id'], exp) + log.info('Setting expiration time of application {0} to {1} minutes'.format(app_name,app_time)) + print('Setting expiration time of application {0} to {1} minutes'.format(app_name,app_time)) + + elif 'STARTING' in status or 'STOPPING' in status: + log.info('Application {0} action in progress, not making any change'.format(app_name)) + print('Application {0} action in progress, not making any change'.format(app_name)) + + elif 'STOPPED' in status: + if app_time != 0: + exp = {'expirationFromNowSeconds': 60*app_time} + client.set_application_expiration(app['id'], exp) + log.info('Setting expiration time of application {0} to {1} minutes'.format(app_name,app_time)) + print('Setting expiration time of application {0} to {1} minutes'.format(app_name,app_time)) + client.start_application(app['id']) + log.info('Starting application {}'.format(app_name)) + print('Starting application {}'.format(app_name)) + else: + log.error('Application {0} is in unknown state {1}, canceling START command'.format(app_name,status)) + print('Application {0} is in unknown state {1}, canceling START command'.format(app_name,status)) + return False + + return True + +def main(): + parser = mkparser() + args = parser.parse_args() + + initlog(args.log_file) + + if not validate_param(args): + parser.print_help() + exit(1) + + #Get user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + app = initapp(args,client) + + app_time = args.exp_time + + rc = start(app,app_time,client) + + exit(rc) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-stop b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-stop new file mode 100755 index 00000000000..bcb5970ef70 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-stop @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# A Ravello SDK example for stopping an application +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +from argparse import ArgumentParser +from common import * + +log = logging.getLogger('main') + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-i", dest="id",default=0,type=int,help='application ID') + parser.add_argument("-l", dest="log_file", default='ravello.log',help='logfile name') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + parser.add_argument("name",nargs='?',default=None,help='application name') + return parser + +def validate_param(args): + if args.id == 0 and not args.name: # Neither app ID nor app name are provided + log.error("Invalid parameters, either application name or ID must be provided") + print("Error: Invalid parameters, either application name or ID must be provided") + return False + return True + +def initapp(args,client): + app_id = args.id + app_name = args.name + if app_id == 0: # If app ID is unknown find the app based on the app name + for app in client.get_applications(): + if app['name'].lower() == app_name.decode('utf-8').lower(): + app_id = app['id'] + break + + try: # Check is this is a valid app ID + app = client.get_application(app_id) + app_name = app['name'] + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) + print('Error: invalid application ID', app_id) + exit(1) + + return app + +def stop(app,client): + + status = application_state(app) + + app_name = app['name'].encode('utf-8') + + if status == 'STOPPED': + log.info('Application {0} is in already in {1} state, no action needed'.format(app_name,status)) + print('Application {0} is in already in {1} state, no action needed'.format(app_name,status)) + + elif 'STARTING' in status or 'STOPPING' in status: + log.info('Application {0} action in progress, not making any change'.format(app_name)) + print('Application {0} action in progress, not making any change'.format(app_name)) + + elif 'STARTED' in status: + client.stop_application(app['id']) + log.info('Stopping application {}'.format(app_name)) + print('Stopping application {}'.format(app_name)) + else: + log.error('Application {0} is in unknown state {1}, canceling START command'.format(app_name,status)) + print('Application {0} is in unknown state {1}, canceling START command'.format(app_name,status)) + return False + + return True + +def main(): + parser = mkparser() + args = parser.parse_args() + + initlog(args.log_file) + + if not validate_param(args): + parser.print_help() + exit(1) + + + #Get user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + app = initapp(args,client) + + rc = stop(app,client) + + exit(rc) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-update b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-update new file mode 100755 index 00000000000..07e2908312f --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/app-update @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# A Ravello SDK example for updating an application from a JSON file +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +import json +from argparse import ArgumentParser +from common import * + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-f", dest="inp_file",help='input file the application is created from') + parser.add_argument("-p", dest="publish_updates",default=False,action="store_true", help='publish updates') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + return parser + +def validate_param(args): + if not args.inp_file: # input file with the application json file must be provided + print("Error: input file must be provided") + return False + return True + +def print_app(app): + if(app): + print ("name: ",app['name']) + print ("id: ",app['id']) + print ("owner: ",app['owner']) + print ("publishOptimization: ",app['deployment']['publishOptimization']) + print ("cloud: ",app['deployment']['cloud']) + print ("regionName: ",app['deployment']['regionName']) + print ("totalActiveVms: ",app['deployment']['totalActiveVms']) +# print ("totalStoppedVms: ",app['deployment']['totalStoppedVms']) + print ("totalErrorVms: ",app['deployment']['totalErrorVms']) + +def print_app_ex(app,out_file): + if app: + print (json.dumps(app, indent=5)) + if out_file: + with open(out_file,'w') as f: + f.write(json.dumps(app,indent=5)) + +def main(): + parser = mkparser() + args = parser.parse_args() + + if not validate_param(args): + parser.print_help() + exit(1) + + #Get user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + + app = None + + if args.inp_file: + with open(args.inp_file,'r') as f: + app = json.load(f) + + if app: + new_app = client.update_application(app) + + if new_app and args.publish_updates: + client.publish_application_updates(new_app,False) + + if new_app: + print_app(new_app) + + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/bp-get-all b/ansible/configs/RHCLS-ScalableInfra-demo/examples/bp-get-all new file mode 100755 index 00000000000..16e1351d586 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/bp-get-all @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# A Ravello SDK example showing all applications in a user account in format: +# Application name, ID, Creation Time, Owner, If published, Cloud/Region +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +import datetime +import json +from argparse import ArgumentParser +from ravello_sdk import * +from common import * + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + return parser + +def print_apps(apps): + for app in apps: + creation_time = datetime.datetime.fromtimestamp(app['creationTime']/1000).strftime('%Y-%m-%d %H:%M') + if app['published']: + print('Application name: {0:<50} ID: {1:<10} Creation Date: {2:<20} Owner: {3:<25} Published: yes Cloud: {4:<10}'.format(app['name'].encode('utf-8'),app['id'],creation_time,app['ownerDetails']['name'],app['deployment']['cloudId'])) + else: + print('Application name: {0:<50} ID: {1:<10} Creation Date: {2:<20} Owner: {3:<25} Published: no'.format(app['name'].encode('utf-8'),app['id'],creation_time,app['ownerDetails']['name'],app['published'])) + + +def main(): + parser = mkparser() + args = parser.parse_args() + + #Set user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + #Get List of application + apps = client.get_blueprints() + + #Display application info + print_apps(apps) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/common.py b/ansible/configs/RHCLS-ScalableInfra-demo/examples/common.py new file mode 100755 index 00000000000..375d88255d0 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/common.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# A Ravello SDK example for creating and publishing applications from a blueprint +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import os +import base64 +import getpass +import logging +import logging.handlers +from ravello_sdk import * + +def get_credentials(): + with open(os.path.expanduser("~/.ravello_login"),"r") as pf: + username = pf.readline().strip() + encrypted_password = pf.readline().strip() + password = base64.b64decode(encrypted_password).decode() + return username,password + +def get_user_credentials(username): + + password = None + + if username: + password = getpass.getpass('Enter a Password: ') + else: + #read user credentials from .ravello_login file in user HOMEDIR + username,password = get_credentials() + + if not username or not password: + log.error('User credentials are not set') + print('Error: User credentials are not set') + return None,None + + return username,password + +def initlog(log_file): + logger = logging.getLogger() + logger.setLevel(logging.INFO) + logpath=os.path.join(os.getcwd(),log_file) + handler = logging.handlers.RotatingFileHandler(logpath, maxBytes=1048576, backupCount=10) + fmt = '%(asctime)s: %(filename)-20s %(levelname)-8s %(message)s' + handler.setFormatter(logging.Formatter(fmt)) + logger.addHandler(handler) + +def connect(username, password): + client = RavelloClient() + try: + client.login(username, password) + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) + log.error('Invalid user credentials, username {0}'.format(username)) + print('Error: Invalid user credentials, username {0}'.format(username)) + return None + return client + +def get_app_id(app_name,client): + app_id=0 + for app in client.get_applications(): + if app['name'].lower() == app_name.lower(): + app_id = app['id'] + break + return app_id + diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/common.pyc b/ansible/configs/RHCLS-ScalableInfra-demo/examples/common.pyc new file mode 100644 index 00000000000..9511819d6c1 Binary files /dev/null and b/ansible/configs/RHCLS-ScalableInfra-demo/examples/common.pyc differ diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/enforce_autostop.py b/ansible/configs/RHCLS-ScalableInfra-demo/examples/enforce_autostop.py new file mode 100644 index 00000000000..e9862a089e0 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/enforce_autostop.py @@ -0,0 +1,57 @@ +# A Ravello SDK example for enforcing a short auto-stop for all published applications +# in the account +# +# To use, edit the relevant variables (or extract them to command line param), +# and run enforce_autostop() +# +# Copyright 2011-2015 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +from ravello_sdk import * +import datetime + +MAX_ALLOWED_EXPIRATION_PERIOD_IN_SEC = 60*60*2 # 2 hours +USERNAME = 'wile.e.coyote@acme.com' +PASSWORD = 'PA$$W0RD' + +def enforce_autostop(): + client = RavelloClient() + client.login(USERNAME, PASSWORD) + + apps = client.get_applications() + for app in apps: + if app['published'] == False: + continue + deployment = app['deployment'] + if deployment['totalActiveVms'] == 0: + continue + if not app.has_key('nextStopTime'): + # no expiration set for this application, set it + set_expiration(client, app) + else: + expiration_time = datetime.datetime.utcfromtimestamp(app['nextStopTime'] / 1e3) + # if expiration_time (utc) is too long into the future, set_expiration correctly + if should_expire_app(expiration_time, app): + set_expiration(client, app) + +def should_expire_app(current_expiration_time_utc, app): + now = datetime.datetime.utcnow() + delta = current_expiration_time_utc - now + if delta.total_seconds() > MAX_ALLOWED_EXPIRATION_PERIOD_IN_SEC: + return True + return False + +def set_expiration(client, app): + print "setting expiration for ", app['name'] + client.set_application_expiration(app, {'expirationFromNowSeconds': MAX_ALLOWED_EXPIRATION_PERIOD_IN_SEC}) \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/etoken-create b/ansible/configs/RHCLS-ScalableInfra-demo/examples/etoken-create new file mode 100755 index 00000000000..9945138589d --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/etoken-create @@ -0,0 +1,163 @@ +#!/usr/bin/env python +# A Ravello SDK example for creating creating an ephemeral access token +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +import json +import time +from argparse import ArgumentParser +from common import * + +log = logging.getLogger('main') + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-i", dest="app_id",default=None,help='application id') + parser.add_argument("-n", dest="app_name",default=None,help='application name') + parser.add_argument("-d", dest="etoken_desc",default=None,help='ephemeral token description') + parser.add_argument("-r", dest="resource_type", default='APPLICATION',help='resource type: APPLICATION, LIBRARY_VM, etc ') + parser.add_argument("-p", dest="action_permissions", default=None,nargs='+',choices=['READ','CREATE','UPDATE','EXECUTE'],help='type action permissions separated by space') + parser.add_argument("-t", dest="etoken_exp_time",default=0,type=int,help='ephemeral token expiration time in minutes') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + parser.add_argument("-l", dest="log_file", default='ravello.log',help='logfile name') + parser.add_argument("etoken_name",nargs='?',default=None,help='ephemeral token name') + + return parser + +def validate_param(args): + if not args.app_name and not args.app_id: # Application name or ID must be provided + log.error("Invalid parameters, either application name or application ID must be provided") + print("Error: Invalid parameters, either blue application name or application ID must be provided") + return False + + if not args.etoken_name: + log.error("Invalid parameters, ephemeral token name must be provided") + print("Error: Invalid parameters, ephemeral token name must be provided") + return False + + return True + +def create_access_token(app_id,token_name,token_desc,resource_type,action_permissions,client): + if (not app_id or not token_name): + return None + + if not resource_type: + resource_type = 'APPLICATION' + + if not action_permissions: + if resource_type == 'APPLICATION' : + action_permissions = ['READ','EXECUTE'] + else: + return None + + token = { + "name" : token_name, + "description" : token_desc, + "permissions" : [ { + "actions" : action_permissions, + "resourceType" : resource_type, + "filterCriterion" : { + "type" : "COMPLEX", + "operator" : "And", + "criteria" : [ { + "type" : "SIMPLE", + "operator" : "Equals", + "propertyName" : "ID", + "operand" : app_id + }] + } + } ] + } + + log.info("Creating a new ephemeral access token {}".format(token_name)) + print("Creating a new ephemeral access token {}".format(token_name)) +# print (json.dumps(token,indent=5)) + access_token = client.create_ephemeral_access_token(token) + if access_token: + log.info("Ephemeral access token {} was created successfully".format(token_name)) + print("Ephemeral access token {} was created successfully".format(token_name)) + + return access_token + +def set_expiration_time(token_id,token_time,client): + token = client.get_ephemeral_access_token(token_id) + if token: + expiration_time = token['expirationTime'] + current_time = int(round(time.time() * 1000)) + expiration_time = current_time + token_time*60*1000 + token['expirationTime']=expiration_time + client.update_ephemeral_access_token(token_id, token) + updated_token = client.get_ephemeral_access_token(token_id) + log.info ("Ephemeral token {0} expiration time is set to {1}".format(token['name'],(updated_token['expirationTime']-current_time)/(60*60*1000))) + print ("Ephemeral token {0} expiration time is set to {1} hours".format(token['name'],(updated_token['expirationTime']-current_time)/(60*60*1000))) + + +def display_token(access_token): + if access_token: +# print(json.dumps(access_token,indent=5)) + token_id = access_token['token'] + app_id = access_token['permissions'][0]['filterCriterion']['criteria'][0]['operand'] + EndUserURL="https://access.ravellosystems.com/simple/#/"+token_id+"/apps/"+app_id + RavelloURL="https://access.ravellosystems.com/#/"+token_id+"/apps/"+app_id + print("End-user: {}".format(EndUserURL)) + print("Ravello UI: {}".format(RavelloURL)) + print("API Token: {}".format(token_id)) +def main(): + parser = mkparser() + args = parser.parse_args() + + if not validate_param(args): + parser.print_help() + exit(1) + + initlog(args.log_file) + + #Set user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + + app_id = args.app_id + + if not app_id: + #Get application ID + app_id = get_app_id(args.app_name,client) + + if app_id: + #Create ephemeral access token + access_token = create_access_token(app_id,args.etoken_name,args.etoken_desc,args.resource_type,args.action_permissions,client) + + + if access_token: + if args.etoken_exp_time != 0: #Update ephemeral token expiration time + set_expiration_time(access_token['id'],args.etoken_exp_time,client) + +# print(access_token) + display_token(access_token) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/ravello.log b/ansible/configs/RHCLS-ScalableInfra-demo/examples/ravello.log new file mode 100644 index 00000000000..9466c56df74 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/ravello.log @@ -0,0 +1,20 @@ +2016-08-17 11:56:35,811: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 11:56:37,021: app_create.py ERROR Blueprint None not found +2016-08-17 11:57:07,366: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 11:57:09,105: app_create.py ERROR Blueprint None not found +2016-08-17 11:57:38,859: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 11:57:40,633: app_create.py ERROR Blueprint OPTLC-OSP8_Director-v0.19-bp not found +2016-08-17 11:57:53,488: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 11:57:54,822: app_create.py ERROR Blueprint OPTLC-OSP8_Director-v0.19-bp not found +2016-08-17 11:59:12,400: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 11:59:13,907: app_create.py INFO Creating a new application test12345 +2016-08-17 12:01:21,254: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 13:01:15,539: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 13:01:16,722: app_create.py INFO Creating a new application test001 +2016-08-17 13:04:11,172: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 13:04:12,456: app-create INFO Creating a new application test002 +2016-08-17 13:04:38,288: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 13:04:44,532: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 13:04:45,863: app-create ERROR Blueprint None not found +2016-08-17 13:08:56,647: connectionpool.py INFO Starting new HTTPS connection (1): cloud.ravellosystems.com +2016-08-17 13:08:58,860: app-create INFO Creating a new application test003 diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/set-creds b/ansible/configs/RHCLS-ScalableInfra-demo/examples/set-creds new file mode 100755 index 00000000000..d8997df82d5 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/set-creds @@ -0,0 +1,36 @@ +#! /usr/bin/env python +# A Ravello SDK example for storing user credentials in a file +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import base64 +import os +import getpass +from sys import version_info + +py3 = version_info[0] > 2 +if py3: + username = input("Enter username: ") +else: + username = raw_input("Enter username: ") + +password = getpass.getpass('Enter a Password: ') + +encryped_password = base64.b64encode(password.encode('utf-8')) + +with open(os.path.expanduser("~/.ravello_login"),"wb") as f: + f.write(str(username+'\n').encode()) + f.write(encryped_password) + diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/startstop.py b/ansible/configs/RHCLS-ScalableInfra-demo/examples/startstop.py new file mode 100755 index 00000000000..140843c5ce9 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/startstop.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python3 +# +# startstop.py: example program that start and stops applications that do not +# need to run all the time. The program needs to be run from cron, and expects +# a configuration file in ~/.startstop/config.js. +# +# Copyright 2012-2014 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +from __future__ import absolute_import, print_function + +import os +import sys +import logging +import logging.handlers +import errno +import json +import textwrap + +from argparse import ArgumentParser +from datetime import datetime +from contextlib import closing +from ravello_sdk import * + +log = logging.getLogger('main') +example_cfg = textwrap.dedent("""\ + { + "expire": 1440, + "applications": [ + { + "id": 1234, + "name": "My Application", + "username": "user@example.com", + "password": "Passw0rd", + "active": [[0, 1440]] + } + ] + } +""") + +def homedir(): + """Return the user's home directory.""" + home = os.environ.get('HOME') + if home is None: + pw = pwd.getpwuid(os.getuid()) + home = pw.pw_dir + return home + +def appdir(): + """Return our application directory.""" + return os.path.join(homedir(), '.startstop') + +def appfile(name): + """Return the path to a file in the application directory.""" + return os.path.join(appdir(), name) + +def mkparser(): + """Create the command-line parser.""" + parser = ArgumentParser() + parser.add_argument('-d', '--debug', action='store_true') + parser.add_argument('-l', '--log-file', action='store_true') + parser.add_argument('-n', '--dry-run', action='store_true') + return parser + +def initapp(args): + """Initialize the application directory.""" + dirname = appdir() + try: + st = os.stat(dirname) + except OSError as e: + if e.errno != errno.ENOENT: + raise + os.mkdir(dirname) + print('Created: {}'.format(dirname)) + cfgname = appfile('config.js.example') + try: + st = os.stat(cfgname) + except OSError as e: + if e.errno != errno.ENOENT: + raise + with open(cfgname, 'w') as fout: + fout.write(example_cfg) + print('Created: {}'.format(cfgname)) + +def initlog(args): + """Initialize the logger.""" + logger = logging.getLogger() + logger.setLevel(logging.DEBUG if args.debug else logging.INFO) + if args.log_file or not sys.stdout.isatty(): + logname = os.path.join(appdir(), 'logfile.txt') + handler = logging.handlers.RotatingFileHandler(logname) + fmt = '%(asctime)s: %(levelname)s %(message)s' + handler.setFormatter(logging.Formatter(fmt)) + logger.addHandler(handler) + fmt = '%(levelname)s %(message)s' + handler = logging.StreamHandler(sys.stdout) + handler.setFormatter(logging.Formatter(fmt)) + logger.addHandler(handler) + +def readcfg(): + """Read our configuration file.""" + cfgname = appfile('config.js') + with open(cfgname) as fin: + cfg = json.load(fin) + return cfg + +def active(intervals, now): + """Return True if the minute of the week of *dt* is in *intervals*.""" + mow = now.weekday() * 24 * 60 + now.hour * 60 + now.minute + for start,end in intervals: + if start <= mow < end: + return True + return False + +def connect(username, password): + """Connect to the API, return a `RavelloClient` instance.""" + client = RavelloClient() + client.connect() + client.login(username, password) + return client + +def startstop(cfg, req, now, dry_run): + """Start or stop an application, if needed.""" + client = connect(req['username'], req['password']) + with closing(client): + app = client.get_application(req['id']) + if app is None: + log.error('no such application: {}'.format(app['id'])) + return False + status = application_state(app) + target = 'STARTED' if active(req['active'], now) else 'STOPPED' + log.info('need transition from {} => {}'.format(status, target)) + if not isinstance(status, list): + status = [status] + if status == [target]: + log.info('no action needed') + elif dry_run: + log.info('dry-run, not making any changes') + elif 'STARTING' in status or 'STOPPING' in status: + log.info('action in progress, not making any changes') + elif target == 'STARTED' and 'STOPPED' in status: + exp = {'expirationFromNowSeconds': 60*cfg['expire']} + client.set_application_expiration(app['id'], exp) + client.start_application(app['id']) + log.info('application started') + elif target == 'STOPPED' and 'STARTED' in status: + client.stop_application(app['id']) + log.info('application stopped') + else: + log.error('don\'t know how to get from {} to {}'.format(status, target)) + return False + return True + +def main(): + parser = mkparser() + args = parser.parse_args() + initapp(args) + initlog(args) + cfg = readcfg() + now = datetime.utcnow() + for req in cfg['applications']: + log.info('processing: {} (id = {})'.format(req['name'], req['id'])) + try: + success = startstop(cfg, req, now, args.dry_run) + except Exception as e: + if args.debug: + log.exception('uncaught exception') + else: + log.error(str(e)) + success = False + if success: + log.info('success: {}'.format(req['name'])) + else: + log.error('failure: {}'.format(req['name'])) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/test.py b/ansible/configs/RHCLS-ScalableInfra-demo/examples/test.py new file mode 100755 index 00000000000..91d5e7f5d4c --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/test.py @@ -0,0 +1,13 @@ +#!/usr/bin/python + +#will probably need these later +#import os +#import re +#import sys +#import json + +from ravello_sdk import RavelloClient +client = RavelloClient() +client.login('jlabocki@redhat.com', 'Redhat1234') +for app in client.get_applications(): + print('Found Application: {0}'.format(app['name'])) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/examples/vm-mgmt b/ansible/configs/RHCLS-ScalableInfra-demo/examples/vm-mgmt new file mode 100755 index 00000000000..158daffee81 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/examples/vm-mgmt @@ -0,0 +1,211 @@ +#!/usr/bin/env python +# A Ravello SDK example for management application VMs +# +# Copyright 2011-2016 Ravello Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import ravello_sdk +import sys +import os +import json +from argparse import ArgumentParser +from common import * + +log = logging.getLogger('main') + +def mkparser(): + parser = ArgumentParser() + parser.add_argument("-n", dest="app_id",default=0,type=int,help='application id') + parser.add_argument("-a", dest="app_name",default=None,help='application name') + parser.add_argument("-i", dest="vm_id",default=0,type=int,help='VM ID') + parser.add_argument("-v", dest="vm_name",default=None,help='VM name') + parser.add_argument("-u", dest="username",default=None,help='Ravello user account name') + parser.add_argument("-l", dest="log_file", default='ravello.log',help='logfile name') + parser.add_argument("command",default=None,choices=['start','stop','restart','poweroff','redeploy','repair','resetDisks'],help='command to execute') + return parser + +def validate_param(args): + if args.app_id == 0 and not args.app_name: # Neither app ID nor app name are provided + print("Error: Invalid parameters, either application name or ID must be provided") + return False + + if args.vm_id == 0 and not args.vm_name: # Neither VM ID nor VM name are provided + print("Error: Invalid parameters, either VM name or ID must be provided") + return False + + if not args.command: + print("Error: Invalid parameters, there is not command to execute") + return False + + return True + +def get_vm_id(app_id,vm_name,client): + vm_id = 0 + vms = client.get_vms(app_id) + for vm in vms: + vm = client.get_vm(app_id,vm['id'],'deployment') + if vm['name'].lower()==vm_name.decode('utf-8').lower(): + vm_id = vm['id'] + return vm_id + +def execute_command(app_id,vm_id,command,client): + if command == 'start': + rc = start_vm(app_id,vm_id,client) + elif command == 'stop': + rc = stop_vm(app_id,vm_id,client) + elif command == 'restart': + rc = restart_vm(app_id,vm_id,client) + elif command == 'poweroff': + rc = poweroff_vm(app_id,vm_id,client) + elif command == 'redeploy': + rc = redeploy_vm(app_id,vm_id,client) + elif command == 'repair': + rc = repair_vm(app_id,vm_id,client) + elif command == 'resetDisks': + rc = reset_disks_vm(app_id,vm_id,client) + else: + log.error("Error: Invalid command {}".format(command)) + print("Error: Invalid command {}".format(command)) + return True + +def start_vm(app_id,vm_id,client): + vm = client.get_vm(app_id,vm_id,'deployment') + vm_name = vm['name'].encode('utf-8') + vm_state = vm['state'] + if vm_state == 'STOPPED': + client.start_vm(app_id,vm_id) + log.info('Starting VM {}'.format(vm_name)) + print('Starting VM {}'.format(vm_name)) + return True + elif vm_state == 'STARTED' or vm_state == 'STARTING': + log.info('VM {0} is in {1} state, skipping START command'.format(vm_name,vm_state)) + print('VM {0} is in {1} state, skipping START command'.format(vm_name,vm_state)) + return True + else: + log.info('VM {0} is in {1} state, canceling START command'.format(vm_name,vm_state)) + print('VM {0} is in {1} state, canceling START command'.format(vm_name,vm_state)) + return False + +def stop_vm(app_id,vm_id,client): + vm = client.get_vm(app_id,vm_id,'deployment') + vm_name = vm['name'].encode('utf-8') + vm_state = vm['state'] + if vm_state == 'STARTED': + client.stop_vm(app_id,vm_id) + log.info('Stopping VM {}'.format(vm_name)) + print('Stopping VM {}'.format(vm_name)) + return True + elif vm_state == 'STOPPED' or vm_state == 'STOPPING': + log.info('VM {0} is in {1} state, skipping STOP command'.format(vm_name,vm_state)) + print('VM {0} is in {1} state, skipping STOP command'.format(vm_name,vm_state)) + return True + else: + log.info('VM {0} is in {1} state, canceling STOP command'.format(vm_name,vm_state)) + print('VM {0} is in {1} state, canceling STOP command'.format(vm_name,vm_state)) + return False + +def restart_vm(app_id,vm_id,client): + vm = client.get_vm(app_id,vm_id,'deployment') + vm_name = vm['name'].encode('utf-8') + vm_state = vm['state'] + if vm_state == 'STARTED' or vm_state == 'STOPPED': + client.restart_vm(app_id,vm_id) + log.info('Restarting VM {}'.format(vm_name)) + print('Restarting VM {}'.format(vm_name)) + return True + else: + log.info('VM {0} is in {1} state, canceling RESTART command'.format(vm_name,vm_state)) + print('VM {0} is in {1} state, canceling RESTART command'.format(vm_name,vm_state)) + return False + +def poweroff_vm(app_id,vm_id,client): + vm = client.get_vm(app_id,vm_id,'deployment') + vm_name = vm['name'].encode('utf-8') + vm_state = vm['state'] + client.poweroff_vm(app_id,vm_id) + log.info('Powering off VM {}'.format(vm_name)) + print('Powering off VM {}'.format(vm_name)) + return True + +def redeploy_vm(app_id,vm_id,client): + vm = client.get_vm(app_id,vm_id,'deployment') + vm_name = vm['name'].encode('utf-8') + vm_state = vm['state'] + client.redeploy_vm(app_id,vm_id) + log.info('Redeploying VM {}'.format(vm_name)) + print('Redeploying VM {}'.format(vm_name)) + return True + +def repair_vm(app_id,vm_id,client): + vm = client.get_vm(app_id,vm_id,'deployment') + vm_name = vm['name'].encode('utf-8') + vm_state = vm['state'] + client.repair_vm(app_id,vm_id) + log.info('Trying to repair VM {}'.format(vm_name)) + print('Trying to repair VM {}'.format(vm_name)) + return True + +def reset_disks_vm(app_id,vm_id,client): + vm = client.get_vm(app_id,vm_id,'deployment') + vm_name = vm['name'].encode('utf-8') + vm_state = vm['state'] + client.reset_disks_vm(app_id,vm_id) + log.info('Resetting disks to the last state of VM {}'.format(vm_name)) + print('Resetting disks to the last state of VM {}'.format(vm_name)) + return True + +def main(): + parser = mkparser() + args = parser.parse_args() + + initlog(args.log_file) + + if not validate_param(args): + parser.print_help() + exit(1) + + + #Get user credentials + username, password = get_user_credentials(args.username) + if not username or not password: + exit(1) + + #Connect to Ravello + client = connect(username, password) + if not client: + exit (1) + + app_id = args.app_id + if app_id == 0: + app_id = get_app_id(args.app_name,client) + if app_id == 0: + print("Error: Invalid application {}".format(args.app_name)) + exit(1) + + vm_id = args.vm_id + if vm_id == 0: + vm_id = get_vm_id(app_id, args.vm_name, client) + if vm_id == 0: + print("Error: Invalid VM name {}".format(args.vm_name)) + exit(1) + + rc = execute_command(app_id,vm_id,args.command,client) + + exit(rc) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('Error: {!s}\n'.format(e)) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/exports b/ansible/configs/RHCLS-ScalableInfra-demo/exports new file mode 100644 index 00000000000..8abeaf6be43 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/exports @@ -0,0 +1,3 @@ +/exports/cinder/tokyo *(rw,fsid=0,no_subtree_check,sync,no_root_squash) +/exports/cinder/paris *(rw,fsid=0,no_subtree_check,sync,no_root_squash) +/exports/cinder/newyork *(rw,fsid=0,no_subtree_check,sync,no_root_squash) diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/bastion-play.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/bastion-play.yml new file mode 100644 index 00000000000..79efa10eead --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/bastion-play.yml @@ -0,0 +1,15 @@ +--- + # FQDN of your host +- hosts: 0workstation-ansiblebrettdemove-ziaojdbx.srv.ravcloud.com + # Remember to set this to true for production runs. + gather_facts: true + vars_files: + - variables.yml + # SSH username used to connect to remote host + remote_user: root + # become: true + # become_method: sudo + # become_user: root + roles: + - bastion +... diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/bastion-play.yml.orig b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/bastion-play.yml.orig new file mode 100644 index 00000000000..014f49f0ad2 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/bastion-play.yml.orig @@ -0,0 +1,13 @@ +--- + # FQDN of your host +- hosts: "{{ bastion_host }}" + # Remember to set this to true for production runs. + gather_facts: false + # SSH username used to connect to remote host + remote_user: "{{ remote_ssh_user }}" + become: true + become_method: sudo + become_user: root + roles: + - bastion +... diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/inventory b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/inventory new file mode 100644 index 00000000000..ad3b0f10668 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/inventory @@ -0,0 +1 @@ +0workstation-ansiblebrettdemove-ziaojdbx.srv.ravcloud.com diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/.travis.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/.travis.yml new file mode 100644 index 00000000000..36bbf6208cf --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/.travis.yml @@ -0,0 +1,29 @@ +--- +language: python +python: "2.7" + +# Use the new container infrastructure +sudo: false + +# Install ansible +addons: + apt: + packages: + - python-pip + +install: + # Install ansible + - pip install ansible + + # Check ansible version + - ansible --version + + # Create ansible.cfg with correct roles_path + - printf '[defaults]\nroles_path=../' >ansible.cfg + +script: + # Basic role syntax check + - ansible-playbook tests/test.yml -i tests/inventory --syntax-check + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/README.md b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/README.md new file mode 100644 index 00000000000..628ae0547af --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/README.md @@ -0,0 +1,40 @@ +Role for configuring Bastion hosts +========= +This role is used to configure bastion hosts for the cloud suite environments. +More details will follow as needed. + +Requirements +------------ +Any pre-requisites that may not be covered by Ansible itself or the role, should/will be mentioned here. + +Role Variables +-------------- +This section contains a list of variables used by the role and their defult values. +Those which should/can be changed will be marked as such followed by a short explanation. +All these variables can be overriden anywhere, since they have the lowest priority. + +- **setup_bastion** - Type: bool. Should be set to yes (it is needed for package setup/install) +- **bastion_packages** - Type: list. Contains the list of packages yum should install on the Bastion host +- **exports_url** - Type: string, Contains the path to the 'exports' file for NFS on Bastion +- **rhel_repositories** - Type: hash, Contains the required key-value pairs for the yum_repository module. +- **internal_network** - Type: string. The IP address range in CIDR notation (eg. 192.168.1.1/24) +- **enabled_repositories** - Type: string. The comma-separated list of repositories to enable on the remote system. + + +Dependencies +------------ +Depends on the following roles: + - packages + +Example Playbook +---------------- +An example of how to use the role (for instance, with variables passed in as parameters): +```yaml + - hosts: group or hostname from inventory + roles: + - { role: bastion, exports_url: some_new_url } +``` + +A simple way calling of the role is included in the *bastion.yml* file in the tests directory. + + diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/defaults/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/defaults/main.yml new file mode 100644 index 00000000000..6745ec3372f --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/defaults/main.yml @@ -0,0 +1,33 @@ +--- +# defaults file for bastion host + +internal_network: 192.168.122.0/24 +rhel_repositories: + - { name: 'rhel-x86_64-server-7', baseurl: '{{ repo_base_url }}/rhel-7-server-rpms', description: 'Red Hat Enterprise Linux 7' } + - { name: 'rhel-x86_64-server-rh-common-7', baseurl: '{{ repo_base_url }}/rhel-7-server-rh-common-rpms', description: 'Red Hat Enterprise Linux 7 Common' } + - { name: 'rhel-x86_64-server-extras-7', baseurl: "{{ repo_base_url }}/rhel-7-server-extras-rpms", description: 'Red Hat Enterprise Linux 7 Extras' } + - { name: 'rhel-x86_64-server-optional-7', baseurl: "{{ repo_base_url }}/rhel-7-server-optional-rpms", description: 'Red Hat Enterprise Linux 7 Optional' } + +exports_url: https://raw.githubusercontent.com/RedHatDemos/RHCLS_ScalableInfrastructure/master/exports + +enabled_services: + - ntpd + - iptables + - nfs + +disabled_services: + - avahi-daemon + - chronyd + - firewalld + - cups + - libvirtd + - ModemManager + - oddjobd + - postfix + - wpa_supplicant + +nfs_exports: + - /exports/cinder/paris + - /exports/cinder/tokyo + - /exports/cinder/newyork + diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/handlers/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/handlers/main.yml new file mode 100644 index 00000000000..c916050d391 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/handlers/main.yml @@ -0,0 +1,9 @@ +--- +# handlers file for bastion +- name: Export NFS + command: exportfs -ra + +- name: restart iptables + service: + name: iptables + state: restarted diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/meta/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/meta/main.yml new file mode 100644 index 00000000000..498489b3e79 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/meta/main.yml @@ -0,0 +1,50 @@ +galaxy_info: + author: Systems Engineering + description: Setting up a Bation host + company: Red Hat + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + + min_ansible_version: 1.2 + + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If travis integration is cofigured, only notification for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + #github_branch: + + # + # Below are all platforms currently available. Just uncomment + # the ones that apply to your role. If you don't see your + # platform on this list, let us know and we'll get it added! + # + #platforms: + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. + +dependencies: + - packages + + # List your role dependencies here, one per line. + # Be sure to remove the '[]' above if you add dependencies + # to this list. diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tasks/iptables.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tasks/iptables.yml new file mode 100644 index 00000000000..7e281e4e3e2 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tasks/iptables.yml @@ -0,0 +1,9 @@ +# the iptables module (E) is broken as far as negation (!) goes. +# Since we need a set of chains it is recommended to use a template file. (based on Ansible docs) +# This uses iptables, not firewall-cmd (firewalld) + +- name: Copy the iptables template file + template: + src: iptables.j2 + dest: /etc/sysconfig/iptables + notify: restart iptables diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tasks/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tasks/main.yml new file mode 100644 index 00000000000..0fa0faa1f53 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tasks/main.yml @@ -0,0 +1,26 @@ +--- +# tasks file for bastion + +- name: Include firewall (iptables) rules + static: yes + include: iptables.yml + +- name: Include package management and installation task + static: yes + include: services.yml + +- name: Create directories for NFS export + file: + path: "{{ item }}" + state: directory + mode: 0755 + with_items: "{{ nfs_exports }}" + +- name: Configure /etc/exports + get_url: + url: "{{ exports_url }}" + dest: /etc/exports + mode: 0644 + force: yes + notify: Export NFS +... diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tasks/services.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tasks/services.yml new file mode 100644 index 00000000000..e19d4650458 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tasks/services.yml @@ -0,0 +1,19 @@ +# Enabling systemD services on the Bastion host. + +- name: Enabling custom services + systemd: + state: started + enabled: yes + name: "{{ item }}" + with_items: "{{ enabled_services | default([])}}" + when: enabled_services is defined + +# Stopping the services which are not needed on a Bastion host. Maybe those could be masked as well, for good measure. + +- name: Stopping and disabling systemD services which are not needed + ignore_errors: yes + systemd: + state: stopped + enabled: no + name: "{{ item }}" + with_items: "{{ disabled_services }}" diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/templates/iptables.j2 b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/templates/iptables.j2 new file mode 100644 index 00000000000..111a99bb203 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/templates/iptables.j2 @@ -0,0 +1,43 @@ +# Do not edit this file manually +# {{ ansible_managed }} + +*mangle +:PREROUTING ACCEPT [0:0] +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +-A POSTROUTING -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill +COMMIT + +# NAT setup + +*nat +:PREROUTING ACCEPT [0:0] +:INPUT ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +-A POSTROUTING -s {{ internal_network }} -d 224.0.0.0/24 -j RETURN +-A POSTROUTING -s {{ internal_network }} -d 255.255.255.255/32 -j RETURN +-A POSTROUTING -s {{ internal_network }} ! -d {{ internal_network }} -p tcp -j MASQUERADE --to-ports 1024-65535 +-A POSTROUTING -s {{ internal_network }} ! -d {{ internal_network }} -p udp -j MASQUERADE --to-ports 1024-65535 +-A POSTROUTING -s {{ internal_network }} ! -d {{ internal_network }} -j MASQUERADE +COMMIT + +# Firewall setup (filter) + +*filter +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT +-A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT +-A INPUT -i virbr0 -p udp -m udp --dport 67 -j ACCEPT +-A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT +-A FORWARD -d {{ internal_network }} -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +-A FORWARD -s {{ internal_network }} -i virbr0 -j ACCEPT +-A FORWARD -i virbr0 -o virbr0 -j ACCEPT +-A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable +-A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable +-A OUTPUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT +COMMIT diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tests/bastion-play.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tests/bastion-play.yml new file mode 100644 index 00000000000..014f49f0ad2 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tests/bastion-play.yml @@ -0,0 +1,13 @@ +--- + # FQDN of your host +- hosts: "{{ bastion_host }}" + # Remember to set this to true for production runs. + gather_facts: false + # SSH username used to connect to remote host + remote_user: "{{ remote_ssh_user }}" + become: true + become_method: sudo + become_user: root + roles: + - bastion +... diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tests/inventory b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tests/inventory new file mode 100644 index 00000000000..d18580b3c36 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tests/inventory @@ -0,0 +1 @@ +localhost \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tests/test.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tests/test.yml new file mode 100644 index 00000000000..15984804934 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - bastion \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/vars/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/vars/main.yml new file mode 100644 index 00000000000..47ba2b33bd7 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/bastion/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for bastion diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/.travis.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/.travis.yml new file mode 100644 index 00000000000..36bbf6208cf --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/.travis.yml @@ -0,0 +1,29 @@ +--- +language: python +python: "2.7" + +# Use the new container infrastructure +sudo: false + +# Install ansible +addons: + apt: + packages: + - python-pip + +install: + # Install ansible + - pip install ansible + + # Check ansible version + - ansible --version + + # Create ansible.cfg with correct roles_path + - printf '[defaults]\nroles_path=../' >ansible.cfg + +script: + # Basic role syntax check + - ansible-playbook tests/test.yml -i tests/inventory --syntax-check + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/README.md b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/README.md new file mode 100644 index 00000000000..00fadf51cc6 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +This role sets the OSP all-in-one deployment. + +Requirements +------------ + +Requires a RHEL OS installed on the host. + +Role Variables +-------------- + +Some sane defaults have already been set. +The variables used in this role are: + +- **glance_images:** - Type: list. Format: `{name: '', src: '', dst: '', flavor: ''}` +- **glance_img_destination:** - Type: string. Path to directory which will hold the glance images to be imported. + +Dependencies +------------ + +TBD + +Example Playbook +---------------- + +TODO + +License +------- + +BSD + +Author Information +------------------ + +Nenad Peric, Systems Engineering, Red Hat inc. diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/defaults/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/defaults/main.yml new file mode 100644 index 00000000000..5fe05f47fc9 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/defaults/main.yml @@ -0,0 +1,9 @@ +--- +# defaults file for ospd + +glance_img_destination: /root/cloud_images + +glance_images: + - { name:'Windows', src: '', dst: '', flavor: 'm1.medium' } + - { name:'Ubuntu', src: '', dst: '', flavor: 'm1.small' } + - { name:'RHEL', src: '',dst: '', flavor: 'm1.small' } diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/handlers/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/handlers/main.yml new file mode 100644 index 00000000000..93a5ec4e16a --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for ospd diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/meta/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/meta/main.yml new file mode 100644 index 00000000000..2e1a91444db --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/meta/main.yml @@ -0,0 +1,222 @@ +galaxy_info: + author: your name + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + + min_ansible_version: 1.2 + + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If travis integration is cofigured, only notification for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + #github_branch: + + # + # Below are all platforms currently available. Just uncomment + # the ones that apply to your role. If you don't see your + # platform on this list, let us know and we'll get it added! + # + #platforms: + #- name: OpenBSD + # versions: + # - all + # - 5.6 + # - 5.7 + # - 5.8 + # - 5.9 + # - 6.0 + #- name: Fedora + # versions: + # - all + # - 16 + # - 17 + # - 18 + # - 19 + # - 20 + # - 21 + # - 22 + # - 23 + # - 24 + # - 25 + #- name: DellOS + # versions: + # - all + # - 10 + # - 6 + # - 9 + #- name: MacOSX + # versions: + # - all + # - 10.10 + # - 10.11 + # - 10.12 + # - 10.7 + # - 10.8 + # - 10.9 + #- name: Synology + # versions: + # - all + # - any + #- name: Junos + # versions: + # - all + # - any + #- name: GenericBSD + # versions: + # - all + # - any + #- name: Void Linux + # versions: + # - all + # - any + #- name: GenericLinux + # versions: + # - all + # - any + #- name: NXOS + # versions: + # - all + # - any + #- name: IOS + # versions: + # - all + # - any + #- name: Amazon + # versions: + # - all + # - 2013.03 + # - 2013.09 + # - 2016.03 + # - 2016.09 + #- name: ArchLinux + # versions: + # - all + # - any + #- name: FreeBSD + # versions: + # - all + # - 10.0 + # - 10.1 + # - 10.2 + # - 10.3 + # - 11.0 + # - 8.0 + # - 8.1 + # - 8.2 + # - 8.3 + # - 8.4 + # - 9.0 + # - 9.1 + # - 9.1 + # - 9.2 + # - 9.3 + #- name: Ubuntu + # versions: + # - all + # - lucid + # - maverick + # - natty + # - oneiric + # - precise + # - quantal + # - raring + # - saucy + # - trusty + # - utopic + # - vivid + # - wily + # - xenial + # - yakkety + #- name: Debian + # versions: + # - all + # - etch + # - jessie + # - lenny + # - sid + # - squeeze + # - stretch + # - wheezy + #- name: Alpine + # versions: + # - all + # - any + #- name: EL + # versions: + # - all + # - 5 + # - 6 + # - 7 + #- name: Windows + # versions: + # - all + # - 2012R2 + #- name: SmartOS + # versions: + # - all + # - any + #- name: opensuse + # versions: + # - all + # - 12.1 + # - 12.2 + # - 12.3 + # - 13.1 + # - 13.2 + #- name: SLES + # versions: + # - all + # - 10SP3 + # - 10SP4 + # - 11 + # - 11SP1 + # - 11SP2 + # - 11SP3 + # - 11SP4 + # - 12 + # - 12SP1 + #- name: GenericUNIX + # versions: + # - all + # - any + #- name: Solaris + # versions: + # - all + # - 10 + # - 11.0 + # - 11.1 + # - 11.2 + # - 11.3 + #- name: eos + # versions: + # - all + # - Any + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. + # Be sure to remove the '[]' above if you add dependencies + # to this list. \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/tasks/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/tasks/main.yml new file mode 100644 index 00000000000..8ee4f1b3276 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/tasks/main.yml @@ -0,0 +1,33 @@ +--- +# tasks file for ospd +# If the bastion host is going to be used to configure OSP, then many of the tasks have to be +# either delegated to bastion, or an additional playbook should be started from bastion host +# itself, which would delegate certain tasks to the OSP host. +# +- name: Capture answers file for all-in-one OSP install + get_url: + src: "{{ answers_file_url }}" + dest: "{{ answers_file }}" + +- name: Install OSP using answers file + local_action: command /usr/bin/packstack --answer-file={{answers_file}} + +- name: Capture glance images + get_url: + src: "{{ item.src }}" + dst: "{{ glance_image_location }}/{{ item.dst }}" + with_items: "{{ glance_images }}" + +- name: Source keystone credentials and import images + local_action: command source ./keystonerc_admin + +# Image-upload does not take argument --name it seems. (based on docs) + +- name: Import images into glance + local_action: command /usr/bin/glance image-upload --file {{ glance_image_location }}/{{ item.dst }} + with_items: "{{ glance_images }}" + +- name: Create instances from glance images + local_action: command nova boot --image {{ item.name }} --flavor {{ item.flavor }} {{ item.name }} + with_items: "{{ glance_images }}" + diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/tests/inventory b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/tests/inventory new file mode 100644 index 00000000000..d18580b3c36 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/tests/inventory @@ -0,0 +1 @@ +localhost \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/tests/test.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/tests/test.yml new file mode 100644 index 00000000000..ab5dff5c239 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - ospd \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/vars/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/vars/main.yml new file mode 100644 index 00000000000..e60ebea7eb9 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/osp/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for ospd diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/.travis.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/.travis.yml new file mode 100644 index 00000000000..36bbf6208cf --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/.travis.yml @@ -0,0 +1,29 @@ +--- +language: python +python: "2.7" + +# Use the new container infrastructure +sudo: false + +# Install ansible +addons: + apt: + packages: + - python-pip + +install: + # Install ansible + - pip install ansible + + # Check ansible version + - ansible --version + + # Create ansible.cfg with correct roles_path + - printf '[defaults]\nroles_path=../' >ansible.cfg + +script: + # Basic role syntax check + - ansible-playbook tests/test.yml -i tests/inventory --syntax-check + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/README.md b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/README.md new file mode 100644 index 00000000000..225dd44b9fc --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/defaults/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/defaults/main.yml new file mode 100644 index 00000000000..d38ef13738f --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/defaults/main.yml @@ -0,0 +1,22 @@ +--- +# defaults file for packages + +bastion_enabled_repos: 'rhel-x86_64-server-7,rhel-x86_64-server-extras-7,rhel-x86_64-server-optional-7,rhel-x86_64-server-rh-common-7' +osp_enabled_repos: 'rhel-x86_64-server-7,rhel-x86_64-server-extras-7,rhel-x86_64-server-rh-common-7,rhel-x86_64-server-openstack-8' + +# Bastion packages + +bastion_packages: + - nfs-utils + - vim + - iptables-services + - ntp + +# OSPd packages + +osp_packages: + - openstack-packstack + - python-redis + - kernel + - mongodb + - wget diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/handlers/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/handlers/main.yml new file mode 100644 index 00000000000..eb512010ea0 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for packages diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/meta/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/meta/main.yml new file mode 100644 index 00000000000..2e1a91444db --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/meta/main.yml @@ -0,0 +1,222 @@ +galaxy_info: + author: your name + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + + min_ansible_version: 1.2 + + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If travis integration is cofigured, only notification for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + #github_branch: + + # + # Below are all platforms currently available. Just uncomment + # the ones that apply to your role. If you don't see your + # platform on this list, let us know and we'll get it added! + # + #platforms: + #- name: OpenBSD + # versions: + # - all + # - 5.6 + # - 5.7 + # - 5.8 + # - 5.9 + # - 6.0 + #- name: Fedora + # versions: + # - all + # - 16 + # - 17 + # - 18 + # - 19 + # - 20 + # - 21 + # - 22 + # - 23 + # - 24 + # - 25 + #- name: DellOS + # versions: + # - all + # - 10 + # - 6 + # - 9 + #- name: MacOSX + # versions: + # - all + # - 10.10 + # - 10.11 + # - 10.12 + # - 10.7 + # - 10.8 + # - 10.9 + #- name: Synology + # versions: + # - all + # - any + #- name: Junos + # versions: + # - all + # - any + #- name: GenericBSD + # versions: + # - all + # - any + #- name: Void Linux + # versions: + # - all + # - any + #- name: GenericLinux + # versions: + # - all + # - any + #- name: NXOS + # versions: + # - all + # - any + #- name: IOS + # versions: + # - all + # - any + #- name: Amazon + # versions: + # - all + # - 2013.03 + # - 2013.09 + # - 2016.03 + # - 2016.09 + #- name: ArchLinux + # versions: + # - all + # - any + #- name: FreeBSD + # versions: + # - all + # - 10.0 + # - 10.1 + # - 10.2 + # - 10.3 + # - 11.0 + # - 8.0 + # - 8.1 + # - 8.2 + # - 8.3 + # - 8.4 + # - 9.0 + # - 9.1 + # - 9.1 + # - 9.2 + # - 9.3 + #- name: Ubuntu + # versions: + # - all + # - lucid + # - maverick + # - natty + # - oneiric + # - precise + # - quantal + # - raring + # - saucy + # - trusty + # - utopic + # - vivid + # - wily + # - xenial + # - yakkety + #- name: Debian + # versions: + # - all + # - etch + # - jessie + # - lenny + # - sid + # - squeeze + # - stretch + # - wheezy + #- name: Alpine + # versions: + # - all + # - any + #- name: EL + # versions: + # - all + # - 5 + # - 6 + # - 7 + #- name: Windows + # versions: + # - all + # - 2012R2 + #- name: SmartOS + # versions: + # - all + # - any + #- name: opensuse + # versions: + # - all + # - 12.1 + # - 12.2 + # - 12.3 + # - 13.1 + # - 13.2 + #- name: SLES + # versions: + # - all + # - 10SP3 + # - 10SP4 + # - 11 + # - 11SP1 + # - 11SP2 + # - 11SP3 + # - 11SP4 + # - 12 + # - 12SP1 + #- name: GenericUNIX + # versions: + # - all + # - any + #- name: Solaris + # versions: + # - all + # - 10 + # - 11.0 + # - 11.1 + # - 11.2 + # - 11.3 + #- name: eos + # versions: + # - all + # - Any + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. + # Be sure to remove the '[]' above if you add dependencies + # to this list. \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tasks/bastion.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tasks/bastion.yml new file mode 100644 index 00000000000..7c58bfc2f63 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tasks/bastion.yml @@ -0,0 +1,20 @@ +- name: Bastion repository configuration + yum_repository: + name: "{{ item.name }}" + baseurl: "{{ item.baseurl }}" + description: "{{ item.description }}" + gpgcheck: no + file: rhel + with_items: "{{ rhel_repositories }}" + +- name: Bastion - Enable the required repositories only + yum: + name: "*" + disablerepo: "*" + enablerepo: "{{ bastion_enabled_repos }}" + +- name: Bastion - Install required packages + yum: + name: "{{ item }}" + state: latest + with_items: "{{ bastion_packages }}" diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tasks/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tasks/main.yml new file mode 100644 index 00000000000..1390bc4a891 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tasks/main.yml @@ -0,0 +1,13 @@ +- name: Disable the default subscription-manager repositories + command: subscription-manager config --rhsm.manage_repos=0 + +# All the variables have a default set. Those, however can be overriden any time (defaults have the lowest var priority). + +- debug: + msg: "setup OSP is set to {{ setup_osp }}" + +- include: osp.yml + when: setup_osp|bool + +- include: bastion.yml + when: setup_bastion diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tasks/osp.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tasks/osp.yml new file mode 100644 index 00000000000..e001f00df78 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tasks/osp.yml @@ -0,0 +1,25 @@ +- name: OSP repository configuration + yum_repository: + name: "{{ item.name }}" + baseurl: "{{ item.baseurl }}" + description: "{{ item.description }}" + gpgcheck: no + file: ospd + with_items: "{{ osp_repositories }}" + +- name: OSP - Enable the required repositories only + yum: + name: "*" + disablerepo: "*" + enablerepo: "{{ osp_enabled_repos }}" + +- name: OSP - Install required packages + yum: + name: "{{ item }}" + state: latest + with_items: "{{ osp_packages }}" + +- name: OSP - Remove Network Manager + yum: + name: NetworkManager + state: absent diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tests/inventory b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tests/inventory new file mode 100644 index 00000000000..d18580b3c36 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tests/inventory @@ -0,0 +1 @@ +localhost \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tests/test.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tests/test.yml new file mode 100644 index 00000000000..5630787033b --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - packages \ No newline at end of file diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/vars/main.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/vars/main.yml new file mode 100644 index 00000000000..3a6cec56ee3 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/roles/packages/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for packages diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/variables.yml b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/variables.yml new file mode 100644 index 00000000000..050c156f22c --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/playbooks/variables.yml @@ -0,0 +1,7 @@ +repo_base_url: http://www.opentlc.com/repos +bastion_host: 0workstation-ansiblebthurberans-9vpccpu4.srv.ravcloud.com +remote_ssh_user: root +setup_bastion: true +setup_osp: false +# This below is just a workaround, it has to be configured someplace, but since OSP is in the works, this will do. +osp_repositories: none diff --git a/ansible/configs/RHCLS-ScalableInfra-demo/redhat.repo b/ansible/configs/RHCLS-ScalableInfra-demo/redhat.repo new file mode 100644 index 00000000000..9ffff5146c8 --- /dev/null +++ b/ansible/configs/RHCLS-ScalableInfra-demo/redhat.repo @@ -0,0 +1,842 @@ +# +# Certificate-Based Repositories +# Managed by (rhsm) subscription-manager +# +# *** This file is auto-generated. Changes made here will be over-written. *** +# *** Use "subscription-manager repo-override --help" if you wish to make changes. *** +# +# If this file is empty and this system is subscribed consider +# a "yum repolist" to refresh available repos +# + +[rhel-7-server-optional-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/optional/debug +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Optional (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rhn-tools-beta-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/rhn-tools/debug +ui_repoid_vars = basearch +sslverify = 1 +name = RHN Tools for Red Hat Enterprise Linux 7 Server Beta (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-v2vwin-1-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/v2vwin/debug +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Virt V2V Tool for RHEL 7 (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rhn-tools-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/rhn-tools/debug +ui_repoid_vars = releasever basearch +sslverify = 1 +name = RHN Tools for Red Hat Enterprise Linux 7 Server (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-server-rhscl-7-beta-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/rhscl/1/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Software Collections Beta RPMs for Red Hat Enterprise Linux 7 Server +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-beta-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server Beta (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rh-common-beta-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/rh-common/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - RH Common Beta (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-openstack-7.0-tools-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/openstack-tools/7.0/os +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat OpenStack Tools 7.0 for Red Hat Enterprise Linux 7 Server (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-v2vwin-1-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/v2vwin/os +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Virt V2V Tool for RHEL 7 (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/os +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 1 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-extras-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/7Server/$basearch/extras/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Extras (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-optional-beta-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/optional/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Optional Beta (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-supplementary-beta-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/supplementary/debug +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Supplementary Beta (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rh-gluster-3-client-for-rhel-7-server-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/rhs-client/source/SRPMS +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Storage Native Client for RHEL 7 (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rhn-tools-beta-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/rhn-tools/os +ui_repoid_vars = basearch +sslverify = 1 +name = RHN Tools for Red Hat Enterprise Linux 7 Server Beta (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rhceph-1.3-tools-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/ceph-tools/1.3/debug +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Ceph Storage Tools 1.3 for Red Hat Enterprise Linux 7 Server (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-supplementary-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/supplementary/debug +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Supplementary (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-satellite-tools-6.1-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/7Server/$basearch/sat-tools/6.1/debug +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Satellite Tools 6.1 (for RHEL 7 Server) (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-server-rhscl-7-beta-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/rhscl/1/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Software Collections Beta Source RPMs for Red Hat Enterprise Linux 7 Server +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rhn-tools-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/rhn-tools/os +ui_repoid_vars = releasever basearch +sslverify = 1 +name = RHN Tools for Red Hat Enterprise Linux 7 Server (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-server-rhscl-7-beta-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/rhscl/1/debug +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Software Collections Beta Debug RPMs for Red Hat Enterprise Linux 7 Server +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-extras-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/7Server/$basearch/extras/debug +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Extras (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rh-common-beta-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/rh-common/debug +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - RH Common Beta (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/debug +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-thirdparty-oracle-java-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/oracle-java/os +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Oracle Java (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-optional-fastrack-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/fastrack/rhel/server/7/$basearch/optional/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Optional Fastrack (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-fastrack-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/fastrack/rhel/server/7/$basearch/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Fastrack (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-satellite-tools-6-beta-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/sat-tools/6/debug +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Satellite Tools 6 Beta (for RHEL 7 Server) (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-optional-beta-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/optional/debug +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Optional Beta (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rh-common-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/rh-common/os +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - RH Common (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-satellite-tools-6.1-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/7Server/$basearch/sat-tools/6.1/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Satellite Tools 6.1 (for RHEL 7 Server) (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-openstack-7.0-tools-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/openstack-tools/7.0/debug +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat OpenStack Tools 7.0 for Red Hat Enterprise Linux 7 Server (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rh-gluster-3-client-for-rhel-7-server-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/rhs-client/debug +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Storage Native Client for RHEL 7 (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-thirdparty-oracle-java-beta-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/oracle-java/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Oracle Java Beta (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-optional-fastrack-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/fastrack/rhel/server/7/$basearch/optional/debug +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Optional Fastrack (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rh-gluster-3-client-for-rhel-7-server-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/rhs-client/os +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Storage Native Client for RHEL 7 (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-satellite-tools-6.1-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/7Server/$basearch/sat-tools/6.1/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Satellite Tools 6.1 (for RHEL 7 Server) (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rh-common-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/rh-common/debug +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - RH Common (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-supplementary-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/supplementary/os +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Supplementary (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rhn-tools-beta-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/rhn-tools/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = RHN Tools for Red Hat Enterprise Linux 7 Server Beta (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-fastrack-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/fastrack/rhel/server/7/$basearch/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Fastrack (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/source/SRPMS +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-optional-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/optional/os +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Optional (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rh-common-beta-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/rh-common/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - RH Common Beta (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rhceph-1.3-tools-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/ceph-tools/1.3/source/SRPMS +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Ceph Storage Tools 1.3 for Red Hat Enterprise Linux 7 Server (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-thirdparty-oracle-java-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/oracle-java/source/SRPMS +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Oracle Java (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-supplementary-beta-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/supplementary/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Supplementary Beta (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-satellite-tools-6-beta-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/sat-tools/6/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Satellite Tools 6 Beta (for RHEL 7 Server) (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-satellite-tools-6-beta-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/sat-tools/6/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Satellite Tools 6 Beta (for RHEL 7 Server) (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-supplementary-beta-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/supplementary/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Supplementary Beta (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rhceph-1.3-tools-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/ceph-tools/1.3/os +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Ceph Storage Tools 1.3 for Red Hat Enterprise Linux 7 Server (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-extras-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/7Server/$basearch/extras/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Extras (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-optional-fastrack-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/fastrack/rhel/server/7/$basearch/optional/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Optional Fastrack (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rhn-tools-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/rhn-tools/source/SRPMS +ui_repoid_vars = releasever basearch +sslverify = 1 +name = RHN Tools for Red Hat Enterprise Linux 7 Server (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-fastrack-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/fastrack/rhel/server/7/$basearch/debug +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Fastrack (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-rh-common-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/rh-common/source/SRPMS +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - RH Common (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-supplementary-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/supplementary/source/SRPMS +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Supplementary (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-thirdparty-oracle-java-beta-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/oracle-java/source/SRPMS +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Oracle Java Beta (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-optional-beta-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/optional/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Optional Beta (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-beta-debug-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/debug +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server Beta (Debug RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-optional-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/optional/source/SRPMS +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server - Optional (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-openstack-7.0-tools-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/openstack-tools/7.0/source/SRPMS +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat OpenStack Tools 7.0 for Red Hat Enterprise Linux 7 Server (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-beta-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/beta/rhel/server/7/$basearch/os +ui_repoid_vars = basearch +sslverify = 1 +name = Red Hat Enterprise Linux 7 Server Beta (RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1 + +[rhel-7-server-v2vwin-1-source-rpms] +metadata_expire = 86400 +sslclientcert = /etc/pki/entitlement/5983099999824052042.pem +baseurl = https://cdn.redhat.com/content/dist/rhel/server/7/$releasever/$basearch/v2vwin/source/SRPMS +ui_repoid_vars = releasever basearch +sslverify = 1 +name = Red Hat Virt V2V Tool for RHEL 7 (Source RPMs) +sslclientkey = /etc/pki/entitlement/5983099999824052042-key.pem +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +enabled = 0 +sslcacert = /etc/rhsm/ca/redhat-uep.pem +gpgcheck = 1