def test_bootaction_tarbuilder(self, input_files, deckhand_ingester, setup): objects.register_all() input_file = input_files.join("deckhand_fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) design_status, design_data = deckhand_ingester.ingest_data( design_state=design_state, design_ref=design_ref) target_host = 'compute01' ba = design_data.get_bootaction('helloworld') action_id = ulid2.generate_binary_ulid() assets = ba.render_assets(target_host, design_data, action_id) assert len(assets) > 0 tarbytes = BootactionUtils.tarbuilder(assets) assert tarbytes is not None fileobj = io.BytesIO(tarbytes) tarball = tarfile.open(mode='r:gz', fileobj=fileobj) tarasset = tarball.getmember('/var/tmp/hello.sh') assert tarasset.mode == 0o555
def test_ingest_federated_design(self, input_files): objects.register_all() profiles_file = input_files.join("fullsite_profiles.yaml") networks_file = input_files.join("fullsite_networks.yaml") nodes_file = input_files.join("fullsite_nodes.yaml") design_state = DesignState() design_data = objects.SiteDesign() design_id = design_data.assign_id() design_state.post_design(design_data) ingester = Ingester() ingester.enable_plugins( ['drydock_provisioner.ingester.plugins.yaml.YamlIngester']) ingester.ingest_data(plugin_name='yaml', design_state=design_state, design_id=design_id, filenames=[ str(profiles_file), str(networks_file), str(nodes_file) ]) design_data = design_state.get_design(design_id) assert len(design_data.host_profiles) == 2
def test_orch_preparesite(self, input_files): objects.register_all() input_file = input_files.join("fullsite.yaml") design_state = statemgmt.DesignState() design_data = objects.SiteDesign() design_id = design_data.assign_id() design_state.post_design(design_data) ingester = Ingester() ingester.enable_plugins([drydock_provisioner.ingester.plugins.yaml.YamlIngester]) ingester.ingest_data(plugin_name='yaml', design_state=design_state, filenames=[str(input_file)], design_id=design_id) design_data = design_state.get_design(design_id) orchestrator = orch.Orchestrator(state_manager=design_state, enabled_drivers={'node': 'drydock_provisioner.drivers.node.maasdriver.driver.MaasNodeDriver'}) orch_task = orchestrator.create_task(task.OrchestratorTask, site='sitename', design_id=design_id, action=hd_fields.OrchestratorAction.PrepareSite) orchestrator.execute_task(orch_task.get_id()) orch_task = design_state.get_task(orch_task.get_id()) assert orch_task.result == hd_fields.ActionResult.Success
def test_bootaction_pipeline_utf8(self): objects.register_all() ba = objects.BootActionAsset() expected_value = 'Test 1 2 3!' orig = expected_value.encode('utf-8') test_value = ba.execute_pipeline(orig, ['utf8_decode']) assert test_value == expected_value
def test_bootaction_pipeline_base64(self): objects.register_all() ba = objects.BootActionAsset() orig = 'Test 1 2 3!'.encode('utf-8') expected_value = base64.b64encode(orig) test_value = ba.execute_pipeline(orig, ['base64_encode']) assert expected_value == test_value
def test_rack_not_found(self, deckhand_ingester, input_files, setup): objects.register_all() input_file = input_files.join("deckhand_fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) design_status, design_data = deckhand_ingester.ingest_data( design_state=design_state, design_ref=design_ref) with pytest.raises(errors.DesignError): design_data.get_rack('foo')
def setup(setup_logging): objects.register_all() config.config_mgr.register_options(enable_keystone=False) config.config_mgr.conf([]) config.config_mgr.conf.set_override( name="database_connect_string", group="database", override="postgresql+psycopg2://drydock:drydock@localhost:5432/drydock" ) config.config_mgr.conf.set_override( name="leader_grace_period", override=15) config.config_mgr.conf.set_override(name="poll_interval", override=3) return
def test_ingest_yaml(self, input_files, setup, yaml_ingester): objects.register_all() input_file = input_files.join("fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) design_status, design_data = yaml_ingester.ingest_data( design_state=design_state, design_ref=design_ref) print("%s" % str(design_status.to_dict())) assert design_status.status == objects.fields.ActionResult.Success assert len(design_data.host_profiles) == 2 assert len(design_data.baremetal_nodes) == 2
def test_bootaction_parse(self, input_files, deckhand_ingester, setup): objects.register_all() input_file = input_files.join("invalid_bootaction.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) design_status, design_data = deckhand_ingester.ingest_data( design_state=design_state, design_ref=design_ref) assert design_status.status == objects.fields.ActionResult.Failure print(str(design_status.to_dict())) error_msgs = [m for m in design_status.message_list if m.error] assert len(error_msgs) == 2
def test_bootaction_render(self, input_files, deckhand_ingester, setup): objects.register_all() input_file = input_files.join("deckhand_fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) design_status, design_data = deckhand_ingester.ingest_data( design_state=design_state, design_ref=design_ref) ba = design_data.get_bootaction('helloworld') action_id = ulid2.generate_binary_ulid() assets = ba.render_assets('compute01', design_data, action_id) assert 'compute01' in assets[0].rendered_bytes.decode('utf-8')
def test_rack_not_found(self, input_files, setup): objects.register_all() input_file = input_files.join("fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) ingester = Ingester() ingester.enable_plugin( 'drydock_provisioner.ingester.plugins.yaml.YamlIngester') design_status, design_data = ingester.ingest_data( design_state=design_state, design_ref=design_ref) with pytest.raises(errors.DesignError): design_data.get_rack('foo')
def test_rack_parse(self, deckhand_ingester, input_files, setup): objects.register_all() input_file = input_files.join("deckhand_fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) design_status, design_data = deckhand_ingester.ingest_data( design_state=design_state, design_ref=design_ref) print("%s" % str(design_status.to_dict())) assert design_status.status == objects.fields.ActionResult.Success rack = design_data.get_rack('rack1') assert rack.location.get('grid') == 'EG12'
def test_ingest_full_site(self, input_files, setup): objects.register_all() input_file = input_files.join("fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) ingester = Ingester() ingester.enable_plugin( 'drydock_provisioner.ingester.plugins.yaml.YamlIngester') design_status, design_data = ingester.ingest_data( design_state=design_state, design_ref=design_ref) assert len(design_data.host_profiles) == 2 assert len(design_data.baremetal_nodes) == 2
def loaded_design(self, input_files): objects.register_all() input_file = input_files.join("oob.yaml") design_state = statemgmt.DesignState() design_data = objects.SiteDesign(id=self.design_id) design_state.post_design(design_data) ingester = Ingester() ingester.enable_plugins([yaml_ingester.YamlIngester]) ingester.ingest_data(plugin_name='yaml', design_state=design_state, design_id=self.design_id, filenames=[str(input_file)]) return design_state
def test_bootaction_parse(self, input_files, setup): objects.register_all() input_file = input_files.join("bootaction.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) ingester = Ingester() ingester.enable_plugin( 'drydock_provisioner.ingester.plugins.yaml.YamlIngester') design_status, design_data = ingester.ingest_data( design_state=design_state, design_ref=design_ref) ba = design_data.get_bootaction('helloworld') assert len(ba.asset_list) == 2
def test_rack_parse(self, input_files, setup): objects.register_all() input_file = input_files.join("fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) ingester = Ingester() ingester.enable_plugin( 'drydock_provisioner.ingester.plugins.yaml.YamlIngester') design_status, design_data = ingester.ingest_data( design_state=design_state, design_ref=design_ref) rack = design_data.get_rack('rack1') assert rack.location.get('grid') == 'EG12'
def test_rack_not_found(self, input_files): objects.register_all() input_file = input_files.join("fullsite.yaml") design_state = DesignState() design_data = objects.SiteDesign() design_id = design_data.assign_id() design_state.post_design(design_data) ingester = Ingester() ingester.enable_plugins( ['drydock_provisioner.ingester.plugins.yaml.YamlIngester']) ingester.ingest_data(plugin_name='yaml', design_state=design_state, filenames=[str(input_file)], design_id=design_id) design_data = design_state.get_design(design_id) with pytest.raises(errors.DesignError): rack = design_data.get_rack('foo')
def test_ingest_full_site(self, input_files): objects.register_all() input_file = input_files.join("fullsite.yaml") design_state = DesignState() design_data = objects.SiteDesign() design_id = design_data.assign_id() design_state.post_design(design_data) ingester = Ingester() ingester.enable_plugins( ['drydock_provisioner.ingester.plugins.yaml.YamlIngester']) ingester.ingest_data(plugin_name='yaml', design_state=design_state, filenames=[str(input_file)], design_id=design_id) design_data = design_state.get_design(design_id) assert len(design_data.host_profiles) == 2 assert len(design_data.baremetal_nodes) == 2
def test_rack_parse(self, input_files): objects.register_all() input_file = input_files.join("fullsite.yaml") design_state = DesignState() design_data = objects.SiteDesign() design_id = design_data.assign_id() design_state.post_design(design_data) ingester = Ingester() ingester.enable_plugins( ['drydock_provisioner.ingester.plugins.yaml.YamlIngester']) ingester.ingest_data(plugin_name='yaml', design_state=design_state, filenames=[str(input_file)], design_id=design_id) design_data = design_state.get_design(design_id) rack = design_data.get_rack('rack1') assert rack.location.get('grid') == 'EG12'
def test_sitedesign_post(self): objects.register_all() state_manager = statemgmt.DesignState() design_data = objects.SiteDesign() design_id = design_data.assign_id() initial_site = objects.Site() initial_site.name = 'testsite' net_a = objects.Network() net_a.name = 'net_a' net_a.region = 'testsite' net_a.cidr = '172.16.0.0/24' design_data.set_site(initial_site) design_data.add_network(net_a) state_manager.post_design(design_data) my_design = state_manager.get_design(design_id) assert design_data.obj_to_primitive() == my_design.obj_to_primitive()
def start_drydock(): objects.register_all() # Setup root logger logger = logging.getLogger('drydock') logger.setLevel(config.DrydockConfig.global_config.get('log_level')) ch = logging.StreamHandler() formatter = logging.Formatter( '%(asctime)s - %(levelname)s - %(filename)s:%(funcName)s - %(message)s' ) ch.setFormatter(formatter) logger.addHandler(ch) # Specalized format for API logging logger = logging.getLogger('drydock.control') logger.propagate = False formatter = logging.Formatter( '%(asctime)s - %(levelname)s - %(user)s - %(req_id)s - %(external_ctx)s - %(message)s' ) ch = logging.StreamHandler() ch.setFormatter(formatter) logger.addHandler(ch) state = statemgmt.DesignState() orchestrator = orch.Orchestrator( config.DrydockConfig.orchestrator_config.get('drivers', {}), state_manager=state) input_ingester = ingester.Ingester() input_ingester.enable_plugins( config.DrydockConfig.ingester_config.get('plugins', [])) return api.start_api(state_manager=state, ingester=input_ingester, orchestrator=orchestrator)
def test_hardwareprofile(self): objects.register_all() model_attr = { 'versioned_object.namespace': 'drydock_provisioner.objects', 'versioned_object.name': 'HardwareProfile', 'versioned_object.version': '1.0', 'versioned_object.data': { 'name': 'server', 'source': fields.ModelSource.Designed, 'site': 'test_site', 'vendor': 'Acme', 'generation': '9', 'hw_version': '3', 'bios_version': '2.1.1', 'boot_mode': 'bios', 'bootstrap_protocol': 'pxe', 'pxe_interface': '0', 'devices': { 'versioned_object.namespace': 'drydock_provisioner.objects', 'versioned_object.name': 'HardwareDeviceAliasList', 'versioned_object.version': '1.0', 'versioned_object.data': { 'objects': [ { 'versioned_object.namespace': 'drydock_provisioner.objects', 'versioned_object.name': 'HardwareDeviceAlias', 'versioned_object.version': '1.0', 'versioned_object.data': { 'alias': 'nic', 'source': fields.ModelSource.Designed, 'address': '0000:00:03.0', 'bus_type': 'pci', 'dev_type': '82540EM Gigabit Ethernet Controller', } }, { 'versioned_object.namespace': 'drydock_provisioner.objects', 'versioned_object.name': 'HardwareDeviceAlias', 'versioned_object.version': '1.0', 'versioned_object.data': { 'alias': 'bootdisk', 'source': fields.ModelSource.Designed, 'address': '2:0.0.0', 'bus_type': 'scsi', 'dev_type': 'SSD', } }, ] } } } } hwprofile = objects.HardwareProfile.obj_from_primitive(model_attr) assert getattr(hwprofile, 'bootstrap_protocol') == 'pxe' hwprofile.bootstrap_protocol = 'network' assert 'bootstrap_protocol' in hwprofile.obj_what_changed() assert 'bios_version' not in hwprofile.obj_what_changed()
def start_drydock(): objects.register_all() # Setup configuration parsing cli_options = [ cfg.BoolOpt('debug', short='d', default=False, help='Enable debug logging'), ] cfg.CONF.register_cli_opts(cli_options) config.config_mgr.register_options() cfg.CONF(sys.argv[1:]) if cfg.CONF.debug: cfg.CONF.set_override(name='log_level', override='DEBUG', group='logging') # Setup root logger logger = logging.getLogger(cfg.CONF.logging.global_logger_name) logger.setLevel(cfg.CONF.logging.log_level) ch = logging.StreamHandler() formatter = logging.Formatter( '%(asctime)s - %(levelname)s - %(filename)s:%(funcName)s - %(message)s' ) ch.setFormatter(formatter) logger.addHandler(ch) # Specalized format for API logging logger = logging.getLogger(cfg.CONF.logging.control_logger_name) logger.propagate = False formatter = logging.Formatter( '%(asctime)s - %(levelname)s - %(user)s - %(req_id)s - %(external_ctx)s - %(message)s' ) ch = logging.StreamHandler() ch.setFormatter(formatter) logger.addHandler(ch) state = statemgmt.DesignState() orchestrator = orch.Orchestrator(cfg.CONF.plugins, state_manager=state) input_ingester = ingester.Ingester() input_ingester.enable_plugins(cfg.CONF.plugins.ingester) # Check if we have an API key in the environment # Hack around until we move MaaS configs to the YAML schema if 'MAAS_API_KEY' in os.environ: cfg.CONF.set_override(name='maas_api_key', override=os.environ['MAAS_API_KEY'], group='maasdriver') # Setup the RBAC policy enforcer policy.policy_engine = policy.DrydockPolicy() policy.policy_engine.register_policy() # Ensure that the policy_engine is initialized before starting the API wsgi_callable = api.start_api(state_manager=state, ingester=input_ingester, orchestrator=orchestrator) # Now that loggers are configured, log the effective config cfg.CONF.log_opt_values( logging.getLogger(cfg.CONF.logging.global_logger_name), logging.DEBUG) return wsgi_callable