def doWork(self):

        if self.options.remove_clouds and sys.version_info[0:3] < (2, 7, 0):
            print('Error: The use of "--remove-cloud-specific" require Python >= 2.7', file=sys.stderr)
            sys.exit(1)

        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        queue = [self.module]
        while len(queue) > 0:
            module = queue.pop(0)
            print('Processing: %s' % module)

            try:
                
                root = self._retrieveModuleAsXml(client, module)
                self._remove_transient_elements(root)
                if self._is_image(root) and self.options.dump_image_ids:
                    self._dump_image_ids(root)
                if self.options.remove_clouds:
                    self._remove_clouds(root)
                if self.options.remove_group_members:
                    self._remove_group_members(root)
                if self.options.reset_commit_message:
                    self._reset_commit_message(root)
                self._writeModuleAsXml(root, module)

                for child in self._getModuleChildren(module, root):
                    queue.append(child)
                    
            except Exception as e:
                print(e)
                if not self.options.continue_on_error:
                    sys.exit(1)
Esempio n. 2
0
def _get_monitoring_status():
    "Returns monitoring status as JSON."
    nagios_user, nagios_pass = ss_get('nagios_creds').split(':')

    h = HttpClient(username=nagios_user, password=nagios_pass)
    _, res = h.get(NAGIOS_STATUS_URL, accept="application/json")
    return json.loads(res)
    def doWork(self):
        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        # read all files once to determine the upload URL for each file
        # the URL is used to sort the files into an order that puts
        # parents before children
        projects = {}
        images = {}
        deployments = {}
        for file in self.args:

            self._check_file(file)

            with open(file) as f:
                contents = f.read()

                dom = self._read_module_as_xml(contents)
                attrs = SlipStreamHttpClient.DomExtractor.get_attributes(dom)

                root_node_name = dom.tag
                if root_node_name == 'list':
                    sys.stderr.write('Cannot update root project\n')
                    sys.exit(-1)
                if not dom.tag in ('imageModule', 'projectModule',
                                   'deploymentModule'):
                    sys.stderr.write('Invalid xml\n')
                    sys.exit(-1)

                parts = [attrs['parentUri'], attrs['shortName']]
                uri = '/' + '/'.join([part.strip('/') for part in parts])

                url = self.options.endpoint + uri

                if dom.tag == 'projectModule':
                    projects[url] = file
                elif dom.tag == 'imageModule':
                    images[url] = file
                elif dom.tag == 'deploymentModule':
                    deployments[url] = file

        # now actually do the uploads in the correct order
        # projects must be done first to get the structure, then
        # images, and finally the deployments
        for url in sorted(projects):
            file = projects[url]
            print('Uploading project: %s' % file)
            self._put(url, file, client)

        for url in sorted(images):
            file = images[url]
            print('Uploading image: %s' % file)
            self._put(url, file, client)

        for url in sorted(deployments):
            file = deployments[url]
            print('Uploading deployment: %s' % file)
            self._put(url, file, client)
Esempio n. 4
0
    def doWork(self):

        client = HttpClient(self.options.username, self.options.password)
        client.verboseLevel = self.verboseLevel

        # get all users
        if self.options.getusers:
            self.get_users(client)
        elif self.options.putusers:
            self.put_users(client)
    def doWork(self):

        client = HttpClient(self.options.username, self.options.password)
        client.verboseLevel = self.verboseLevel

        # get all users
        if self.options.getusers:
            self.get_users(client)
        elif self.options.putusers:
            self.put_users(client)
Esempio n. 6
0
    def doWork(self):
        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        uri = util.MODULE_RESOURCE_PATH
        if self.module:
            uri += '/' + self.module

        url = self.options.endpoint + uri

        client.delete(url)
    def doWork(self):
        client = HttpClient(self.options.username, self.options.password)
        client.verboseLevel = self.verboseLevel

        uri = util.MODULE_URL_PATH
        if self.module:
            uri += '/' + self.module

        url = self.options.endpoint + uri

        client.delete(url)
    def doWork(self):
        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        uri = util.MODULE_RESOURCE_PATH
        if self.module:
            uri += '/' + self.module

        url = self.options.endpoint + uri

        _, content = client.get(url)
        print(content)
Esempio n. 9
0
    def doWork(self):
        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        uri = util.USER_RESOURCE_PATH
        if self.user:
            uri += '/' + self.user

        url = self.options.endpoint + uri

        _, content = client.get(url)
        print(content)
Esempio n. 10
0
    def doWork(self):
        client = HttpClient(self.options.username, self.options.password)
        client.verboseLevel = self.verboseLevel

        uri = util.RUN_URL_PATH
        if self.run:
            uri += '/' + self.run

        url = self.options.endpoint + uri

        _, content = client.get(url)
        print(content)
    def doWork(self):

        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        self._retrieve_and_set_run(client)

        self._check_allowed_to_scale(client)

        self._set_scale_rtps(client)

        self._set_scale_state(client)
        self._set_run_provisioning(client)
    def doWork(self):

        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        self._retrieve_and_set_run(client)

        self._check_allowed_to_scale(client)

        self._set_scale_rtps(client)

        self._set_scale_state(client)
        self._set_run_provisioning(client)
    def test_unknown_http_return_code(self):
        client = HttpClient()
        client.verboseLevel = 0
        client.session = Mock()
        client.session.cookies = []
        resp = Mock(spec_set=requests.Response())
        resp.request = Mock()
        resp.request.headers = {}
        resp.status_code = 999
        client.session.request = Mock(return_value=resp)

        self.assertRaises(NetworkError, client.get, 'http://foo.bar',
                          retry=False)
Esempio n. 14
0
    def doWork(self):

        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        uri = util.RUN_RESOURCE_PATH + "/" + self.runId + "/" + self.nodeName
        url = self.options.endpoint + uri

        instances = str(self.instancesToRemove)[1:-1]
        self.log("Removing node instances: %s..." % instances)

        print(instances)
        client.delete(url, "ids=" + instances)
Esempio n. 15
0
    def test_init_session_login_apikey(self):
        ch = ConfigHolder()
        ch.context = {}
        ch.set('verboseLevel', 0)
        ch.set('cookie_filename', '/dev/null')
        ch.set('api_key', 'key')
        ch.set('api_secret', 'secret')

        client = HttpClient(ch)
        client.init_session('http://foo.bar')
        assert client.session is not None
        assert client.session.login_params
        assert 'key' in client.session.login_params
        assert 'secret' in client.session.login_params
    def testGetSetsCookie(self):

        httpRequestMock = Mock(return_value=(httplib2.Response({'set-cookie': 'acookie'}), ''))

        httpObjectMock = Mock()
        httpObjectMock.request = httpRequestMock

        mock = Mock(return_value=httpObjectMock)
        HttpClient._getHttpObject = mock

        client = HttpClient('username', 'password')
        client.get('http://localhost:9999/url')

        self.assertEqual('acookie', client.cookie)
Esempio n. 17
0
    def doWork(self):

        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        baseUri = util.RUN_RESOURCE_PATH + "/" + self.runId
        nodeUri = baseUri + "/" + self.nodeName
        url = self.options.endpoint + nodeUri

        self.log("Adding %s node instance(s) to node type %s..." %
                 (self.numberToAdd, self.nodeName))
        _, content = client.post(url, "n=" + str(self.numberToAdd))

        addedIds = NodeInstanceRuntimeParameter.parse_added_node_instances(
            content)

        url = self.options.endpoint + baseUri + '/'

        if self.numberToTolerate > 0:
            self.log("Setting max-provisioning-failures to %s on node %s..." %
                     (self.numberToTolerate, self.nodeName))
            runtime_param = self.nodeName + NodeDecorator.NODE_PROPERTY_SEPARATOR + \
                            NodeDecorator.MAX_PROVISIONING_FAILURES_KEY
            client.put(url + runtime_param, str(self.numberToTolerate))

        if self.runtimeParameters:
            for rp in self.runtimeParameters:
                name, values = NodeInstanceRuntimeParameter.parse_option_value(
                    rp)
                mapped = NodeInstanceRuntimeParameter.generate_mapping_index_name_value(
                    self.nodeName, name, values, addedIds)
                for k in mapped:
                    print(k, mapped[k])
                    client.put(url + k, mapped[k])
    def testUnknownHttpReturnCode(self):

        httpRequestMock = Mock(return_value=(httplib2.Response({'status': '999'}), ''))

        httpObjectMock = Mock()
        httpObjectMock.request = httpRequestMock

        mock = Mock(return_value=httpObjectMock)
        HttpClient._getHttpObject = mock

        client = HttpClient('username', 'password')
        client.cookie = 'acookie'

        self.assertRaises(NetworkError, client.get, 'url')
Esempio n. 19
0
    def test_init_session_login_internal(self):
        ch = ConfigHolder()
        ch.context = {}
        ch.set('verboseLevel', 0)
        ch.set('cookie_filename', '/dev/null')
        ch.set('username', 'foo')
        ch.set('password', 'bar')

        client = HttpClient(ch)
        client.init_session('http://foo.bar')
        assert client.session is not None
        assert client.session.login_params
        assert 'username' in client.session.login_params
        assert 'password' in client.session.login_params
    def test_init_session_login_apikey(self):
        ch = ConfigHolder()
        ch.context = {}
        ch.set('verboseLevel', 0)
        ch.set('cookie_filename', '/dev/null')
        ch.set('api_key', 'key')
        ch.set('api_secret', 'secret')

        client = HttpClient(ch)
        client.init_session('http://foo.bar')
        assert client.session is not None
        assert client.session.login_params
        assert 'key' in client.session.login_params
        assert 'secret' in client.session.login_params
    def test_init_session_login_internal(self):
        ch = ConfigHolder()
        ch.context = {}
        ch.set('verboseLevel', 0)
        ch.set('cookie_filename', '/dev/null')
        ch.set('username', 'foo')
        ch.set('password', 'bar')

        client = HttpClient(ch)
        client.init_session('http://foo.bar')
        assert client.session is not None
        assert client.session.login_params
        assert 'username' in client.session.login_params
        assert 'password' in client.session.login_params
Esempio n. 22
0
    def test_unknown_http_return_code(self):
        client = HttpClient()
        client.verboseLevel = 0
        client.session = Mock()
        client.session.cookies = []
        resp = Mock(spec_set=requests.Response())
        resp.request = Mock()
        resp.request.headers = {}
        resp.status_code = 999
        client.session.request = Mock(return_value=resp)

        self.assertRaises(NetworkError,
                          client.get,
                          'http://foo.bar',
                          retry=False)
    def __init__(self, configHolder):
        self.category = None
        self.run_dom = None
        self.ignoreAbort = False
        self.username = ''
        self.password = ''
        self.diid = ''
        self.node_instance_name = ''
        self.serviceurl = ''
        self.verboseLevel = None
        self.retry = True

        configHolder.assign(self)
        self._assemble_endpoints()
        self.httpClient = HttpClient(configHolder=configHolder)
        self.httpClient.init_session(self.serviceurl)
        self.api = self.httpClient.get_ss_api()
Esempio n. 24
0
    def doWork(self):

        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        baseUri = util.RUN_RESOURCE_PATH + "/" + self.runId
        nodeUri = baseUri + "/" + self.nodeName
        url = self.options.endpoint + nodeUri

        self.log("Adding %s node instance(s) to node type %s..." % (self.numberToAdd, self.nodeName))
        _, content = client.post(url, "n=" + str(self.numberToAdd))

        addedIds = NodeInstanceRuntimeParameter.parse_added_node_instances(content)

        url = self.options.endpoint + baseUri + '/'

        if self.numberToTolerate > 0:
            self.log("Setting max-provisioning-failures to %s on node %s..." %
                     (self.numberToTolerate, self.nodeName))
            runtime_param = self.nodeName + NodeDecorator.NODE_PROPERTY_SEPARATOR + \
                            NodeDecorator.MAX_PROVISIONING_FAILURES_KEY
            client.put(url + runtime_param, str(self.numberToTolerate))

        if self.runtimeParameters:
            for rp in self.runtimeParameters:
                name, values = NodeInstanceRuntimeParameter.parse_option_value(rp)
                mapped = NodeInstanceRuntimeParameter.generate_mapping_index_name_value(self.nodeName, name, values, addedIds)
                for k in mapped:
                    print(k, mapped[k])
                    client.put(url + k, mapped[k])
Esempio n. 25
0
    def doWork(self):
        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        dom = self.read_xml_and_exit_on_error(self.user)
        if not dom.tag in ('user'):
            sys.stderr.write('Invalid xml\n')
            sys.exit(-1)

        dom = self.read_xml_and_exit_on_error(self.user)
        attrs = SlipStreamHttpClient.DomExtractor.get_attributes(dom)

        user = attrs['name']
        uri = util.USER_RESOURCE_PATH + '/' + user

        url = self.options.endpoint + uri

        client.put(url, self.user)
    def testGetWithUsernamePassword(self):

        httpRequestMock = Mock(return_value=(httplib2.Response({}), ''))

        httpObjectMock = Mock()
        httpObjectMock.request = httpRequestMock

        mock = Mock(return_value=httpObjectMock)
        HttpClient._getHttpObject = mock

        client = HttpClient('username', 'password')
        client.get('url')

        args, kwargs = httpRequestMock.call_args

        self.assertEqual(('url', 'GET', None), args)

        self.assertTrue(kwargs['headers']['Authorization'].startswith('Basic '))
Esempio n. 27
0
    def doWork(self):
        client = HttpClient(self.options.username, self.options.password)
        client.verboseLevel = self.verboseLevel

        dom = self.read_xml_and_exit_on_error(self.user)
        if not dom.tag in ('user'):
            sys.stderr.write('Invalid xml\n')
            sys.exit(-1)

        dom = self.read_xml_and_exit_on_error(self.user)
        attrs = SlipStreamHttpClient.DomExtractor.getAttributes(dom)

        user = attrs['name']
        uri = util.USER_URL_PATH + '/' + user

        url = self.options.endpoint + uri

        client.put(url, self.user)
    def testGetWithCookie(self):

        httpRequestMock = Mock(return_value=(httplib2.Response({}), ''))

        httpObjectMock = Mock()
        httpObjectMock.request = httpRequestMock

        mock = Mock(return_value=httpObjectMock)
        HttpClient._getHttpObject = mock

        client = HttpClient()
        client.cookie = 'acookie'

        client.get('url')

        _, kwargs = httpRequestMock.call_args

        headers = kwargs['headers']
        self.assertEqual(headers['cookie'], 'acookie')
    def test_post_with_data(self):
        ch = ConfigHolder()
        ch.context = {}
        ch.set('verboseLevel', 0)
        ch.set('cookie_filename', '/dev/null')
        ch.set('api_key', 'key')
        ch.set('api_secret', 'secret')
        client = HttpClient(ch)
        resp = requests.Response()
        resp.status_code = 200
        resp.get = Mock(return_value=None)
        resp.request = Mock()
        resp.request.headers = {}
        requests.sessions.Session.send = Mock(return_value=resp)

        client.post('http://example.com', 'a=b\nc=d')

        args, kwargs = requests.sessions.Session.send.call_args
        self.assertEqual(len(args), 1)
        req = args[0]
        self.assertEqual(req.body, 'a=b\nc=d')
Esempio n. 30
0
    def doWork(self):
        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        dom = self.read_xml_and_exit_on_error(self.module)
        attrs = SlipStreamHttpClient.DomExtractor.get_attributes(dom)

        root_node_name = dom.tag
        if root_node_name == 'list':
            sys.stderr.write('Cannot update root project\n')
            sys.exit(-1)
        if not dom.tag in ('imageModule', 'projectModule', 'deploymentModule'):
            sys.stderr.write('Invalid xml\n')
            sys.exit(-1)

        parts = [attrs['parentUri'], attrs['shortName']]
        uri = '/' + '/'.join([part.strip('/') for part in parts])

        url = self.options.endpoint + uri

        client.put(url, self.module)
Esempio n. 31
0
    def doWork(self):
        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        dom = self.read_xml_and_exit_on_error(self.module)
        attrs = SlipStreamHttpClient.DomExtractor.get_attributes(dom)

        root_node_name = dom.tag
        if root_node_name == 'list':
            sys.stderr.write('Cannot update root project\n')
            sys.exit(-1)
        if not dom.tag in ('imageModule', 'projectModule', 'deploymentModule'):
            sys.stderr.write('Invalid xml\n')
            sys.exit(-1)

        parts = [attrs['parentUri'], attrs['shortName']]
        uri = '/' + '/'.join([part.strip('/') for part in parts])

        url = self.options.endpoint + uri

        client.put(url, self.module)
    def test_init_session_fail_no_creds(self):
        ch = ConfigHolder()
        ch.context = {}
        ch.set('verboseLevel', 0)
        ch.set('cookie_filename', '/dev/null')

        client = HttpClient(ch)
        client.init_session('http://foo.bar')
        assert client.session is not None
        assert client.session.login_params == {}
        resp = Mock(spec=Response)
        resp.status_code = 403
        resp.cookies = None
        resp.headers = {}
        client.session._request = Mock(return_value=resp)
        client.session.cimi_login = Mock(return_value=resp)
        try:
            client.get('http://foo.bar', retry=False)
        except Exception as ex:
            assert ex.code == 403
        assert client.session.cimi_login.called is True
Esempio n. 33
0
    def test_post_with_data(self):
        ch = ConfigHolder()
        ch.context = {}
        ch.set('verboseLevel', 0)
        ch.set('cookie_filename', '/dev/null')
        ch.set('api_key', 'key')
        ch.set('api_secret', 'secret')
        client = HttpClient(ch)
        resp = requests.Response()
        resp.status_code = 200
        resp.get = Mock(return_value=None)
        resp.request = Mock()
        resp.request.headers = {}
        requests.sessions.Session.send = Mock(return_value=resp)

        client.post('http://example.com', 'a=b\nc=d')

        args, kwargs = requests.sessions.Session.send.call_args
        self.assertEqual(len(args), 1)
        req = args[0]
        self.assertEqual(req.body, 'a=b\nc=d')
    def doWork(self):

        if self.options.remove_clouds and sys.version_info[0:3] < (2, 7, 0):
            print(
                'Error: The use of "--remove-cloud-specific" require Python >= 2.7',
                file=sys.stderr)
            sys.exit(1)

        client = HttpClient()
        client.verboseLevel = self.verboseLevel

        queue = [self.module]
        while len(queue) > 0:
            module = queue.pop(0)
            print('Processing: %s' % module)

            try:

                root = self._retrieveModuleAsXml(client, module)
                self._remove_transient_elements(root)
                if self._is_image(root) and self.options.dump_image_ids:
                    self._dump_image_ids(root)
                if self.options.remove_clouds:
                    self._remove_clouds(root)
                if self.options.remove_group_members:
                    self._remove_group_members(root)
                if self.options.reset_commit_message:
                    self._reset_commit_message(root)
                self._writeModuleAsXml(root, module)

                for child in self._getModuleChildren(module, root):
                    queue.append(child)

            except Exception as e:
                print(e)
                if not self.options.continue_on_error:
                    sys.exit(1)
Esempio n. 35
0
    def test_init_session_fail_no_creds(self):
        ch = ConfigHolder()
        ch.context = {}
        ch.set('verboseLevel', 0)
        ch.set('cookie_filename', '/dev/null')

        client = HttpClient(ch)
        client.init_session('http://foo.bar')
        assert client.session is not None
        assert client.session.login_params == {}
        resp = Mock(spec=Response)
        resp.status_code = 403
        resp.cookies = None
        resp.headers = {}
        client.session._request = Mock(return_value=resp)
        client.session.cimi_login = Mock(return_value=resp)
        try:
            client.get('http://foo.bar', retry=False)
        except Exception as ex:
            assert ex.code == 403
        assert client.session.cimi_login.called is True
    def testCookieHeaderSet(self):

        client = HttpClient(cookie='acookie')
        headers = client._createAuthenticationHeader()

        self.assertEqual('acookie', headers['cookie'])
class SlipStreamHttpClient(object):
    URL_IGNORE_ABORT_ATTRIBUTE_QUERY = '?ignoreabort=true'

    def __init__(self, configHolder):
        self.category = None
        self.run_dom = None
        self.ignoreAbort = False
        self.username = ''
        self.password = ''
        self.diid = ''
        self.node_instance_name = ''
        self.serviceurl = ''
        self.verboseLevel = None
        self.retry = True

        configHolder.assign(self)
        self._assemble_endpoints()
        self.httpClient = HttpClient(configHolder=configHolder)
        self.httpClient.init_session(self.serviceurl)
        self.api = self.httpClient.get_ss_api()

    def set_retry(self, retry):
        self.retry = retry

    def _assemble_endpoints(self):
        self.runEndpoint = self.serviceurl + util.RUN_RESOURCE_PATH
        self.run_url = self.runEndpoint + '/' + self.diid

        self.userEndpoint = '%s/user/%s' % (self.serviceurl,
                                            self.username)

        self.configuration_endpoint = '%s%s' % (self.serviceurl,
                                                util.CONFIGURATION_RESOURCE_PATH)

    @staticmethod
    def _strip_unwanted_attrs(resource):
        unwanted = ('id', 'resourceURI', 'acl', 'operations',
                    'created', 'updated', 'name', 'description', 'properties')
        for k in resource.keys():
            if k in unwanted:
                del resource[k]
        return resource

    def _get_user(self):
        _, jresp = self.httpClient.get(self.serviceurl + '/api/user/%s' % self.username,
                                       accept='application/json')
        return self._strip_unwanted_attrs(json.loads(jresp))

    def _get_user_params(self):
        _, jresp = self.httpClient.get(self.serviceurl + '/api/user-param',
                                       accept='application/json')
        user_params = json.loads(jresp)
        if user_params.get('count', 0) < 1:
            raise Exception('No user params found for %s.' % self.username)
        return self._strip_unwanted_attrs(user_params.get('userParam')[0])

    def _get_cloud_cred(self, cloud_qualifier):
        creds = self._get_cloud_creds(cloud_qualifier)
        cred = self._strip_unwanted_attrs(creds.get('credentials')[0])
        cred[UserInfo.CLOUD_USERNAME_KEY] = cred.get('key', '')
        cred[UserInfo.CLOUD_PASSWORD_KEY] = cred.get('secret', '')
        return cred

    def _get_cloud_creds(self, cloud_qualifier):
        _filter = "$filter=type^='cloud-cred' and connector/href='connector/%s'" % \
                  cloud_qualifier
        _, jresp = self.httpClient.put(self.serviceurl + '/api/credential?%s' % _filter,
                                       accept='application/json')
        creds = json.loads(jresp)
        if creds.get('count', 0) < 1:
            raise Exception('No cloud creds found for %s with %s.' % (self.username, _filter))
        return creds

    def _get_connector_conf(self, cloud_qualifier):
        _, jresp = self.httpClient.get(self.serviceurl + '/api/connector/%s' % cloud_qualifier,
                                       accept='application/json')
        return self._strip_unwanted_attrs(json.loads(jresp))

    def get_user_info(self, cloud_qualifier):

        user_info = UserInfo(cloud_qualifier)

        user = self._get_user()
        if 'password' in user:
            del user['password']
        user_info.set_user_params(user)

        user_info.set_general_params(self._get_user_params())

        if cloud_qualifier:
            connector_conf = self._get_connector_conf(cloud_qualifier)
            connector_conf.update(self._get_cloud_cred(cloud_qualifier))
            user_info.set_cloud_params(connector_conf)

        return user_info

    def _extractModuleResourceUri(self, run):
        rootElement = etree.fromstring(run.encode('utf-8'))
        return rootElement.attrib[NodeDecorator.MODULE_RESOURCE_URI]

    def get_nodes_instances(self, cloud_service_name=None):
        '''Return dict {<node_instance_name>: NodeInstance, }
        '''
        nodes_instances = {}

        self._retrieveAndSetRun()

        nodes_instances_runtime_parameters = \
            DomExtractor.extract_nodes_instances_runtime_parameters(self.run_dom, cloud_service_name)

        nodes_runtime_parameters = DomExtractor.extract_nodes_runtime_parameters(self.run_dom)

        for node_instance_name, node_instance_runtime_parameters in nodes_instances_runtime_parameters.items():

            node_instance = NodeInstance(node_instance_runtime_parameters)
            node_name = node_instance.get_node_name()

            if nodes_runtime_parameters:
                node_runtime_parameters = nodes_runtime_parameters.get(node_name, {})
                if node_runtime_parameters:
                    node_instance.set_parameter(NodeDecorator.MAX_PROVISIONING_FAILURES_KEY,
                        node_runtime_parameters.get(NodeDecorator.MAX_PROVISIONING_FAILURES_KEY, '0'))

            image_attributes = DomExtractor.extract_node_image_attributes(self.run_dom, node_name)
            node_instance.set_image_attributes(image_attributes)

            image_targets = DomExtractor.extract_node_image_targets(self.run_dom, node_name)
            node_instance.set_image_targets(image_targets)

            build_state = DomExtractor.extract_node_image_build_state(self.run_dom, node_name)
            node_instance.set_build_state(build_state)

            nodes_instances[node_instance_name] = node_instance

        return nodes_instances

    def _get_nodename(self):
        'Node name derived from the node instance name.'
        return self.node_instance_name.split(
            NodeDecorator.NODE_MULTIPLICITY_SEPARATOR)[0]

    def get_run_category(self):
        self._retrieveAndSetRun()
        return DomExtractor.extractCategoryFromRun(self.run_dom)

    def get_run_type(self):
        self._retrieveAndSetRun()
        return DomExtractor.extractTypeFromRun(self.run_dom)

    def get_run_mutable(self):
        self._retrieveAndSetRun()
        return DomExtractor.extract_mutable_from_run(self.run_dom)

    def discard_run(self):
        self.run_dom = None

    def _retrieveAndSetRun(self):
        if self.run_dom is None:
            url = self.run_url
            _, run = self._retrieve(url)
            self.run_dom = etree.fromstring(run.encode('utf-8'))

    def _retrieve(self, url):
        return self._httpGet(url, 'application/xml')

    def execute(self, resourceUri):
        url = self.runEndpoint
        return self._httpPost(url, resourceUri, 'text/plain')

    def complete_state(self, node_instance_name):
        url = '%s/%s:%s' % (self.run_url, node_instance_name,
                            NodeDecorator.COMPLETE_KEY)
        url += SlipStreamHttpClient.URL_IGNORE_ABORT_ATTRIBUTE_QUERY
        return self._httpPost(url, 'reset', 'text/plain')

    def terminate_run(self):
        return self._httpDelete(self.run_url)

    def _fail(self, message):
        self.setRuntimeParameter(
            NodeDecorator.globalNamespacePrefix + NodeDecorator.ABORT_KEY, message)

    def sendReport(self, report):
        resource_id = self._create_external_object_report(report)
        upload_url = self._generate_upload_url_external_object_report(resource_id)
        self._upload_report(upload_url, report)
        self._set_report_ready(resource_id)

    def _create_external_object_report(self, report_path):
        resp = self.api.cimi_add('externalObjects',
                                 {'externalObjectTemplate': {'href': 'external-object-template/report',
                                                             'runUUID': self.diid,
                                                             'component': self.node_instance_name,
                                                             'filename': os.path.basename(report_path),
                                                             'contentType': 'application/tar+gzip'}})
        return resp.json['resource-id']

    def _generate_upload_url_external_object_report(self, resource_id):
        resp = self.api.cimi_operation(resource_id, "http://sixsq.com/slipstream/1/action/upload")
        return resp.json['uri']

    def _upload_report(self, url, report):
        self._printDetail('Uploading report to: %s' % url)
        body = open(report, 'rb').read()
        self._httpPut(url, body, 'application/tar+gzip', accept="*/*")

    def _set_report_ready(self, resource_id):
        self.api.cimi_operation(resource_id, "http://sixsq.com/slipstream/1/action/ready")

    def isAbort(self):
        return self.getGlobalAbortMessage() != ''

    def getGlobalAbortMessage(self):
        url = '%s/%s%s' % (self.run_url,
                           NodeDecorator.globalNamespacePrefix,
                           NodeDecorator.ABORT_KEY)
        url += SlipStreamHttpClient.URL_IGNORE_ABORT_ATTRIBUTE_QUERY
        _, content = self._httpGet(url, accept='text/plain')
        return content.strip().strip('"').strip("'")

    def get_run_parameters(self):
        self._retrieveAndSetRun()
        return DomExtractor.extract_run_parameters_from_run(self.run_dom)

    def getRuntimeParameter(self, key, ignoreAbort=False):

        url = self.run_url + '/' + key
        if self.ignoreAbort or ignoreAbort:
            url += SlipStreamHttpClient.URL_IGNORE_ABORT_ATTRIBUTE_QUERY
        try:
            _, content = self._httpGet(url, accept='text/plain')
        except Exceptions.NotFoundError as ex:
            raise Exceptions.NotFoundError('"%s" for %s' % (str(ex), key))

        return content.strip().strip('"').strip("'")

    def setRuntimeParameter(self, key, value, ignoreAbort=False):
        url = self.run_url + '/' + key
        if self.ignoreAbort or ignoreAbort:
            url += SlipStreamHttpClient.URL_IGNORE_ABORT_ATTRIBUTE_QUERY

        _, content = self._httpPut(url, util.removeASCIIEscape(value),
                                   accept='text/plain')

        return content.strip().strip('"').strip("'")

    def unset_runtime_parameter(self, key, ignore_abort=False):
        url = '%s/%s' % (self.run_url, key)

        if (self.ignoreAbort or ignore_abort):
            url += SlipStreamHttpClient.URL_IGNORE_ABORT_ATTRIBUTE_QUERY

        self._httpDelete(url)

    def _httpGet(self, url, accept='application/xml'):
        return self.httpClient.get(url, accept, retry=self.retry)

    def _httpPut(self, url, body=None, contentType='application/xml', accept='application/xml'):
        return self.httpClient.put(url, body, contentType, accept, retry=self.retry)

    def _httpPost(self, url, body=None, contentType='application/xml'):
        return self.httpClient.post(url, body, contentType, retry=self.retry)

    def _httpDelete(self, url, body=None):
        return self.httpClient.delete(url, body=body, retry=self.retry)

    def _printDetail(self, message):
        util.printDetail(message, self.verboseLevel, util.VERBOSE_LEVEL_DETAILED)

    def put_new_image_id(self, image_resource_uri, image_id):
        url = self.serviceurl + '/' + image_resource_uri
        self._printDetail('Set new image id: %s %s' % (url, image_id))
        self._httpPut(url, image_id)

    def launchDeployment(self, params):
        body = '&'.join(params)
        resp, _ = self._httpPost(self.runEndpoint, body,
                                 contentType='text/plain')
        return resp.headers['location']

    def getRunState(self, uuid=None, ignoreAbort=True):
        if not uuid and not self.diid:
            raise Exceptions.ExecutionException("Run ID should be provided "
                                                "to get state.")
        state_key = NodeDecorator.globalNamespacePrefix + NodeDecorator.STATE_KEY
        self.run_url = self.runEndpoint + '/' + (uuid or self.diid)
        return self.getRuntimeParameter(state_key, ignoreAbort=ignoreAbort)

    def remove_instances_from_run(self, node_name, ids, detele_ids_only=True):
        """ids : []
        """
        url = '%s/%s' % (self.run_url, node_name)
        body = "ids=%s" % ','.join(map(str, ids))
        if detele_ids_only:
            body = body + '&delete-ids-only=true'
        self._httpDelete(url, body=body)

    def get_server_configuration(self):
        _, config = self._retrieve(self.configuration_endpoint)
        return config

    def login(self, username, password):
        self.api.login_internal(username=username, password=password)

    def logout(self):
        self.api.logout()

    def get_session(self):
        return self.httpClient.get_session()

    def get_api(self):
        return self.api
    def testBasicAuthenticationHeaderSet(self):

        client = HttpClient('username', 'password')
        headers = client._createAuthenticationHeader()

        self.assertTrue(headers['Authorization'].startswith('Basic '))