def test_load_transitive_indirect(self): x = ExpressionDict({ "field": "${injected.value}", "found": "FOUND", "injected.value": "${found}", }) self.assertEqual("FOUND", x.get("field"))
def test_cyclic_reference(self): x = ExpressionDict({'field': '${injected.value}', 'injected.value': '${field}'}) with self.assertRaises(ValueError): x['field'] with self.assertRaises(ValueError): x.get('field')
def test_load_transitive_indirect(self): x = ExpressionDict({ 'field': '${injected.value}', 'found': 'FOUND', 'injected.value': '${found}' }) self.assertEqual('FOUND', x.get('field'))
def test_cyclic_reference(self): x = ExpressionDict({ 'field': '${injected.value}', 'injected.value': '${field}' }) with self.assertRaises(ValueError): x['field'] with self.assertRaises(ValueError): x.get('field')
def test_cyclic_reference(self): x = ExpressionDict({ "field": "${injected.value}", "injected.value": "${field}" }) with self.assertRaises(ValueError): x["field"] with self.assertRaises(ValueError): x.get("field")
def test_def_value(self): x = ExpressionDict({'t': 'true', 'f': 'false', 'def': '${unknown:true}', 'indirect': '${f}'}) x.default_value_interpreter = lambda x: True if x == 'true' else False if x == 'false' else x self.assertEqual('true', x.get('t')) self.assertEqual('false', x.get('f')) self.assertEqual(True, x.get('def')) self.assertEqual('false', x.get('indirect'))
def test_def_value(self): x = ExpressionDict({ 't': 'true', 'f': 'false', 'def': '${unknown:true}', 'indirect': '${f}' }) x.default_value_interpreter = lambda x: True if x == 'true' else False if x == 'false' else x self.assertEqual('true', x.get('t')) self.assertEqual('false', x.get('f')) self.assertEqual(True, x.get('def')) self.assertEqual('false', x.get('indirect'))
def test_def_value(self): x = ExpressionDict({ "t": "true", "f": "false", "def": "${unknown:true}", "indirect": "${f}" }) x.default_value_interpreter = (lambda x: True if x == "true" else False if x == "false" else x) self.assertEqual("true", x.get("t")) self.assertEqual("false", x.get("f")) self.assertEqual(True, x.get("def")) self.assertEqual("false", x.get("indirect"))
def test_load_transitive_indirect(self): x = ExpressionDict({'field': '${injected.value}', 'found': 'FOUND', 'injected.value': '${found}'}) self.assertEqual('FOUND', x.get('field'))
def test_load_default(self): x = ExpressionDict({"field": "${injected.value:HELLO}"}) self.assertEqual("HELLO", x.get("field"))
def test_load_transitive(self): x = ExpressionDict({ 'field': '${injected.value}', 'injected.value': 'HELLO' }) self.assertEqual('HELLO', x.get('field'))
def test_load_tail_not_found(self): x = ExpressionDict({'field': '${injected.value}', 'injected': {}}) self.assertEqual('${injected.value}', x.get('field'))
def test_load_default(self): x = ExpressionDict({'field': '${injected.value}'}) self.assertEqual('MISSING', x.get('missing', 'MISSING'))
def test_constructor(self): d = {'a': 'A'} x = ExpressionDict({'a': 'A'}) self.assertEquals('A', x['a']) self.assertEquals(d.items(), x.items()) self.assertEquals(d, x)
def test_constructor(self): d = {'a': 'A'} x = ExpressionDict({'a': 'A'}) self.assertEquals('A', x['a']) self.assertEquals(d.items(), x.items()) self.assertEquals(d, x)
def test_load_key_not_found(self): x = ExpressionDict({"field": "${injected.value}", "injected": {}}) self.assertIsNone(x.get("unknown")) with self.assertRaises(KeyError): x["unknown"]
def test_load_not_found(self): x = ExpressionDict({"field": "${injected.value}"}) self.assertEqual("${injected.value}", x.get("field", None)) self.assertEqual("${injected.value}", x["field"])
def test_load_transitive(self): x = ExpressionDict({ "field": "${injected.value}", "injected.value": "HELLO" }) self.assertEqual("HELLO", x.get("field"))
def test_load_key_not_found(self): x = ExpressionDict({'field': '${injected.value}', 'injected': {}}) self.assertIsNone(x.get('unknown')) with self.assertRaises(KeyError): x['unknown']
def test_load_default(self): x = ExpressionDict({"field": "${injected.value}"}) self.assertEqual("MISSING", x.get("missing", "MISSING"))
def test_load_composite_value(self): x = ExpressionDict({'a':'A', 'b':'B', 'test':'${a}/${b}'}) self.assertEqual('A/B', x.get('test'))
def __get_deployed_local_yaml_bindings(gcloud, instance): """Return the contents of the spinnaker-local.yml configuration file. Args: gcloud: [GCloudAgent] Specifies project and zone. Capable of remote fetching if needed. instance: [string] The GCE instance name containing the deployment. Returns: None or the configuration file contents. """ config_dict = ExpressionDict() logger = logging.getLogger(__name__) if gce_util.am_i(gcloud.project, gcloud.zone, instance): yaml_file = os.path.expanduser('~/.spinnaker/spinnaker-local.yml') logger.debug('We are the instance. Config from %s', yaml_file) if not os.path.exists(yaml_file): logger.debug('%s does not exist', yaml_file) return None try: yaml_accumulator.load_path(yaml_file, config_dict) return config_dict except IOError as ex: logger.error('Failed to load from %s: %s', yaml_file, ex) return None logger.debug('Load spinnaker-local.yml from instance %s', instance) # If this is a production installation, look in: # /home/spinnaker/.spinnaker # or /opt/spinnaker/config # or /etc/default/spinnaker (name/value) # Otherwise look in ~/.spinnaker for a development installation. # pylint: disable=bad-continuation response = gcloud.remote_command( instance, 'LIST=""' '; for i in /etc/default/spinnaker' ' /home/spinnaker/.spinnaker/spinnaker-local.yml' ' /opt/spinnaker/config/spinnaker-local.yml' ' $HOME/.spinnaker/spinnaker-local.yml' '; do' ' if sudo stat $i >& /dev/null; then' ' LIST="$LIST $i"' '; fi' '; done' # tar emits warnings about the absolute paths, so we'll filter them out # We need to base64 the binary results so we return text. '; (sudo tar czf - $LIST 2> /dev/null | base64)') if not response.ok(): logger.error( 'Could not determine configuration:\n%s', response.error) return None # gcloud prints an info message about upgrades to the output stream. # There seems to be no way to supress this! # Look for it and truncate the stream there if we see it. got = response.output update_msg_offset = got.find('Updates are available') if update_msg_offset > 0: got = got[0:update_msg_offset] # When we ssh in, there may be a message written warning us that the host # was added to known hosts. If so, this will be the first line. Remove it. eoln = got.find('\n') if eoln > 0 and re.match('^Warning: .+$', got[0:eoln]): got = got[eoln + 1:] if not got: return None tar = tarfile.open(mode='r', fileobj=StringIO(base64.b64decode(got))) try: entry = tar.extractfile('etc/default/spinnaker') except KeyError: pass else: logger.info('Importing configuration from /etc/default/spinnaker') config_dict.update(name_value_to_dict(entry.read())) file_list = ['home/spinnaker/.spinnaker/spinnaker-local.yml', 'opt/spinnaker/config/spinnaker-local.yml'] log_name = os.environ.get('LOGNAME') if log_name is not None: file_list.append(os.path.join('home', log_name, '.spinnaker/spinnaker-local.yml')) for member in file_list: try: entry = tar.extractfile(member) except KeyError: continue logger.info('Importing configuration from ' + member) yaml_accumulator.load_string(entry.read(), config_dict) return config_dict
def test_load_default(self): x = ExpressionDict({'field': '${injected.value}'}) self.assertEqual('MISSING', x.get('missing', 'MISSING'))
def test_load_composite_value(self): x = ExpressionDict({'a': 'A', 'b': 'B', 'test': '${a}/${b}'}) self.assertEqual('A/B', x.get('test'))
def test_load_not_found(self): x = ExpressionDict({'field': '${injected.value}'}) self.assertEqual('${injected.value}', x.get('field', None)) self.assertEqual('${injected.value}', x['field'])
def test_load_not_found(self): x = ExpressionDict({'field': '${injected.value}'}) self.assertEqual('${injected.value}', x.get('field', None)) self.assertEqual('${injected.value}', x['field'])
def test_load_key_not_found(self): x = ExpressionDict({'field': '${injected.value}', 'injected': {}}) self.assertIsNone(x.get('unknown')) with self.assertRaises(KeyError): x['unknown']
def test_load_default(self): x = ExpressionDict({'field': '${injected.value:HELLO}'}) self.assertEqual('HELLO', x.get('field'))
def test_load_composite_value(self): x = ExpressionDict({"a": "A", "b": "B", "test": "${a}/${b}"}) self.assertEqual("A/B", x.get("test"))
def test_load_tail_not_found(self): x = ExpressionDict({'field': '${injected.value}', 'injected': {}}) self.assertEqual('${injected.value}', x.get('field'))
def test_load_tail_not_found(self): x = ExpressionDict({"field": "${injected.value}", "injected": {}}) self.assertEqual("${injected.value}", x.get("field"))
def test_load_default(self): x = ExpressionDict({'field': '${injected.value:HELLO}'}) self.assertEqual('HELLO', x.get('field'))
def test_load_transitive(self): x = ExpressionDict({'field': '${injected.value}', 'injected.value': 'HELLO'}) self.assertEqual('HELLO', x.get('field'))
def __get_deployed_local_yaml_bindings(gcloud, instance): """Return the contents of the spinnaker-local.yml configuration file. Args: gcloud: [GCloudAgent] Specifies project and zone. Capable of remote fetching if needed. instance: [string] The GCE instance name containing the deployment. Returns: None or the configuration file contents. """ config_dict = ExpressionDict() logger = logging.getLogger(__name__) if gce_util.am_i(gcloud.project, gcloud.zone, instance): yaml_file = os.path.expanduser('~/.spinnaker/spinnaker-local.yml') logger.debug('We are the instance. Config from %s', yaml_file) if not os.path.exists(yaml_file): logger.debug('%s does not exist', yaml_file) return None try: yaml_accumulator.load_path(yaml_file, config_dict) return config_dict except IOError as ex: logger.error('Failed to load from %s: %s', yaml_file, ex) return None logger.debug('Load spinnaker-local.yml from instance %s', instance) # If this is a production installation, look in: # /home/spinnaker/.spinnaker # or /opt/spinnaker/config # or /etc/default/spinnaker (name/value) # Otherwise look in ~/.spinnaker for a development installation. # pylint: disable=bad-continuation response = gcloud.remote_command( instance, 'LIST=""' '; for i in /etc/default/spinnaker' ' /home/spinnaker/.spinnaker/spinnaker-local.yml' ' /opt/spinnaker/config/spinnaker-local.yml' ' $HOME/.spinnaker/spinnaker-local.yml' '; do' ' if sudo stat $i >& /dev/null; then' ' LIST="$LIST $i"' '; fi' '; done' # tar emits warnings about the absolute paths, so we'll filter them out # We need to base64 the binary results so we return text. '; (sudo tar czf - $LIST 2> /dev/null | base64)') if not response.ok(): logger.error('Could not determine configuration:\n%s', response.error) return None # gcloud prints an info message about upgrades to the output stream. # There seems to be no way to supress this! # Look for it and truncate the stream there if we see it. got = response.output update_msg_offset = got.find('Updates are available') if update_msg_offset > 0: got = got[0:update_msg_offset] # When we ssh in, there may be a message written warning us that the host # was added to known hosts. If so, this will be the first line. Remove it. eoln = got.find('\n') if eoln > 0 and re.match('^Warning: .+$', got[0:eoln]): got = got[eoln + 1:] if not got: return None tar = tarfile.open(mode='r', fileobj=StringIO(base64.b64decode(got))) try: entry = tar.extractfile('etc/default/spinnaker') except KeyError: pass else: logger.info('Importing configuration from /etc/default/spinnaker') config_dict.update(name_value_to_dict(entry.read())) file_list = [ 'home/spinnaker/.spinnaker/spinnaker-local.yml', 'opt/spinnaker/config/spinnaker-local.yml' ] log_name = os.environ.get('LOGNAME') if log_name is not None: file_list.append( os.path.join('home', log_name, '.spinnaker/spinnaker-local.yml')) for member in file_list: try: entry = tar.extractfile(member) except KeyError: continue logger.info('Importing configuration from ' + member) yaml_accumulator.load_string(entry.read(), config_dict) return config_dict
def test_constructor(self): d = {"a": "A"} x = ExpressionDict({"a": "A"}) self.assertEquals("A", x["a"]) self.assertEquals(d.items(), x.items()) self.assertEquals(d, x)