def test_get_server_by_ilo_address_with_no_registered_servers(self):
        self.mock_connection.get.side_effect = [
            self.get_as_rest_collection([])
        ]

        icsphelper = ICspHelper(self.mock_connection)
        server = icsphelper.get_server_by_ilo_address('16.124.135.239')

        self.mock_connection.get.assert_called_once_with(
            '/rest/os-deployment-servers/?count=-1')

        self.assertIsNone(server)
    def test_get_server_by_ilo_address_with_non_matching_result(self):
        self.mock_connection.get.side_effect = [
            self.get_as_rest_collection([DEFAULT_SERVER])
        ]

        icsphelper = ICspHelper(self.mock_connection)
        server = icsphelper.get_server_by_ilo_address('16.124.135.255')

        self.mock_connection.get.assert_called_once_with(
            '/rest/os-deployment-servers/?count=-1')

        self.assertIsNone(server)
def deploy_server(module):
    # Credentials
    icsp_host = module.params['icsp_host']
    icsp_api_version = module.params['api_version']
    username = module.params['username']
    password = module.params['password']

    # Build Plan Options
    server_id = module.params['server_id']
    os_build_plan = module.params['os_build_plan']
    custom_attributes = module.params['custom_attributes']
    personality_data = module.params['personality_data']
    ilo_address = module.params['server_ipAddress']

    if ilo_address is None and server_id is None:
        return module.fail_json(
            msg=
            'No server information provided. Param \"server_id\" or \"server_ipAddress\" must be specified.'
        )

    con = hpICsp.connection(icsp_host, icsp_api_version)
    icsphelper = ICspHelper(con)

    # Create objects for all necessary resources.
    credential = {'userName': username, 'password': password}
    con.login(credential)

    jb = hpICsp.jobs(con)
    sv = hpICsp.servers(con)

    bp = icsphelper.get_build_plan(os_build_plan)

    if bp is None:
        return module.fail_json(msg='Cannot find OS Build plan: ' +
                                os_build_plan)

    timeout = 600
    while True:
        if ilo_address:
            server = icsphelper.get_server_by_ilo_address(ilo_address)
        else:
            server = icsphelper.get_server_by_serial(server_id)
        if server:
            break
        if timeout < 0:
            module.fail_json(msg='Cannot find server in ICSP.')
            return
        timeout -= 30
        time.sleep(30)

    server = sv.get_server(server['uri'])
    if server['state'] == 'OK':
        return module.exit_json(changed=False,
                                msg="Server already deployed.",
                                ansible_facts={'icsp_server': server})

    if custom_attributes:
        ca_list = []

        for ca in custom_attributes:
            ca_list.append({
                'key':
                list(ca.keys())[0],
                'values': [{
                    'scope': 'server',
                    'value': str(list(ca.values())[0])
                }]
            })

        ca_list.extend(server['customAttributes'])
        server['customAttributes'] = ca_list
        sv.update_server(server)

    server_data = {"serverUri": server['uri'], "personalityData": None}

    build_plan_body = {
        "osbpUris": [bp['uri']],
        "serverData": [server_data],
        "stepNo": 1
    }

    hpICsp.common.monitor_execution(jb.add_job(build_plan_body), jb)

    # If the playbook included network personalization, update the server to include it
    if personality_data:
        server_data['personalityData'] = personality_data
        network_config = {"serverData": [server_data]}
        # Monitor the execution of a nework personalization job.
        hpICsp.common.monitor_execution(jb.add_job(network_config), jb)

    server = sv.get_server(server['uri'])
    return module.exit_json(changed=True,
                            msg='OS Deployed Successfully.',
                            ansible_facts={'icsp_server': server})
Exemple #4
0
class ICspServerModule(object):
    SERVER_CREATED = "Server created: '{}'"
    SERVER_ALREADY_PRESENT = "Server is already present."
    SERVER_ALREADY_ABSENT = "Target server is already absent in ICsp."
    SERVER_REMOVED = "Server '{}' removed successfully from ICsp."
    CUSTOM_ATTR_NETWORK_UPDATED = 'Network Custom Attribute Updated.'
    SERVER_NOT_FOUND = "Target server is not present in ICsp."
    SERVER_PERSONALITY_DATA_REQUIRED = 'server_personality_data must be informed.'

    argument_spec = dict(
        # Connection
        api_version=dict(type='int', default=300),
        icsp_host=dict(required=True, type='str'),
        username=dict(required=True, type='str'),
        password=dict(required=True, type='str', no_log=True),
        # options
        state=dict(required=True,
                   choices=['present', 'absent', 'network_configured']),
        # server data
        server_ipAddress=dict(required=True, type='str'),
        server_username=dict(required=True, type='str'),
        server_password=dict(required=True, type='str', no_log=True),
        server_port=dict(type='int', default=443),
        server_personality_data=dict(required=False, type='dict'))

    def __init__(self):
        self.module = AnsibleModule(argument_spec=self.argument_spec,
                                    supports_check_mode=False)
        self.connection = self.__authenticate()
        self.icsphelper = ICspHelper(self.connection)

    def run(self):

        state = self.module.params['state']
        ilo_address = self.module.params['server_ipAddress']
        target_server = self.icsphelper.get_server_by_ilo_address(ilo_address)

        if state == 'present':
            self.__present(target_server)

        elif state == 'absent':
            self.__absent(target_server)

        elif state == 'network_configured':
            self.__configure_network(target_server)

    def __authenticate(self):
        # Credentials
        icsp_host = self.module.params['icsp_host']
        icsp_api_version = self.module.params['api_version']
        username = self.module.params['username']
        password = self.module.params['password']

        con = hpICsp.connection(icsp_host, icsp_api_version)

        credential = {'userName': username, 'password': password}
        con.login(credential)
        return con

    def __present(self, target_server):
        # check if server exists
        if target_server:
            return self.module.exit_json(
                changed=False,
                msg=self.SERVER_ALREADY_PRESENT,
                ansible_facts=dict(target_server=target_server))

        return self._add_server()

    def __absent(self, target_server):
        # check if server exists
        if not target_server:
            return self.module.exit_json(changed=False,
                                         msg=self.SERVER_ALREADY_ABSENT)

        server_uri = target_server['uri']
        servers_service = hpICsp.servers(self.connection)

        try:
            servers_service.delete_server(server_uri)
            return self.module.exit_json(
                changed=True, msg=self.SERVER_REMOVED.format(server_uri))

        except HPICspException as icsp_exe:
            self.module.fail_json(msg=json.dumps(icsp_exe.__dict__))

        except Exception as exception:
            self.module.fail_json(msg='; '.join(
                str(e) for e in exception.args))

    def __configure_network(self, target_server):
        personality_data = self.module.params.get('server_personality_data')

        if not personality_data:
            return self.module.fail_json(
                msg=self.SERVER_PERSONALITY_DATA_REQUIRED)

        # check if server exists
        if not target_server:
            return self.module.exit_json(changed=False,
                                         msg=self.SERVER_NOT_FOUND)

        server_data = {
            "serverUri": target_server['uri'],
            "personalityData": personality_data,
            "skipReboot": True
        }
        network_config = {
            "serverData": [server_data],
            "failMode": None,
            "osbpUris": []
        }

        # Save nework personalization attribute, without running the job
        self.__add_write_only_job(network_config)

        servers_service = hpICsp.servers(self.connection)
        server = servers_service.get_server(target_server['uri'])
        return self.module.exit_json(changed=True,
                                     msg=self.CUSTOM_ATTR_NETWORK_UPDATED,
                                     ansible_facts={'target_server': server})

    def __add_write_only_job(self, body):
        body = self.connection.post("/rest/os-deployment-jobs/?writeOnly=true",
                                    body)
        return body

    def _add_server(self):
        ilo_address = self.module.params['server_ipAddress']

        # Creates a JSON body for adding an iLo.
        ilo_body = {
            'ipAddress': ilo_address,
            'username': self.module.params['server_username'],
            'password': self.module.params['server_password'],
            'port': self.module.params['server_port']
        }

        job_monitor = hpICsp.jobs(self.connection)
        servers_service = hpICsp.servers(self.connection)

        # Monitor_execution is a utility method to watch job progress on the command line.
        add_server_job = servers_service.add_server(ilo_body)
        hpICsp.common.monitor_execution(add_server_job, job_monitor)

        # Python bindings throw an Exception when the status != ok
        # So if we got this far, the job execution finished as expected

        # gets the target server added to ICsp to return on ansible facts
        target_server = self.icsphelper.get_server_by_ilo_address(ilo_address)
        return self.module.exit_json(
            changed=True,
            msg=self.SERVER_CREATED.format(target_server['uri']),
            ansible_facts=dict(target_server=target_server))