def upgrade(self): etag = generate_etag() Printer.start_test("Update plan") # CHECK: Plan upgrade succeeds (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s/resources/%s/%s" % ( self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"]), 'PUT', xmlutil.xml_for_create_resource( plan=self.config['upgrade_plan'], resource_type=self.config['resource_type'], promotion_code=self.config['promo_code'], etag=etag ), validate_xml=True ) if status in [200, 201]: Printer.success("Upgrade Resource succeeded.") Printer.info("Checking XML") else: Printer.error("Upgrade Resource failed with HTTP status code %s" % status) return t = xmlutil.get_subtree_from_xml_string(response) self._validate_resource_response(etag, t) Printer.info("Checking if new plan is %s" % self.config['upgrade_plan']) self._check_node_value(t, './{0}Plan', self.config['upgrade_plan'])
def upgrade(self): etag = generate_etag() Printer.start_test("Update plan") # CHECK: Plan upgrade succeeds (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s/resources/%s/%s" % (self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"]), 'PUT', xmlutil.xml_for_create_resource( plan=self.config['upgrade_plan'], resource_type=self.config['resource_type'], promotion_code=self.config['promo_code'], etag=etag), validate_xml=True) if status in [200, 201]: Printer.success("Upgrade Resource succeeded.") Printer.info("Checking XML") else: Printer.error("Upgrade Resource failed with HTTP status code %s" % status) return t = xmlutil.get_subtree_from_xml_string(response) self._validate_resource_response(etag, t) Printer.info("Checking if new plan is %s" % self.config['upgrade_plan']) self._check_node_value(t, './{0}Plan', self.config['upgrade_plan'])
def _check_node_value(self, t, xpath, expected): try: actual = xmlutil.get_node_value(t, xpath) if actual != expected: Printer.error("Node at XPath %s has actual value %s, expected value %s" % (xpath, actual, expected)) except NodeNotFoundException: Printer.error("Node at XPath %s was not found in the response" % xpath)
def read_config(): resources.init("Microsoft", "Dukaan") contents = resources.user.read('config.ini') if contents: d = json.loads(contents) for k in d: config[k] = d[k] else: Printer.info("Configuration is empty. Run 'dukaan init' to save common settings to configuration file.")
def _check_node_exists(self, t, xpath, behavior="error"): try: xmlutil.node_exists(t, xpath) except NodeNotFoundException: msg = "XPath %s was not found in the response" % xpath if behavior == "error": Printer.error(msg) else: Printer.warn(msg)
def _check_node_value(self, t, xpath, expected): try: actual = xmlutil.get_node_value(t, xpath) if actual != expected: Printer.error( "Node at XPath %s has actual value %s, expected value %s" % (xpath, actual, expected)) except NodeNotFoundException: Printer.error("Node at XPath %s was not found in the response" % xpath)
def _check_node_exists(self, t, xpath, behavior="error"): try: xmlutil.node_exists(t, xpath) return True except NodeNotFoundException: msg = "XPath %s was not found in the response" % xpath if behavior == "error": Printer.error(msg) else: Printer.warn(msg) return False
def get_resource(self): Printer.start_test("Get Resource") (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s/resources/%s/%s" % ( self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"], ), "GET", None, validate_xml=True, ) if status in [200, 201]: Printer.success("Get resource succeeded.") Printer.info("Checking XML") else: Printer.error("Get resource failed with HTTP status code %s" % status) return t = xmlutil.get_subtree_from_xml_string(response) self._validate_resource_response(None, t)
def validate_config(): required = { 'create': ['resource_provider_namespace', 'resource_type', 'subscription_id', 'resource_name', 'purchase_plan'], 'show': ['resource_provider_namespace', 'resource_type', 'subscription_id', 'resource_name'], 'delete': ['resource_provider_namespace', 'resource_type', 'subscription_id', 'resource_name'], 'upgrade': ['resource_provider_namespace', 'resource_type', 'subscription_id', 'resource_name', 'upgrade_plan'], 'sso': ['resource_provider_namespace', 'resource_type', 'subscription_id', 'resource_name'], 'manifest': [] } missing = map( lambda x: x.replace("_", "-"), ["--" + k for k in required[config['command']] if k not in config] ) if missing: Printer.error("The following flags are required for this command: %s" % string.join(missing, ', ')) utility.die()
def manifest(self): errors, warnings, manifest_config = xmlutil.parse_manifest(self.config['manifest_path']) if errors or warnings: Printer.start_test('Checking manifest') for error in errors: Printer.error("Manifest: %s" % error) for warning in warnings: Printer.warn("Manifest: %s" % warning)
def run_checks(): if 'manifest_path' in config: manifest_path = config['manifest_path'] else: manifest_path = os.path.join(os.getcwdu(), "manifest.xml") config['manifest_path'] = manifest_path try: with open(manifest_path) as f: pass except IOError as e: Printer.error("Manifest file %s could not be opened" % (manifest_path)) utility.die() validator = Validator(config) dispatch = { 'create': validator.create, 'show': validator.get_cloud_service, 'delete': validator.delete, 'upgrade': validator.upgrade, 'manifest': validator.manifest, 'sso': validator.sso, } dispatch[config['command']]()
def manifest(self): errors, warnings, manifest_config = xmlutil.parse_manifest( self.config['manifest_path']) if errors or warnings: Printer.start_test('Checking manifest') for error in errors: Printer.error("Manifest: %s" % error) for warning in warnings: Printer.warn("Manifest: %s" % warning)
def get_resource(self): Printer.start_test("Get Resource") (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s/resources/%s/%s" % (self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"]), "GET", None, validate_xml=True) if status in [200, 201]: Printer.success("Get resource succeeded.") Printer.info("Checking XML") else: Printer.error("Get resource failed with HTTP status code %s" % status) return t = xmlutil.get_subtree_from_xml_string(response) self._validate_resource_response(None, t)
def delete(self): etag = generate_etag() Printer.start_test("Delete Resource") (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s/resources/%s/%s" % (self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"]), 'DELETE', None) if status in [200, 201]: Printer.success("Delete Resource succeeded.") else: Printer.error("Delete Resource failed with HTTP status code %s" % status) return
def delete(self): etag = generate_etag() Printer.start_test("Delete Resource") (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s/resources/%s/%s" % ( self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"]), 'DELETE', None ) if status in [200, 201]: Printer.success("Delete Resource succeeded.") else: Printer.error("Delete Resource failed with HTTP status code %s" % status) return
def perform_request(self, uri, method, body, uri_type='base', validate_xml=True, timeout=20.0): full_url = urlparse.urljoin( self.base_uri, uri) if uri_type == 'base' else urlparse.urljoin( self.sso_uri, uri) dispatch = { 'GET': requests.get, 'PUT': requests.put, 'POST': requests.post, 'DELETE': requests.delete } Printer.info("%s on %s" % (method, full_url)) try: if method in ['PUT', 'POST']: result = dispatch[method](full_url, body, headers=self.headers) elif method in ['GET', 'DELETE']: result = dispatch[method](full_url, headers=self.headers) except requests.exceptions.ConnectionError as e: Printer.error("Could not %s on %s. Error: %s" % (method, full_url, e.message[1])) die() except requests.exceptions.Timeout as e: Printer.error("%s on %s timed out." % (method, full_url)) die() Printer.info("Server returned HTTP status code %s" % result.status_code) if result.content and validate_xml: try: t = xmlutil.get_root_element( xmlutil.get_subtree_from_xml_string(result.content)) except Exception as e: Printer.error( "Could not parse response as XML. Check for mismatched tags or missing XML header. Error: %s" % e.message) die() try: xmlutil.check_tags_alpha_ordered(t) except xmlutil.TagOrderingException as e: Printer.error( "Tags in response have to be alphabetically sorted. These tags are not alphabetically-sorted: %s" % e.message) die() return (result.status_code, result.content)
def perform_request(self, uri, method, body, uri_type='base', validate_xml=True, timeout=20.0): full_url = urlparse.urljoin(self.base_uri,uri) if uri_type == 'base' else urlparse.urljoin(self.sso_uri,uri) dispatch = { 'GET': requests.get, 'PUT': requests.put, 'POST': requests.post, 'DELETE': requests.delete } Printer.info("%s on %s" % (method, full_url)) try: if method in ['PUT','POST']: result = dispatch[method](full_url, body, headers=self.headers) elif method in ['GET', 'DELETE']: result = dispatch[method](full_url, headers=self.headers) except requests.exceptions.ConnectionError as e: Printer.error("Could not %s on %s. Error: %s" % (method, full_url, e.message[1])) die() except requests.exceptions.Timeout as e: Printer.error("%s on %s timed out." % (method, full_url)) die() Printer.info("Server returned HTTP status code %s" % result.status_code) if result.content and validate_xml: try: t = xmlutil.get_root_element(xmlutil.get_subtree_from_xml_string(result.content)) except Exception as e: Printer.error("Could not parse response as XML. Check for mismatched tags or missing XML header. Error: %s" % e.message) die() try: xmlutil.check_tags_alpha_ordered(t) except xmlutil.TagOrderingException as e: Printer.error("Tags in response have to be alphabetically sorted. These tags are not alphabetically-sorted: %s" % e.message) die() return (result.status_code, result.content)
def _validate_resource_response(self, etag, t): root_node_expected_tag = xmlutil.get_root_tag(t) Printer.info("Checking if root node's tag is %s" % root_node_expected_tag) root_node_actual_tag = xmlutil.get_root_tag(t) if (root_node_expected_tag != root_node_actual_tag): Printer.error("Root node does not have expected tag %s" % root_node_expected_tag) Printer.info("Checking if xmlns is correct") xmlns_actual = xmlutil.get_xmlns(t) xmlns_expected = "http://schemas.datacontract.org/2004/07/Microsoft.Cis.DevExp.Services.Rdfe.ServiceManagement" if not xmlns_actual: Printer.error("Missing xmlns tag") if xmlns_actual != xmlns_expected: Printer.error("xmlns in response body is not correct. Expected: %s, Actual: %s" % (xmlns_expected, xmlns_actual)) Printer.info("Checking if CloudServiceSettings are present") self._check_node_exists(t, './{0}CloudServiceSettings') if etag: Printer.info("Checking if ETag is %s" % etag) self._check_node_value(t, './{0}ETag', etag) Printer.info("Checking if Name is %s" % self.config['resource_name']) self._check_node_value(t, './{0}Name', self.config['resource_name']) Printer.info("Checking if OperationStatus/Result is 'Succeeded'") self._check_node_value(t, './{0}OperationStatus/{0}Result', "Succeeded") Printer.info("Checking if OutputItems are present") # warn if OutputItems are not returned if self._check_node_exists(t, './{0}OutputItems', behavior='warn'): output_items = t.findall('.//{0}OutputItem'.format(xmlutil.get_namespace(t))) # check that no. of OutputItems are turned is equal to no. of OutputItems defined in manifest if len(output_items) != len(self.config['manifest']['output_keys']): Printer.error( "Your response contains a different number of OutputItems (%s) than is defined in the manifest (%s)." % ( len(output_items), len(self.config['manifest']['output_keys']) ) ) for output_item in output_items: output_item_tree = xmlutil.get_subtree_from_element(output_item) # warn if Key node is not present if self._check_node_exists(output_item_tree, './{0}Key'): output_item_key = self._get_node_value(output_item_tree, './{0}Key') Printer.info("Checking if OutputItem '%s' is present in manifest and cased properly" % output_item_key) # warn if OutputItem is not defined in manifest if output_item_key not in self.config['manifest']['output_keys']: Printer.error("OutputItem '%s' not found in manifest. Make sure it is cased properly in your response and defined in the manifest" % output_item_key) # warn if Value node is not present self._check_node_exists(output_item_tree, './{0}Value') Printer.info("Checking if UsageMeters are present") if self._check_node_exists(t, './{0}UsageMeters', behavior='warn'): usage_meters = xmlutil.get_nodes(t, './/{0}UsageMeter') for usage_meter in usage_meters: usage_meter_tree = xmlutil.get_subtree_from_element(usage_meter) self._check_node_exists(usage_meter_tree, './{0}Included') self._check_node_exists(usage_meter_tree, './{0}Name') if self._check_node_exists(usage_meter_tree, './{0}Unit', behavior='warn'): meter_name = self._get_node_value(usage_meter_tree, './{0}Unit') allowed_meter_names = ['bytes', 'hours', 'generic'] if meter_name not in allowed_meter_names: Printer.error("Usage Meter '%s' is not one of allowed values: %s" % (meter_name, string.join(allowed_meter_names, ', '))) self._check_node_exists(usage_meter_tree, './{0}Used') Printer.info("Checking if Plan is present") self._check_node_exists(t, './{0}Plan') Printer.info("Checking if State is 'Started'") self._check_node_value(t, './{0}State', "Started") Printer.info("Checking if Type is '%s'" % self.config["resource_type"]) self._check_node_value(t, './{0}Type', self.config["resource_type"])
def sso(self): Printer.start_test("SSO with valid timestamp and token") (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s/resources/%s/%s/SsoToken" % (self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"]), "POST", None, validate_xml=True) if status in [200, 201]: Printer.success("SSO token request succeeded.") Printer.info("Checking XML") else: Printer.error("SSO token request failed with HTTP status code %s" % status) return t = xmlutil.get_subtree_from_xml_string(response) self._check_node_exists(t, "./{0}SsoToken/TimeStamp") self._check_node_exists(t, "./{0}SsoToken/Token") fragment = urllib.urlencode({ "token": xmlutil.get_node_value(t, "./{0}Token"), "timestamp": xmlutil.get_node_value(t, "./{0}TimeStamp") }) (status, response) = self.client.perform_request( "?subid=%s&cloudservicename=%s&resourcetype=%s&resourcename=%s&%s" % (self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"], fragment), "GET", None, uri_type="sso", validate_xml=False) if status in [200, 201]: Printer.success("SSO login succeeded.") else: Printer.error("SSO login request failed with HTTP status code %s" % status) return Printer.start_test("SSO with expired timestamp") given_timestamp = iso8601.parse_date( xmlutil.get_node_value(t, "./{0}TimeStamp")) expired_timestamp = given_timestamp + timedelta(seconds=60 * 10) fragment = urllib.urlencode({ "token": xmlutil.get_node_value(t, "./{0}Token"), "timestamp": str(expired_timestamp) }) (status, response) = self.client.perform_request( "sso?subid=%s&cloudservicename=%s&resourcetype=%s&resourcename=%s&%s" % (self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"], fragment), "GET", None, uri_type="sso", validate_xml=False) if status in [200, 201]: Printer.error("SSO login with expired timestamp succeeded.") else: Printer.success( "SSO login with expired timestamp failed with error code %s" % status) return
def create(self): etag = generate_etag() Printer.start_test("Create resource") (status, response) = self.client.perform_request( "subscriptions/%s/Events" % self.config['subscription_id'], 'POST', xmlutil.xml_for_subscription_event( self.config["subscription_id"], self.config["resource_provider_namespace"], self.config["resource_type"], "Registered")) # CHECK: Subscription Register event succeeds if status in [200, 201]: Printer.success("Subscription register event succeeded") else: Printer.error( "Subscription register event failed with HTTP status code %s" % status) return # CHECK: Resource creation succeeds (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s/resources/%s/%s" % (self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"]), 'PUT', xmlutil.xml_for_create_resource( plan=self.config['purchase_plan'], resource_type=self.config['resource_type'], promotion_code=self.config['promo_code'], etag=etag)) if status in [200, 201]: Printer.success("Resource creation succeeded") Printer.info("Checking XML") else: Printer.error( "Resource creation event failed with HTTP status code %s" % status) t = xmlutil.get_subtree_from_xml_string(response) self._validate_resource_response(etag, t)
def create(self): etag = generate_etag() Printer.start_test("Create resource") (status, response) = self.client.perform_request( "subscriptions/%s/Events" % self.config['subscription_id'], 'POST', xmlutil.xml_for_subscription_event( self.config["subscription_id"], self.config["resource_provider_namespace"], self.config["resource_type"], "Registered" ) ) # CHECK: Subscription Register event succeeds if status in [200, 201]: Printer.success("Subscription register event succeeded") else: Printer.error("Subscription register event failed with HTTP status code %s" % status) return # CHECK: Resource creation succeeds (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s/resources/%s/%s" % ( self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"]), 'PUT', xmlutil.xml_for_create_resource( plan=self.config['purchase_plan'], resource_type=self.config['resource_type'], promotion_code=self.config['promo_code'], etag=etag ) ) if status in [200,201]: Printer.success("Resource creation succeeded") Printer.info("Checking XML") else: Printer.error("Resource creation event failed with HTTP status code %s" % status) t = xmlutil.get_subtree_from_xml_string(response) self._validate_resource_response(etag, t)
def sso(self): Printer.start_test("SSO with valid timestamp and token") (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s/resources/%s/%s/SsoToken" % ( self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"] ), "POST", None, validate_xml=True ) if status in [200, 201]: Printer.success("SSO token request succeeded.") Printer.info("Checking XML") else: Printer.error("SSO token request failed with HTTP status code %s" % status) return t = xmlutil.get_subtree_from_xml_string(response) self._check_node_exists(t, "./{0}SsoToken/TimeStamp") self._check_node_exists(t, "./{0}SsoToken/Token") fragment = urllib.urlencode( { "token": xmlutil.get_node_value(t, "./{0}Token"), "timestamp": xmlutil.get_node_value(t, "./{0}TimeStamp") } ) (status, response) = self.client.perform_request( "?subid=%s&cloudservicename=%s&resourcetype=%s&resourcename=%s&%s" % ( self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"], fragment ), "GET", None, uri_type="sso", validate_xml=False ) if status in [200, 201]: Printer.success("SSO login succeeded.") else: Printer.error("SSO login request failed with HTTP status code %s" % status) return Printer.start_test("SSO with expired timestamp") given_timestamp = iso8601.parse_date(xmlutil.get_node_value(t, "./{0}TimeStamp")) expired_timestamp = given_timestamp + timedelta(seconds=60*10) fragment = urllib.urlencode( { "token": xmlutil.get_node_value(t, "./{0}Token"), "timestamp": str(expired_timestamp) } ) (status, response) = self.client.perform_request( "sso?subid=%s&cloudservicename=%s&resourcetype=%s&resourcename=%s&%s" % ( self.config["subscription_id"], self.config["cloud_service_name"], self.config["resource_type"], self.config["resource_name"], fragment ), "GET", None, uri_type="sso", validate_xml=False ) if status in [200, 201]: Printer.error("SSO login with expired timestamp succeeded.") else: Printer.success("SSO login with expired timestamp failed with error code %s" % status) return
def get_cloud_service(self): Printer.start_test("Get CloudService") (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s" % ( self.config["subscription_id"], self.config["cloud_service_name"] ), "GET", None, validate_xml=True ) if status in [200, 201]: Printer.success("Get CloudService succeeded.") Printer.info("Checking XML") else: Printer.error("Get CloudService failed with HTTP status code %s" % status) return t = xmlutil.get_subtree_from_xml_string(response) root_node_expected_tag = '{0}CloudService'.format(xmlutil.get_namespace(t)) root_node_actual_tag = xmlutil.get_root_tag(t) if (root_node_expected_tag != root_node_actual_tag): Printer.error("Root node does not have expected tag %s" % root_node_expected_tag) return resource_names = map(lambda t: t.text, xmlutil.get_nodes(t, ".//{0}Resource/{0}Name")) if self.config['resource_name'] not in resource_names: Printer.error("Resource named '%s' not returned by endpoint" % self.config['resource_name'])
def _validate_resource_response(self, etag, t): root_node_expected_tag = xmlutil.get_root_tag(t) Printer.info("Checking if root node's tag is %s" % root_node_expected_tag) root_node_actual_tag = xmlutil.get_root_tag(t) if (root_node_expected_tag != root_node_actual_tag): Printer.error("Root node does not have expected tag %s" % root_node_expected_tag) Printer.info("Checking if CloudServiceSettings are present") self._check_node_exists(t, './{0}CloudServiceSettings') if etag: Printer.info("Checking if ETag is %s" % etag) self._check_node_value(t, './{0}ETag', etag) Printer.info("Checking if Name is %s" % self.config['resource_name']) self._check_node_value(t, './{0}Name', self.config['resource_name']) Printer.info("Checking if OperationStatus/Result is 'Succeeded'") self._check_node_value(t, './{0}OperationStatus/{0}Result', "Succeeded") Printer.info("Checking if OutputItems are present") if self._check_node_exists(t, './{0}OutputItems', behavior='warn'): output_items = t.findall('.//{0}OutputItem'.format(xmlutil.get_namespace(t))) for output_item in output_items: output_item_tree = xmlutil.get_subtree_from_element(output_item) self._check_node_exists(output_item_tree, './{0}Key') self._check_node_exists(output_item_tree, './{0}Value') Printer.info("Checking if UsageMeters are present") if self._check_node_exists(t, './{0}UsageMeters', behavior='warn'): usage_meters = xmlutil.get_nodes('.//{0}UsageMeter') for usage_meter in usage_meters: usage_meter_tree = xmlutil.get_subtree_from_element(usage_meter) self._check_node_exists(usage_meter_tree, './{0}Included') self._check_node_exists(usage_meter_tree, './{0}Name') self._check_node_exists(usage_meter_tree, './{0}Unit', behavior='warn') self._check_node_exists(usage_meter_tree, './{0}Used') Printer.info("Checking if Plan is present") self._check_node_exists(t, './{0}Plan') Printer.info("Checking if State is 'Started'") self._check_node_value(t, './{0}State', "Started")
def _validate_resource_response(self, etag, t): root_node_expected_tag = xmlutil.get_root_tag(t) Printer.info("Checking if root node's tag is %s" % root_node_expected_tag) root_node_actual_tag = xmlutil.get_root_tag(t) if (root_node_expected_tag != root_node_actual_tag): Printer.error("Root node does not have expected tag %s" % root_node_expected_tag) Printer.info("Checking if xmlns is correct") xmlns_actual = xmlutil.get_xmlns(t) xmlns_expected = "http://schemas.microsoft.com/windowsazure" if not xmlns_actual: Printer.error("Missing xmlns tag") if xmlns_actual != xmlns_expected: Printer.error( "xmlns in response body is not correct. Expected: %s, Actual: %s" % (xmlns_expected, xmlns_actual)) Printer.info("Checking if CloudServiceSettings are present") self._check_node_exists(t, './{0}CloudServiceSettings') if etag: Printer.info("Checking if ETag is %s" % etag) self._check_node_value(t, './{0}ETag', etag) Printer.info("Checking if Name is %s" % self.config['resource_name']) self._check_node_value(t, './{0}Name', self.config['resource_name']) Printer.info("Checking if OperationStatus/Result is 'Succeeded'") self._check_node_value(t, './{0}OperationStatus/{0}Result', "Succeeded") Printer.info("Checking if OutputItems are present") # warn if OutputItems are not returned if self._check_node_exists(t, './{0}OutputItems', behavior='warn'): output_items = t.findall('.//{0}OutputItem'.format( xmlutil.get_namespace(t))) # check that no. of OutputItems are turned is equal to no. of OutputItems defined in manifest if len(output_items) != len( self.config['manifest']['output_items']): Printer.error( "Your response contains a different number of OutputItems (%s) than is defined in the manifest (%s)." % (len(output_items), len(self.config['manifest']['output_items']))) for output_item in output_items: output_item_tree = xmlutil.get_subtree_from_element( output_item) # warn if Key node is not present if self._check_node_exists(output_item_tree, './{0}Key'): output_item_key = self._get_node_value( output_item_tree, './{0}Key') Printer.info( "Checking if OutputItem '%s' is present in manifest and cased properly" % output_item_key) # warn if OutputItem is not defined in manifest if output_item_key not in self.config['manifest'][ 'output_items']: Printer.error( "OutputItem '%s' not found in manifest. Make sure it is cased properly in your response and defined in the manifest" % output_item_key) # warn if Value node is not present self._check_node_exists(output_item_tree, './{0}Value') Printer.info("Checking if UsageMeters are present") if self._check_node_exists(t, './{0}UsageMeters', behavior='warn'): usage_meters = xmlutil.get_nodes(t, './/{0}UsageMeter') for usage_meter in usage_meters: usage_meter_tree = xmlutil.get_subtree_from_element( usage_meter) self._check_node_exists(usage_meter_tree, './{0}Included') self._check_node_exists(usage_meter_tree, './{0}Name') if self._check_node_exists(usage_meter_tree, './{0}Unit', behavior='warn'): meter_name = self._get_node_value(usage_meter_tree, './{0}Unit') allowed_meter_names = ['bytes', 'hours', 'generic'] if meter_name not in allowed_meter_names: Printer.error( "Usage Meter '%s' is not one of allowed values: %s" % (meter_name, string.join(allowed_meter_names, ', '))) self._check_node_exists(usage_meter_tree, './{0}Used') Printer.info("Checking if Plan is present") self._check_node_exists(t, './{0}Plan') Printer.info("Checking if State is 'Started'") self._check_node_value(t, './{0}State', "Started") Printer.info("Checking if Type is '%s'" % self.config["resource_type"]) self._check_node_value(t, './{0}Type', self.config["resource_type"])
def _validate_resource_response(self, etag, t): root_node_expected_tag = xmlutil.get_root_tag(t) Printer.info("Checking if root node's tag is %s" % root_node_expected_tag) root_node_actual_tag = xmlutil.get_root_tag(t) if root_node_expected_tag != root_node_actual_tag: Printer.error("Root node does not have expected tag %s" % root_node_expected_tag) Printer.info("Checking if xmlns is correct") xmlns_actual = xmlutil.get_xmlns(t) xmlns_expected = "http://schemas.microsoft.com/windowsazure" if not xmlns_actual: Printer.error("Missing xmlns tag") if xmlns_actual != xmlns_expected: Printer.error( "xmlns in response body is not correct. Expected: %s, Actual: %s" % (xmlns_expected, xmlns_actual) ) Printer.info("Checking if CloudServiceSettings are present") self._check_node_exists(t, "./{0}CloudServiceSettings") if etag: Printer.info("Checking if ETag is %s" % etag) self._check_node_value(t, "./{0}ETag", etag) Printer.info("Checking if Name is %s" % self.config["resource_name"]) self._check_node_value(t, "./{0}Name", self.config["resource_name"]) Printer.info("Checking if OperationStatus/Result is 'Succeeded'") self._check_node_value(t, "./{0}OperationStatus/{0}Result", "Succeeded") Printer.info("Checking if OutputItems are present") # warn if OutputItems are not returned if self._check_node_exists(t, "./{0}OutputItems", behavior="warn"): output_items = t.findall(".//{0}OutputItem".format(xmlutil.get_namespace(t))) # check that no. of OutputItems are turned is equal to no. of OutputItems defined in manifest if len(output_items) != len(self.config["manifest"]["output_items"]): Printer.error( "Your response contains a different number of OutputItems (%s) than is defined in the manifest (%s)." % (len(output_items), len(self.config["manifest"]["output_items"])) ) for output_item in output_items: output_item_tree = xmlutil.get_subtree_from_element(output_item) # warn if Key node is not present if self._check_node_exists(output_item_tree, "./{0}Key"): output_item_key = self._get_node_value(output_item_tree, "./{0}Key") Printer.info( "Checking if OutputItem '%s' is present in manifest and cased properly" % output_item_key ) # warn if OutputItem is not defined in manifest if output_item_key not in self.config["manifest"]["output_items"]: Printer.error( "OutputItem '%s' not found in manifest. Make sure it is cased properly in your response and defined in the manifest" % output_item_key ) # warn if Value node is not present self._check_node_exists(output_item_tree, "./{0}Value") Printer.info("Checking if UsageMeters are present") if self._check_node_exists(t, "./{0}UsageMeters", behavior="warn"): usage_meters = xmlutil.get_nodes(t, ".//{0}UsageMeter") for usage_meter in usage_meters: usage_meter_tree = xmlutil.get_subtree_from_element(usage_meter) self._check_node_exists(usage_meter_tree, "./{0}Included") self._check_node_exists(usage_meter_tree, "./{0}Name") if self._check_node_exists(usage_meter_tree, "./{0}Unit", behavior="warn"): meter_name = self._get_node_value(usage_meter_tree, "./{0}Unit") allowed_meter_names = ["bytes", "hours", "generic"] if meter_name not in allowed_meter_names: Printer.error( "Usage Meter '%s' is not one of allowed values: %s" % (meter_name, string.join(allowed_meter_names, ", ")) ) self._check_node_exists(usage_meter_tree, "./{0}Used") Printer.info("Checking if Plan is present") self._check_node_exists(t, "./{0}Plan") Printer.info("Checking if State is 'Started'") self._check_node_value(t, "./{0}State", "Started") Printer.info("Checking if Type is '%s'" % self.config["resource_type"]) self._check_node_value(t, "./{0}Type", self.config["resource_type"])
def get_cloud_service(self): Printer.start_test("Get CloudService") (status, response) = self.client.perform_request( "subscriptions/%s/cloudservices/%s" % (self.config["subscription_id"], self.config["cloud_service_name"]), "GET", None, validate_xml=True) if status in [200, 201]: Printer.success("Get CloudService succeeded.") Printer.info("Checking XML") else: Printer.error("Get CloudService failed with HTTP status code %s" % status) return t = xmlutil.get_subtree_from_xml_string(response) root_node_expected_tag = '{0}CloudService'.format( xmlutil.get_namespace(t)) root_node_actual_tag = xmlutil.get_root_tag(t) if (root_node_expected_tag != root_node_actual_tag): Printer.error("Root node does not have expected tag %s" % root_node_expected_tag) return resource_names = map(lambda t: t.text, xmlutil.get_nodes(t, ".//{0}Resource/{0}Name")) if self.config['resource_name'] not in resource_names: Printer.error("Resource named '%s' not returned by endpoint" % self.config['resource_name'])