def execute_tasks(self, params): """Execute deployment tasks fuel node --node 2 --tasks hiera netconfig fuel node --node 2 --tasks netconfig --force fuel node --node 2 --skip hiera netconfig fuel node --node 2 --skip rsync --end pre_deployment_end fuel node --node 2 --end netconfig fuel node --node 2 --start hiera --end neutron fuel node --node 2 --start post_deployment_start """ node_collection = NodeCollection.init_with_ids(params.node) env_id_to_start = self.get_env_id(node_collection) env = Environment(env_id_to_start) tasks = params.tasks or None force = params.force or None if params.skip or params.end or params.start: tasks = env.get_tasks( skip=params.skip, end=params.end, start=params.start, include=tasks) if not tasks: self.serializer.print_to_output({}, "Nothing to run.") return task = env.execute_tasks( node_collection.collection, tasks=tasks, force=force) self.serializer.print_to_output( task.data, "Started tasks {0} for nodes {1}.".format(tasks, node_collection))
def roles(self, uid): from fuelclient.objects.node import Node from fuelclient.objects.environment import Environment node = Node(uid) env = Environment(node.data['cluster']) facts = env.get_default_facts('deployment', [uid]) return [f['role'] for f in facts]
def set(self, params): """To change environment name: fuel --env 1 env set --name NewEnvName """ acceptable_params = ('name', ) env = Environment(params.env, params=params) # forming message for output and data structure for request body # TODO(aroma): make it less ugly msg_template = ("Following attributes are changed for " "the environment: {env_attributes}") env_attributes = [] update_kwargs = dict() for param_name in acceptable_params: attr_value = getattr(params, param_name, None) if attr_value: update_kwargs[param_name] = attr_value env_attributes.append(''.join( [param_name, '=', str(attr_value)])) data = env.set(update_kwargs) env_attributes = ', '.join(env_attributes) self.serializer.print_to_output( data, msg_template.format(env_attributes=env_attributes))
class TestEnvironmentOstf(base.UnitTestCase): def setUp(self): super(TestEnvironmentOstf, self).setUp() self.env = Environment(None) @mock.patch.object(Environment.connection, 'post_request', mock.Mock( return_value=[ {'id': 1}, {'id': 2}, ])) def test_run_test_sets(self): self.assertEqual(self.env._testruns_ids, []) testruns = self.env.run_test_sets(['sanity', 'ha']) self.assertEqual(len(testruns), 2) self.assertIn(1, self.env._testruns_ids) self.assertIn(2, self.env._testruns_ids) @mock.patch.object(Environment.connection, 'get_request', mock.Mock( side_effect=[ {'id': 1, 'status': 'running'}, {'id': 2, 'status': 'finished'}, ])) def test_get_state_of_tests(self): self.env._testruns_ids.extend([1, 2]) tests = self.env.get_state_of_tests() self.env.connection.get_request.assert_has_calls([ mock.call('testruns/1', ostf=True), mock.call('testruns/2', ostf=True)]) self.assertEqual(tests, [ {'id': 1, 'status': 'running'}, {'id': 2, 'status': 'finished'}])
def check(self, params): """To run some health checks: fuel --env 1 health --check smoke,sanity """ env = Environment(params.env) if env.status not in self._allowed_statuses and not params.force: exit_with_error( "Environment is not ready to run health check " "because it is in {0} state. " "Health check is likely to fail because of " "this. Use --force flag to proceed anyway.". format(env.status) ) if env.is_customized and not params.force: exit_with_error( "Environment deployment facts were updated. " "Health check is likely to fail because of " "that. Use --force flag to proceed anyway." ) test_sets_to_check = params.check or set( ts["id"] for ts in env.get_testsets()) env.run_test_sets(test_sets_to_check) tests_state = env.get_state_of_tests() self.serializer.print_to_output( tests_state, env, print_method=print_health_check )
def set(self, params): """To change environment name: fuel --env 1 env set --name NewEnvName """ acceptable_params = ('name', 'pending_release_id') env = Environment(params.env, params=params) # forming message for output and data structure for request body # TODO(aroma): make it less ugly msg_template = ("Following attributes are changed for " "the environment: {env_attributes}") env_attributes = [] update_kwargs = dict() for param_name in acceptable_params: attr_value = getattr(params, param_name, None) if attr_value: update_kwargs[param_name] = attr_value env_attributes.append( ''.join([param_name, '=', str(attr_value)]) ) data = env.set(update_kwargs) env_attributes = ', '.join(env_attributes) self.serializer.print_to_output( data, msg_template.format(env_attributes=env_attributes) )
def execute_tasks(self, params): """Execute deployment tasks fuel node --node 2 --tasks hiera netconfig fuel node --node 2 --tasks netconfig --force fuel node --node 2 --skip hiera netconfig fuel node --node 2 --skip rsync --end pre_deployment_end fuel node --node 2 --end netconfig fuel node --node 2 --start hiera --end neutron fuel node --node 2 --start post_deployment_start """ node_collection = NodeCollection.init_with_ids(params.node) env_id_to_start = self.get_env_id(node_collection) env = Environment(env_id_to_start) tasks = params.tasks or None force = params.force or None if params.skip or params.end or params.start: tasks = env.get_tasks(skip=params.skip, end=params.end, start=params.start, include=tasks) if not tasks: self.serializer.print_to_output({}, "Nothing to run.") return task = env.execute_tasks(node_collection.collection, tasks=tasks, force=force) self.serializer.print_to_output( task.data, "Started tasks {0} for nodes {1}.".format(tasks, node_collection))
def execute_tasks(self, params): """Execute deployment tasks fuel node --node 2 --tasks hiera netconfig fuel node --node 2 --skip hiera netconfig fuel node --node 2 --skip rsync --end pre_deployment fuel node --node 2 --end netconfig fuel node --node 2 --start hiera --end neutron fuel node --node 2 --start post_deployment """ node_collection = NodeCollection.init_with_ids(params.node) env_id_to_start = self.get_env_id(node_collection) env = Environment(env_id_to_start) if params.tasks: tasks = params.tasks else: tasks = env.get_tasks( skip=params.skip, end=params.end, start=params.start) task = env.execute_tasks(node_collection.collection, tasks=tasks) self.serializer.print_to_output( task.data, "Started tasks {0} for nodes {1}.".format(tasks, node_collection))
def delete(self, params): """Deletes network template for specified environment: fuel --env 1 --network-template --delete """ env = Environment(params.env) env.delete_network_template_data() print("Network template configuration for environment id={0}" " has been deleted.".format(env.id))
def delete(self, params): """To delete the environment: fuel --env 1 env delete """ env = Environment(params.env, params=params) data = env.delete() self.serializer.print_to_output( data, "Environment with id={0} was deleted.".format(env.id))
def verify(self, params): """To verify network configuration from some directory for some environment: fuel --env 1 network --verify --dir path/to/directory """ env = Environment(params.env) response = env.verify_network() print("Verification status is '{status}'. message: {message}".format(**response))
class TestEnvironmentOstf(base.UnitTestCase): def setUp(self): super(TestEnvironmentOstf, self).setUp() self.env = Environment(None) @mock.patch.object(Environment.connection, 'post_request', mock.Mock(return_value=[ { 'id': 1 }, { 'id': 2 }, ])) def test_run_test_sets(self): self.assertEqual(self.env._testruns_ids, []) testruns = self.env.run_test_sets(['sanity', 'ha']) self.assertEqual(len(testruns), 2) self.assertIn(1, self.env._testruns_ids) self.assertIn(2, self.env._testruns_ids) @mock.patch.object(Environment.connection, 'get_request', mock.Mock(side_effect=[ { 'id': 1, 'status': 'running' }, { 'id': 2, 'status': 'finished' }, ])) def test_get_state_of_tests(self): self.env._testruns_ids.extend([1, 2]) tests = self.env.get_state_of_tests() self.env.connection.get_request.assert_has_calls([ mock.call('testruns/1', ostf=True), mock.call('testruns/2', ostf=True) ]) self.assertEqual(tests, [{ 'id': 1, 'status': 'running' }, { 'id': 2, 'status': 'finished' }]) def test_get_deployment_tasks_with_end(self): end = 'task1' get = self.m_request.get(rm.ANY, json={}) self.env.get_deployment_tasks(end=end) self.assertEqual(get.last_request.qs, {'end': ['task1']})
def upload(self, params): """To upload settings for some environment from some directory: fuel --env 1 settings --upload --dir path/to/directory """ env = Environment(params.env) settings_data = env.read_settings_data(directory=params.dir, serializer=self.serializer) env.set_settings_data(settings_data, params.force) print("Settings configuration uploaded.")
def upload(self, params): """To upload vmware settings for some environment from some directory: fuel --env 1 vmware-settings --upload --dir path/to/directory """ env = Environment(params.env) vmware_settings_data = env.read_vmware_settings_data( directory=params.dir, serializer=self.serializer) env.set_vmware_settings_data(vmware_settings_data) print("Vmware settings configuration uploaded.")
def upload(self, params): """To upload network configuration from some directory for some environment: fuel --env 1 network --upload --dir path/to/directory """ env = Environment(params.env) network_data = env.read_network_data(directory=params.dir, serializer=self.serializer) env.set_network_data(network_data) print("Network configuration uploaded.")
def verify(self, params): """To verify network configuration from some directory for some environment: fuel --env 1 network --verify --dir path/to/directory """ env = Environment(params.env) response = env.verify_network() print("Verification status is '{status}'. message: {message}".format( **response))
def list(self, params): """To list all health check test sets: fuel --env 1 health or: fuel --env 1 health --list """ env = Environment(params.env) test_sets = env.get_testsets() self.serializer.print_to_output(test_sets, format_table(test_sets))
def delete(self, params): """Also {action_name} information can be left or taken from specific directory: fuel --env 1 {action_name} --upload \\ --dir path/to/some/directory """ env = Environment(params.env) env.delete_facts(self.action_name) print("{0} facts deleted.".format(self.action_name))
def list(self, params): """To list all health check test sets: fuel health or: fuel --env 1 health --list """ env = Environment(params.env) test_sets = env.get_testsets() self.serializer.print_to_output(test_sets, format_table(test_sets))
def upload(self, params): """To upload {action_name} information for some environment: fuel --env 1 {action_name} --upload """ env = Environment(params.env) facts = env.read_fact_info(self.action_name, directory=params.dir, serializer=self.serializer) env.upload_facts(self.action_name, facts) print("{0} facts were uploaded.".format(self.action_name))
def get_fuel_node_ip(env): fuel_node_ip = None from fuelclient.objects.environment import Environment e = Environment(env) nodes_id = [x.data['id'] for x in e.get_all_nodes()] for fact in e.get_default_facts('deployment', [nodes_id[0]]): fuel_node_ip = fact['master_ip'] if fuel_node_ip: break return fuel_node_ip
def upload(self, params): """Uploads network template from filesystem path for specified environment: fuel --env 1 network-template --upload --dir path/to/directory """ env = Environment(params.env) network_template_data = env.read_network_template_data(directory=params.dir, serializer=self.serializer) env.set_network_template_data(network_template_data) full_path = self.serializer.prepare_path(env.get_network_template_data_path(directory=params.dir)) print("Network template {0} has been uploaded.".format(full_path))
def default(self, params): """To download default settings for some environment in some directory: fuel --env 1 settings --default --dir path/to/directory """ env = Environment(params.env) default_data = env.get_default_settings_data() settings_file_path = env.write_settings_data( default_data, directory=params.dir, serializer=self.serializer) print("Default settings configuration downloaded to {0}.".format( settings_file_path))
def download(self, params): """To download settings for some environment in this directory: fuel --env 1 settings --download """ env = Environment(params.env) settings_data = env.get_settings_data() settings_file_path = env.write_settings_data( settings_data, directory=params.dir, serializer=self.serializer) print("Settings configuration for environment with id={0}" " downloaded to {1}".format(env.id, settings_file_path))
def upload(self, params): """To upload settings for some environment from some directory: fuel --env 1 settings --upload --dir path/to/derectory """ env = Environment(params.env) network_data = env.read_settings_data(directory=params.dir) response = env.set_settings_data(network_data) self.serializer.print_to_output( response, "Settings configuration uploaded." )
def download(self, params): """To download network configuration in this directory for some environment: fuel --env 1 network --download """ env = Environment(params.env) network_data = env.get_network_data() network_file_path = env.write_network_data(network_data, directory=params.dir, serializer=self.serializer) print( "Network configuration for environment with id={0}" " downloaded to {1}".format(env.id, network_file_path) )
def upload(self, params): """To upload settings for some environment from some directory: fuel --env 1 settings --upload --dir path/to/directory """ env = Environment(params.env) settings_data = env.read_settings_data( directory=params.dir, serializer=self.serializer ) env.set_settings_data(settings_data, params.force) print("Settings configuration uploaded.")
def deploy_changes(self, params): """To deploy all applied changes to some environment: fuel --env 1 deploy-changes """ from fuelclient.objects.environment import Environment env = Environment(params.env) deploy_task = env.deploy_changes() self.serializer.print_to_output( deploy_task.data, deploy_task, print_method=print_deploy_progress)
def delete(self, params): """To delete the environment: fuel --env 1 env delete """ env = Environment(params.env, params=params) data = env.delete() self.serializer.print_to_output( data, "Environment with id={0} was deleted." .format(env.id) )
def upload(self, params): """To upload vmware settings for some environment from some directory: fuel --env 1 vmware-settings --upload --dir path/to/directory """ env = Environment(params.env) vmware_settings_data = env.read_vmware_settings_data( directory=params.dir, serializer=self.serializer ) env.set_vmware_settings_data(vmware_settings_data) print("Vmware settings configuration uploaded.")
def download(self, params): """Downloads network template in current directory for specified environment: fuel --env 1 network-template --download """ env = Environment(params.env) template_data = env.get_network_template_data() network_template_file_path = env.write_network_template_data( template_data, directory=params.dir, serializer=self.serializer) print("Network template configuration for environment with id={0}" " downloaded to {1}".format(env.id, network_template_file_path))
def upload(self, params): """To upload {action_name} information for some environment: fuel --env 1 {action_name} --upload """ env = Environment(params.env) facts = env.read_fact_info( self.action_name, directory=params.dir, serializer=self.serializer ) env.upload_facts(self.action_name, facts) print("{0} facts were uploaded.".format(self.action_name))
def download(self, params): """To download {action_name} information for some environment: fuel --env 1 {action_name} --download """ env = Environment(params.env) dir_name = env.write_facts_to_dir(self.action_name, env.get_facts(self.action_name, nodes=params.node), directory=params.dir, serializer=self.serializer) print("Current {0} info was downloaded to {1}".format( self.action_name, dir_name))
def upload(self, params): """To upload VIP configuration from some file for some environment: fuel --env 1 vip --upload vip.yaml """ env = Environment(params.env) vips_data = env.read_vips_data_from_file( file_path=params.upload, serializer=self.serializer ) env.set_vips_data(vips_data) print("VIP configuration uploaded.")
def set(self, params): """Assign some nodes to environment with with specific roles: fuel --env 1 node set --node 1 --role controller fuel --env 1 node set --node 2,3,4 --role compute,cinder """ env = Environment(params.env) nodes = Node.get_by_ids(params.node) roles = map(str.lower, params.role) env.assign(nodes, roles) self.serializer.print_to_output({}, "Nodes {0} with roles {1} " "were added to environment {2}".format( params.node, roles, params.env))
def download(self, params): """To download network configuration in this directory for some environment: fuel --env 1 network --download """ env = Environment(params.env) network_data = env.get_network_data() network_file_path = env.write_network_data(network_data, directory=params.dir, serializer=self.serializer) print("Network configuration for environment with id={0}" " downloaded to {1}".format(env.id, network_file_path))
def default(self, params): """To download default settings for some environment in some directory: fuel --env 1 settings --default --dir path/to/directory """ env = Environment(params.env) default_data = env.get_default_settings_data() settings_file_path = env.write_settings_data( default_data, directory=params.dir, serializer=self.serializer) print( "Default settings configuration downloaded to {0}." .format(settings_file_path) )
def update(self, params): """Update environment to given OS release: fuel env --env 1 --update --release 1 """ params.pending_release_id = params.release self.set(params) env = Environment(params.env, params=params) update_task = env.update_env() msg = ("Update process for environment has been started. " "Update task id is {0}".format(update_task.id)) self.serializer.print_to_output({}, msg)
def delete(self, params): """Remove some nodes from environment: fuel --env 1 node remove --node 2,3 Remove nodes no matter to which environment they were assigned: fuel node remove --node 2,3,6,7 Remove all nodes from some environment: fuel --env 1 node remove --all """ if params.env: env = Environment(params.env) if params.node: env.unassign(params.node) self.serializer.print_to_output( {}, "Nodes with ids {0} were removed " "from environment with id {1}." .format(params.node, params.env)) else: if params.all: env.unassign_all() else: raise error.ArgumentException( "You have to select which nodes to remove " "with --node-id. Try --all for removing all nodes." ) self.serializer.print_to_output( {}, "All nodes from environment with id {0} were removed." .format(params.env)) else: nodes = map(Node, params.node) for env_id, _nodes in groupby(nodes, attrgetter("env_id")): list_of_nodes = [n.id for n in _nodes] if env_id: Environment(env_id).unassign(list_of_nodes) self.serializer.print_to_output( {}, "Nodes with ids {0} were removed " "from environment with id {1}." .format(list_of_nodes, env_id) ) else: self.serializer.print_to_output( {}, "Nodes with ids {0} aren't added to " "any environment.".format(list_of_nodes) )
def download(self, params): """To download settings for some environment in this directory: fuel --env 1 settings --download """ env = Environment(params.env) settings_data = env.get_settings_data() settings_file_path = env.write_settings_data( settings_data, directory=params.dir, serializer=self.serializer) print( "Settings configuration for environment with id={0}" " downloaded to {1}" .format(env.id, settings_file_path) )
def download(self, params): """Downloads network template in current directory for specified environment: fuel --env 1 network-template --download """ env = Environment(params.env) template_data = env.get_network_template_data() network_template_file_path = env.write_network_template_data( template_data, directory=params.dir, serializer=self.serializer ) print( "Network template configuration for environment with id={0}" " downloaded to {1}".format(env.id, network_template_file_path) )
def set(self, params): """Assign some nodes to environment with with specific roles: fuel --env 1 node set --node 1 --role controller fuel --env 1 node set --node 2,3,4 --role compute,cinder """ env = Environment(params.env) nodes = Node.get_by_ids(params.node) roles = map(str.lower, params.role) env.assign(nodes, roles) self.serializer.print_to_output( {}, "Nodes {0} with roles {1} " "were added to environment {2}" .format(params.node, roles, params.env) )
def get_nodes_info(env): from fuelclient.objects.environment import Environment e = Environment(env) nodes_info = [] for node in e.get_all_nodes(): node_info = {} node_info['id'] = node.data['id'] node_info['fqdn'] = node.data['fqdn'] node_info['roles'] = node.data['roles'] for nic in node.data['network_data']: if nic['name'] == 'fuelweb_admin': node_info['fuelweb_admin'] = nic['ip'] if nic['name'] == 'management': node_info['management'] = nic['ip'] nodes_info.append(node_info) return nodes_info
def create(self, params): """To create an environment with name MyEnv and release id=1 run: fuel env create --name MyEnv --rel 1 By default it creates environment in multinode mode, and nova network mode, to specify other modes add optional arguments: fuel env create --name MyEnv --rel 1 \\ --mode ha --network-mode neutron """ env = Environment.create( params.name, params.release, params.net, net_segment_type=params.nst ) if params.mode: data = env.set({'mode': params.mode}) else: data = env.get_fresh_data() self.serializer.print_to_output( data, u"Environment '{name}' with id={id}, mode={mode}" u" and network-mode={net_provider} was created!" .format(**data) )
def create(self, params): """To create an environment with name MyEnv and release id=1 run: fuel env create --name MyEnv --rel 1 By default, it creates environment setting neutron with VLAN network segmentation as network provider To specify other modes add optional arguments: fuel env create --name MyEnv --rel 1 --net-segment-type vlan """ if params.nst == 'gre': six.print_( "WARNING: GRE network segmentation type is deprecated " "since 7.0 release.", file=sys.stderr) env = Environment.create( params.name, params.release, params.nst, ) data = env.get_fresh_data() self.serializer.print_to_output( data, u"Environment '{name}' with id={id} was created!".format(**data))
def set(self, params): """For changing environments name, mode or network mode exists set action: fuel --env 1 env set --name NewEmvName --mode ha_compact """ env = Environment(params.env, params=params) data = env.set(name=params.name, mode=params.mode) msg_templates = [] if params.name: msg_templates.append( "Environment with id={id} was renamed to '{name}'.") if params.mode: msg_templates.append( "Mode of environment with id={id} was set to '{mode}'.") self.serializer.print_to_output( data, "\n".join(msg_templates).format(**data))
def create(self, params): """To create an environment with name MyEnv and release id=1 run: fuel env create --name MyEnv --rel 1 By default, it creates environment setting neutron with VLAN network segmentation as network provider To specify other modes add optional arguments: fuel env create --name MyEnv --rel 1 --net-segment-type vlan """ if params.nst == 'gre': self.serializer.print_to_output( {}, "WARNING: GRE network segmentation type is deprecated " "since 7.0 release." ) env = Environment.create( params.name, params.release, params.nst, ) data = env.get_fresh_data() self.serializer.print_to_output( data, u"Environment '{name}' with id={id} was created!" .format(**data) )
def create(self, params): """To create an environment with name MyEnv and release id=1 run: fuel env create --name MyEnv --rel 1 By default, it creates environment with ha_compact mode and neutron with VLAN network segmentation as network provider (WARNING: nova-network is deprecated since 6.1 release). To specify other modes add optional arguments: fuel env create --name MyEnv --rel 1 \\ --mode ha --network-mode neutron """ if params.net == "nova": self.serializer.print_to_output( {}, "Warning: nova-network is deprecated since 6.1 release." ) env = Environment.create( params.name, params.release, params.net, params.nst ) if params.mode: data = env.set({'mode': params.mode}) else: data = env.get_fresh_data() self.serializer.print_to_output( data, u"Environment '{name}' with id={id}, mode={mode}" u" and network-mode={net_provider} was created!" .format(**data) )
class DeployTask(Task): def __init__(self, obj_id, env_id): from fuelclient.objects.environment import Environment super(DeployTask, self).__init__(obj_id) self.env = Environment(env_id) self.nodes = self.env.get_all_nodes() @classmethod def init_with_data(cls, data): return cls(data["id"], data["cluster"]) @property def not_finished_nodes(self): return filter(lambda n: not n.is_finished(latest=False), self.nodes) @property def is_finished(self): return super(DeployTask, self).is_finished and all( map(methodcaller("is_finished"), self.not_finished_nodes)) def __iter__(self): return self def next(self): if not self.is_finished: sleep(1) deploy_task_data = self.get_fresh_data() if deploy_task_data["status"] == "error": raise DeployProgressError(deploy_task_data["message"]) for node in self.not_finished_nodes: node.update() return self.progress, self.nodes else: raise StopIteration
def default(self, params): """To get default {action_name} information for some environment: fuel --env 1 {action_name} --default It's possible to get default {action_name} information just for some nodes: fuel --env 1 {action_name} --default --node 1,2,3 """ env = Environment(params.env) dir_name = env.write_facts_to_dir(self.action_name, env.get_default_facts( self.action_name, nodes=params.node), directory=params.dir, serializer=self.serializer) print("Default {0} info was downloaded to {1}".format( self.action_name, dir_name))
def delete(self, params): """To delete the environment: fuel --env 1 env --force delete """ env = Environment(params.env, params=params) if env.status == "operational" and not params.force: self.serializer.print_to_output( env.data, "Deleting an operational" "environment is a dangerous " "operation. Please use --force to " "bypass this message.") return data = env.delete() self.serializer.print_to_output( data, "Environment with id={0} was deleted".format(env.id))