def format(cls, entry, *args, **kwargs): attrs = kwargs.get('attributes', []) key = kwargs.get('key', None) if key: output = jsutil.get_value(entry.result, key) else: # drop entry to the dict so that jsutil can operate entry = vars(entry) output = '' for attr in attrs: value = jsutil.get_value(entry, attr) if (isinstance(value, basestring) and len(value) > 0 and value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']): new_value = ast.literal_eval(value) if type(new_value) in [dict, list]: value = new_value if type(value) in [dict, list]: # 1. To get a nice overhang indent get safe_dump to generate output with # the attribute key and then remove the attribute key from the string. # 2. Drop the trailing newline # 3. Set width to maxint so pyyaml does not split text. Anything longer # and likely we will see other issues like storage :P. formatted_value = yaml.safe_dump({attr: value}, default_flow_style=False, width=sys.maxint, indent=2)[len(attr) + 2:-1] value = ('\n' if isinstance(value, dict) else '') + formatted_value output += ('\n' if output else '') + '%s: %s' % \ (DisplayColors.colorize(attr, DisplayColors.BLUE), value) return strutil.unescape(output)
def test_dot_notation(self): self.assertEqual(jsutil.get_value(DOC, 'a01'), 1) self.assertEqual(jsutil.get_value(DOC, 'c01.c11'), 3) self.assertEqual(jsutil.get_value(DOC, 'c01.c13.c22'), 6) self.assertEqual(jsutil.get_value(DOC, 'c01.c13'), { 'c21': 5, 'c22': 6 }) self.assertListEqual(jsutil.get_value(DOC, 'c01.c14'), [7, 8, 9])
def test_dot_notation(self): self.assertEqual(jsutil.get_value(DOC, "a01"), 1) self.assertEqual(jsutil.get_value(DOC, "c01.c11"), 3) self.assertEqual(jsutil.get_value(DOC, "c01.c13.c22"), 6) self.assertEqual(jsutil.get_value(DOC, "c01.c13"), { "c21": 5, "c22": 6 }) self.assertListEqual(jsutil.get_value(DOC, "c01.c14"), [7, 8, 9])
def format(cls, entry, *args, **kwargs): attrs = kwargs.get('attributes', []) attribute_transform_functions = kwargs.get( 'attribute_transform_functions', {}) key = kwargs.get('key', None) if key: output = jsutil.get_value(entry.result, key) else: # drop entry to the dict so that jsutil can operate entry = vars(entry) output = '' for attr in attrs: value = jsutil.get_value(entry, attr) value = strutil.strip_carriage_returns(strutil.unescape(value)) if (isinstance(value, six.string_types) and len(value) > 0 and value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']): new_value = ast.literal_eval(value) if type(new_value) in [dict, list]: value = new_value if type(value) in [dict, list]: # 1. To get a nice overhang indent get safe_dump to generate output with # the attribute key and then remove the attribute key from the string. # 2. Drop the trailing newline # 3. Set width to maxint so pyyaml does not split text. Anything longer # and likely we will see other issues like storage :P. formatted_value = yaml.safe_dump({attr: value}, default_flow_style=False, width=PLATFORM_MAXINT, indent=2)[len(attr) + 2:-1] value = ('\n' if isinstance(value, dict) else '') + formatted_value value = strutil.dedupe_newlines(value) # transform the value of our attribute so things like 'status' # and 'timestamp' are formatted nicely transform_function = attribute_transform_functions.get( attr, lambda value: value) value = transform_function(value=value) output += ('\n' if output else '') + '%s: %s' % \ (DisplayColors.colorize(attr, DisplayColors.BLUE), value) if six.PY3: return strutil.unescape(str(output)) else: # Assume Python 2 return strutil.unescape( str(output)).decode('unicode_escape').encode('utf-8')
def format(cls, entry, *args, **kwargs): attrs = kwargs.get('attributes', []) attribute_transform_functions = kwargs.get('attribute_transform_functions', {}) key = kwargs.get('key', None) if key: output = jsutil.get_value(entry.result, key) else: # drop entry to the dict so that jsutil can operate entry = vars(entry) output = '' for attr in attrs: value = jsutil.get_value(entry, attr) value = strutil.strip_carriage_returns(strutil.unescape(value)) if (isinstance(value, six.string_types) and len(value) > 0 and value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']): new_value = ast.literal_eval(value) if type(new_value) in [dict, list]: value = new_value if type(value) in [dict, list]: # 1. To get a nice overhang indent get safe_dump to generate output with # the attribute key and then remove the attribute key from the string. # 2. Drop the trailing newline # 3. Set width to maxint so pyyaml does not split text. Anything longer # and likely we will see other issues like storage :P. formatted_value = yaml.safe_dump({attr: value}, default_flow_style=False, width=PLATFORM_MAXINT, indent=2)[len(attr) + 2:-1] value = ('\n' if isinstance(value, dict) else '') + formatted_value value = strutil.dedupe_newlines(value) # transform the value of our attribute so things like 'status' # and 'timestamp' are formatted nicely transform_function = attribute_transform_functions.get(attr, lambda value: value) value = transform_function(value=value) output += ('\n' if output else '') + '%s: %s' % \ (DisplayColors.colorize(attr, DisplayColors.BLUE), value) if six.PY3: return strutil.unescape(str(output)) else: # Assume Python 2 return strutil.unescape(str(output)).decode('unicode_escape').encode('utf-8')
def format(cls, entry, *args, **kwargs): attrs = kwargs.get('attributes', []) key = kwargs.get('key', None) if key: output = jsutil.get_value(entry.result, key) else: # drop entry to the dict so that jsutil can operate entry = vars(entry) output = '' for attr in attrs: value = jsutil.get_value(entry, attr) if (isinstance(value, basestring) and len(value) > 0 and value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']): new_value = ast.literal_eval(value) if type(new_value) in [dict, list]: value = new_value if type(value) in [dict, list]: value = ('\n' if isinstance(value, dict) else '') + json.dumps(value, indent=4) output += ('\n' if output else '') + '%s: %s' % \ (DisplayColors.colorize(attr, DisplayColors.BLUE), value) return strutil.unescape(output)
def _format_for_common_representation(self, task): ''' Formats a task for common representation between mistral and action-chain. ''' # This really needs to be better handled on the back-end but that would be a bigger # change so handling in cli. context = getattr(task, 'context', None) if context and 'chain' in context: task_name_key = 'context.chain.name' elif context and 'mistral' in context: task_name_key = 'context.mistral.task_name' # Use LiveAction as the object so that the formatter lookup does not change. # AKA HACK! return models.action.LiveAction(**{ 'id': task.id, 'status': task.status, 'task': jsutil.get_value(vars(task), task_name_key), 'action': task.action.get('ref', None), 'start_timestamp': task.start_timestamp })
def format(cls, entry, *args, **kwargs): attrs = kwargs.get('attributes', []) key = kwargs.get('key', None) if key: output = jsutil.get_value(entry.result, key) else: output = '' for attr in attrs: value = getattr(entry, attr, None) if (isinstance(value, basestring) and len(value) > 0 and value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']): new_value = ast.literal_eval(value) if type(new_value) in [dict, list]: value = new_value if type(value) in [dict, list]: value = ('\n' if isinstance(value, dict) else '') + json.dumps(value, indent=4) output += ('\n' if output else '') + '%s: %s' % (attr.upper(), value) return strutil.unescape(output)
def test_ip_address_calls_complex(self, mock__get_value_complex): jsutil.get_value(DOC_IP_ADDRESS, 'ips."192.168.1.1"') mock__get_value_complex.assert_called_with(DOC_IP_ADDRESS, 'ips."192.168.1.1"')
def test_dot_notation_with_key_error(self): self.assertIsNone(jsutil.get_value(DOC, 'd01')) self.assertIsNone(jsutil.get_value(DOC, 'a01.a11')) self.assertIsNone(jsutil.get_value(DOC, 'c01.c11.c21.c31')) self.assertIsNone(jsutil.get_value(DOC, 'c01.c14.c31'))
def test_ip_address(self): self.assertEqual(jsutil.get_value(DOC_IP_ADDRESS, 'ips."192.168.1.1"'), {"hostname": "router.domain.tld"})
def test_single_key_calls_simple(self, mock__get_value_simple): jsutil.get_value(DOC, 'a01') mock__get_value_simple.assert_called_with(DOC, 'a01')
def test_chars_nums_dashes_underscores_calls_simple(self): for char in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_': with mock.patch( "st2client.utils.jsutil._get_value_simple") as mock_simple: jsutil.get_value(DOC, char) mock_simple.assert_called_with(DOC, char)
def test_double_dot_calls_complex(self, mock__get_value_complex): jsutil.get_value(DOC, 'c01..c11') mock__get_value_complex.assert_called_with(DOC, 'c01..c11')
def test_dot_notation_calls_simple(self, mock__get_value_simple): jsutil.get_value(DOC, 'c01.c11') mock__get_value_simple.assert_called_with(DOC, 'c01.c11')
def test_symbols_calls_complex(self): for char in '`~!@#$%^&&*()=+{}[]|\\;:\'"<>,./?': with mock.patch("st2client.utils.jsutil._get_value_complex") as mock_complex: jsutil.get_value(DOC, char) mock_complex.assert_called_with(DOC, char)
def test_chars_nums_dashes_underscores_calls_simple(self): for char in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_': with mock.patch("st2client.utils.jsutil._get_value_simple") as mock_simple: jsutil.get_value(DOC, char) mock_simple.assert_called_with(DOC, char)
def test_beginning_dot_calls_complex(self, mock__get_value_complex): jsutil.get_value(DOC, '.c01.c11') mock__get_value_complex.assert_called_with(DOC, '.c01.c11')
def test_ending_dot_calls_complex(self, mock__get_value_complex): jsutil.get_value(DOC, 'c01.c11.') mock__get_value_complex.assert_called_with(DOC, 'c01.c11.')
def format(cls, entry, *args, **kwargs): attrs = kwargs.get('attributes', []) attribute_transform_functions = kwargs.get( 'attribute_transform_functions', {}) key = kwargs.get('key', None) if key: output = jsutil.get_value(entry.result, key) else: # drop entry to the dict so that jsutil can operate entry = vars(entry) output = '' for attr in attrs: value = jsutil.get_value(entry, attr) value = strutil.strip_carriage_returns(strutil.unescape(value)) # TODO: This check is inherently flawed since it will crash st2client # if the leading character is objectish start and last character is objectish # end but the string isn't supposed to be a object. Try/Except will catch # this for now, but this should be improved. if (isinstance(value, six.string_types) and len(value) > 0 and value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']): try: new_value = ast.literal_eval(value) except: new_value = value if type(new_value) in [dict, list]: value = new_value if type(value) in [dict, list]: # 1. To get a nice overhang indent get safe_dump to generate output with # the attribute key and then remove the attribute key from the string. # 2. Drop the trailing newline # 3. Set width to maxint so pyyaml does not split text. Anything longer # and likely we will see other issues like storage :P. formatted_value = yaml.safe_dump({attr: value}, default_flow_style=False, width=PLATFORM_MAXINT, indent=2)[len(attr) + 2:-1] value = ('\n' if isinstance(value, dict) else '') + formatted_value value = strutil.dedupe_newlines(value) # transform the value of our attribute so things like 'status' # and 'timestamp' are formatted nicely transform_function = attribute_transform_functions.get( attr, lambda value: value) value = transform_function(value=value) output += ('\n' if output else '') + '%s: %s' % \ (DisplayColors.colorize(attr, DisplayColors.BLUE), value) output_schema = entry.get('action', {}).get('output_schema') schema_check = get_config()['general']['silence_schema_output'] if not output_schema and kwargs.get('with_schema'): rendered_schema = { 'output_schema': schema.render_output_schema_from_output(entry['result']) } rendered_schema = yaml.safe_dump(rendered_schema, default_flow_style=False) output += '\n' output += _print_bordered( "Based on the action output the following inferred schema was built:" "\n\n" "%s" % rendered_schema) elif not output_schema and not schema_check: output += ( "\n\n** This action does not have an output_schema. " "Run again with --with-schema to see a suggested schema.") if six.PY3: return strutil.unescape(str(output)) else: # Assume Python 2 try: result = strutil.unescape( str(output)).decode('unicode_escape').encode('utf-8') except UnicodeDecodeError: # String contains a value which is not an unicode escape sequence, ignore the error result = strutil.unescape(str(output)) return result
def test_symbols_calls_complex(self): for char in '`~!@#$%^&&*()=+{}[]|\\;:\'"<>,./?': with mock.patch("st2client.utils.jsutil._get_value_complex" ) as mock_complex: jsutil.get_value(DOC, char) mock_complex.assert_called_with(DOC, char)
def format(cls, entry, *args, **kwargs): attrs = kwargs.get('attributes', []) attribute_transform_functions = kwargs.get('attribute_transform_functions', {}) key = kwargs.get('key', None) if key: output = jsutil.get_value(entry.result, key) else: # drop entry to the dict so that jsutil can operate entry = vars(entry) output = '' for attr in attrs: value = jsutil.get_value(entry, attr) value = strutil.strip_carriage_returns(strutil.unescape(value)) # TODO: This check is inherently flawed since it will crash st2client # if the leading character is objectish start and last character is objectish # end but the string isn't supposed to be a object. Try/Except will catch # this for now, but this should be improved. if (isinstance(value, six.string_types) and len(value) > 0 and value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']): try: new_value = ast.literal_eval(value) except: new_value = value if type(new_value) in [dict, list]: value = new_value if type(value) in [dict, list]: # 1. To get a nice overhang indent get safe_dump to generate output with # the attribute key and then remove the attribute key from the string. # 2. Drop the trailing newline # 3. Set width to maxint so pyyaml does not split text. Anything longer # and likely we will see other issues like storage :P. formatted_value = yaml.safe_dump({attr: value}, default_flow_style=False, width=PLATFORM_MAXINT, indent=2)[len(attr) + 2:-1] value = ('\n' if isinstance(value, dict) else '') + formatted_value value = strutil.dedupe_newlines(value) # transform the value of our attribute so things like 'status' # and 'timestamp' are formatted nicely transform_function = attribute_transform_functions.get(attr, lambda value: value) value = transform_function(value=value) output += ('\n' if output else '') + '%s: %s' % \ (DisplayColors.colorize(attr, DisplayColors.BLUE), value) output_schema = entry.get('action', {}).get('output_schema') schema_check = get_config()['general']['silence_schema_output'] if not output_schema and kwargs.get('with_schema'): rendered_schema = { 'output_schema': schema.render_output_schema_from_output(entry['result']) } rendered_schema = yaml.safe_dump(rendered_schema, default_flow_style=False) output += '\n' output += _print_bordered( "Based on the action output the following inferred schema was built:" "\n\n" "%s" % rendered_schema ) elif not output_schema and not schema_check: output += ( "\n\n** This action does not have an output_schema. " "Run again with --with-schema to see a suggested schema." ) if six.PY3: return strutil.unescape(str(output)) else: # Assume Python 2 try: result = strutil.unescape(str(output)).decode('unicode_escape').encode('utf-8') except UnicodeDecodeError: # String contains a value which is not an unicode escape sequence, ignore the error result = strutil.unescape(str(output)) return result
def test_dot_notation(self): self.assertEqual(jsutil.get_value(DOC, 'a01'), 1) self.assertEqual(jsutil.get_value(DOC, 'c01.c11'), 3) self.assertEqual(jsutil.get_value(DOC, 'c01.c13.c22'), 6) self.assertEqual(jsutil.get_value(DOC, 'c01.c13'), {'c21': 5, 'c22': 6}) self.assertListEqual(jsutil.get_value(DOC, 'c01.c14'), [7, 8, 9])
def format(cls, entry, *args, **kwargs): attrs = kwargs.get("attributes", []) attribute_transform_functions = kwargs.get( "attribute_transform_functions", {}) key = kwargs.get("key", None) if key: output = jsutil.get_value(entry.result, key) else: # drop entry to the dict so that jsutil can operate entry = vars(entry) output = "" for attr in attrs: value = jsutil.get_value(entry, attr) value = strutil.strip_carriage_returns(strutil.unescape(value)) # transform the value of our attribute so things like 'status' # and 'timestamp' are formatted nicely transform_function = attribute_transform_functions.get( attr, lambda value: value) value = transform_function(value=value) # TODO: This check is inherently flawed since it will crash st2client # if the leading character is objectish start and last character is objectish # end but the string isn't supposed to be a object. Try/Except will catch # this for now, but this should be improved. if (isinstance(value, six.string_types) and len(value) > 0 and value[0] in ["{", "["] and value[len(value) - 1] in ["}", "]"]): try: new_value = ast.literal_eval(value) except: new_value = value if type(new_value) in [dict, list]: value = new_value if isinstance(value, (dict, list)): # 1. To get a nice overhang indent get safe_dump to generate output with # the attribute key and then remove the attribute key from the string. # 2. Drop the trailing newline # 3. Set width to maxint so pyyaml does not split text. Anything longer # and likely we will see other issues like storage :P. # NOTE: We use C version of the safe dumper which is faster. # Keep in mind that using YamlSafeDumper is the same as using yaml.safe_dumps # (same class is used underneath when using yaml.safe_dump) so the code is safe. formatted_value = yaml.dump( {attr: value}, default_flow_style=False, width=PLATFORM_MAXINT, indent=2, Dumper=YamlSafeDumper, )[len(attr) + 2:-1] if isinstance(value, list): # Indent list values with 2 spaces for a nicer display. lines = formatted_value.split("\n") formatted_value = [] for line in lines: formatted_value.append(" %s" % (line)) formatted_value = "\n".join(formatted_value) value = ("\n" if isinstance(value, (dict, list)) else "") + formatted_value value = strutil.dedupe_newlines(value) # transform the value of our attribute so things like 'status' # and 'timestamp' are formatted nicely transform_function = attribute_transform_functions.get( attr, lambda value: value) value = transform_function(value=value) output += ("\n" if output else "") + "%s: %s" % ( DisplayColors.colorize(attr, DisplayColors.BLUE), value, ) output_schema = entry.get("action", {}).get("output_schema") schema_check = get_config()["general"]["silence_schema_output"] if not output_schema and kwargs.get("with_schema"): rendered_schema = { "output_schema": schema.render_output_schema_from_output(entry["result"]) } rendered_schema = yaml.safe_dump(rendered_schema, default_flow_style=False) output += "\n" output += _print_bordered( "Based on the action output the following inferred schema was built:" "\n\n" "%s" % rendered_schema) elif not output_schema and not schema_check: output += ( "\n\n** This action does not have an output_schema. " "Run again with --with-schema to see a suggested schema.") if six.PY3: return strutil.unescape(str(output)) else: # Assume Python 2 try: result = (strutil.unescape( str(output)).decode("unicode_escape").encode("utf-8")) except UnicodeDecodeError: # String contains a value which is not an unicode escape sequence, ignore the error result = strutil.unescape(str(output)) return result