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
示例#2
0
    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
示例#3
0
    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
示例#6
0
    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')
示例#7
0
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
示例#8
0
    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
示例#9
0
    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
示例#10
0
    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')
示例#12
0
    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'
示例#13
0
    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
示例#14
0
    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'
示例#17
0
    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')
示例#18
0
    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
示例#19
0
    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'
示例#20
0
    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()
示例#21
0
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)
示例#22
0
    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()
示例#23
0
文件: drydock.py 项目: cb371j/drydock
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