def init(self, ref, path, config=None, env=None, deployment=None, sync=False, **kwargs): app, service = self.parse_app_ref(ref, kwargs, app_only=True) if config: config_file = os.path.expanduser(config) else: config_file = os.path.join(path, 'mcloud.yml') config = YamlConfig(file=config_file, app_name=app) config.load(process=False) deployment_info = yield self._remote_exec('deployment_info', name=deployment) if deployment_info: if not deployment: deployment = deployment_info['name'] if not deployment_info['local']: yield self._remote_exec('init', app, config=config.export(), env=env, deployment=deployment) if sync: yield self.sync(os.path.realpath(path), '%s@%s' % (app, self.host), no_remove=False, force=True, full=True) else: yield self._remote_exec('init', app, path=os.path.realpath(path), config=config.export(), deployment=deployment) else: print('There is no deployments configured yet.\n\n' 'You can create new local deployment using following command:\n' '\n $ mcloud deployment-create local\n\n') reactor.stop()
def test_process_with_local_config(): c = YamlConfig(source='{"nginx": {"image": "bar"}, "---": {"commands": {"bar": ["foo"]}}}') flexmock(c) c.should_receive('process_local_config').once().with_args({"commands": {"bar": ["foo"]}}) c.load(process=False)
def test_load_config_from_config(): config = YamlConfig(source='{"foo": "bar"}', app_name='myapp') flexmock(config).should_receive('prepare').with_args({'foo': 'bar'}).once().and_return({'foo': 'bar1'}) flexmock(config).should_receive('validate').with_args({'foo': 'bar1'}).once() flexmock(config).should_receive('process').with_args(OrderedDict([('foo', 'bar1')]), path=None, app_name='myapp', client='booo').once() config.load(client='booo')
def config(self, ref, diff=False, config=None, update=False, set_env=None, **kwargs): app, service = self.parse_app_ref(ref, kwargs, app_only=True) app_config = yield self._remote_exec('config', app) parser_env = set_env or app_config['env'] if diff or (not update and not set_env): old_config = YamlConfig(source=unicode(app_config['source']), app_name=app, env=parser_env) old_config.load(process=False) from collections import OrderedDict yaml.add_representer(unicode, yaml.representer.SafeRepresenter.represent_unicode) yaml.add_representer(OrderedDict, self.represent_ordereddict) olds = yaml.dump(old_config.config, default_flow_style=False) if not update and not diff and not set_env: x = PrettyTable(["Name", "Value"], hrules=ALL, align='l', header=False) x.align = "l" x.add_row(['Config', olds]) x.add_row(['Environment', app_config['env']]) x.add_row(['Path', app_config['path']]) print(x) else: if config: config_file = os.path.expanduser(config) else: config_file = 'mcloud.yml' new_config = YamlConfig(file=config_file, app_name=app, env=parser_env) new_config.load(process=False) if diff: yaml.add_representer(unicode, yaml.representer.SafeRepresenter.represent_unicode) yaml.add_representer(OrderedDict, self.represent_ordereddict) news = yaml.dump(new_config.config, default_flow_style=False) if olds == news: print('Configs are identical.') else: for line in unified_diff(olds.splitlines(1), news.splitlines(1)): if line.endswith('\n'): line = line[0:-1] if line.startswith('+'): print color_text(line, color='green') elif line.startswith('-'): print color_text(line, color='red') else: print line else: if set_env and not update: yield self._remote_exec('update', app, env=set_env) else: yield self._remote_exec('update', app, config=new_config.export(), env=set_env)
def test_load_config(tmpdir): p = tmpdir.join('mcloud.yml') p.write('foo: bar') config = YamlConfig(file=p.realpath(), app_name='myapp') flexmock(config).should_receive('prepare').with_args({'foo': 'bar'}).once().and_return({'foo': 'bar1'}) flexmock(config).should_receive('validate').with_args({'foo': 'bar1'}).once() flexmock(config).should_receive('process').with_args(OrderedDict([('foo', 'bar1')]), path=None, app_name='myapp', client='booo').once() config.load(client='booo')
def test_load_config_not_valid(tmpdir): p = tmpdir.join('mcloud.yml') p.write('foo: bar') config = YamlConfig(file=p.realpath(), app_name='myapp') flexmock(config).should_receive('prepare').with_args({'foo': 'bar'}).once().and_return({'foo': 'bar1'}) flexmock(config).should_receive('validate').with_args({'foo': 'bar1'}).once().and_raise(ValueError('boo')) flexmock(config).should_receive('process').times(0) with pytest.raises(ConfigParseError): config.load()
def test_process_with_local_config(): c = YamlConfig( source= '{"nginx": {"image": "bar"}, "---": {"commands": {"bar": ["foo"]}}}') flexmock(c) c.should_receive('process_local_config').once().with_args( {"commands": { "bar": ["foo"] }}) c.load(process=False)
def init(self, ref, path, config=None, env=None, deployment=None, sync=False, **kwargs): app, service = self.parse_app_ref(ref, kwargs, app_only=True) if config: config_file = os.path.expanduser(config) else: config_file = os.path.join(path, 'mcloud.yml') config = YamlConfig(file=config_file, app_name=app) config.load(process=False) deployment_info = yield self._remote_exec('deployment_info', name=deployment) if deployment_info: if not deployment: deployment = deployment_info['name'] if not deployment_info['local']: yield self._remote_exec('init', app, config=config.export(), env=env, deployment=deployment) if sync: yield self.sync(os.path.realpath(path), '%s@%s' % (app, self.host), no_remove=False, force=True, full=True) else: yield self._remote_exec('init', app, path=os.path.realpath(path), config=config.export(), deployment=deployment) else: print( 'There is no deployments configured yet.\n\n' 'You can create new local deployment using following command:\n' '\n $ mcloud deployment-create local\n\n') reactor.stop()
def test_load_config_not_valid(tmpdir): p = tmpdir.join('mcloud.yml') p.write('foo: bar') config = YamlConfig(file=p.realpath(), app_name='myapp') flexmock(config).should_receive('prepare').with_args({ 'foo': 'bar' }).once().and_return({'foo': 'bar1'}) flexmock(config).should_receive('validate').with_args({ 'foo': 'bar1' }).once().and_raise(ValueError('boo')) flexmock(config).should_receive('process').times(0) with pytest.raises(ConfigParseError): config.load()
def test_load_config_from_config(): config = YamlConfig(source='{"foo": "bar"}', app_name='myapp') flexmock(config).should_receive('prepare').with_args({ 'foo': 'bar' }).once().and_return({'foo': 'bar1'}) flexmock(config).should_receive('validate').with_args({ 'foo': 'bar1' }).once() flexmock(config).should_receive('process').with_args(OrderedDict([ ('foo', 'bar1') ]), path=None, app_name='myapp', client='booo').once() config.load(client='booo')
def test_load_config(tmpdir): p = tmpdir.join('mcloud.yml') p.write('foo: bar') config = YamlConfig(file=p.realpath(), app_name='myapp') flexmock(config).should_receive('prepare').with_args({ 'foo': 'bar' }).once().and_return({'foo': 'bar1'}) flexmock(config).should_receive('validate').with_args({ 'foo': 'bar1' }).once() flexmock(config).should_receive('process').with_args(OrderedDict([ ('foo', 'bar1') ]), path=None, app_name='myapp', client='booo').once() config.load(client='booo')
def load(self, need_details=False): try: if 'source' in self.config: yaml_config = YamlConfig(source=self.config['source'], app_name=self.name, path=self.config['path'], env=self.get_env()) elif 'path' in self.config: yaml_config = YamlConfig(file=os.path.join( self.config['path'], 'mcloud.yml'), app_name=self.name, path=self.config['path']) else: self.error = {'msg': 'Can not parse config'} defer.returnValue(None) deployment = yield self.get_deployment() if not deployment: self.error = {'msg': 'No deployment found'} else: client = deployment.get_client() yield yaml_config.load(client=client) yield defer.gatherResults([ service.inspect() for service in yaml_config.get_services().values() ]) if need_details: defer.returnValue(self._details(yaml_config, deployment)) else: defer.returnValue(yaml_config) except (ValueError, DeploymentDoesNotExist) as e: config_ = { 'name': self.name, 'config': self.config, 'services': [], 'running': False, 'status': 'error', 'message': '%s When loading config: %s' % (e.message, self.config) } defer.returnValue(config_)
def load(self, need_details=False): try: if 'source' in self.config: yaml_config = YamlConfig(source=self.config['source'], app_name=self.name, path=self.config['path'], env=self.get_env()) elif 'path' in self.config: yaml_config = YamlConfig(file=os.path.join(self.config['path'], 'mcloud.yml'), app_name=self.name, path=self.config['path']) else: self.error = { 'msg': 'Can not parse config' } defer.returnValue(None) deployment = yield self.get_deployment() if not deployment: self.error = { 'msg': 'No deployment found' } else: client = deployment.get_client() yield yaml_config.load(client=client) yield defer.gatherResults([service.inspect() for service in yaml_config.get_services().values()]) if need_details: defer.returnValue(self._details(yaml_config, deployment)) else: defer.returnValue(yaml_config) except (ValueError, DeploymentDoesNotExist) as e: config_ = {'name': self.name, 'config': self.config, 'services': [], 'running': False, 'status': 'error', 'message': '%s When loading config: %s' % (e.message, self.config)} defer.returnValue(config_)
:param config: :type config: mcloud.config.YamlConfig :return: """ for name, command in config.get_commands().items(): cmd_instance = LocalCommand(config, command) cmd = subparsers.add_parser('*%s' % name, help=command['help']) cmd.add_argument('to', help='Host to use with command', default=None, choices=config.hosts, nargs='?') cmd.set_defaults(func=cmd_instance.call) if os.path.exists('mcloud.yml'): config = YamlConfig(file='mcloud.yml') config.load(process=False) load_commands(config) def cli(help_, arguments=None, by_ref=False, name=None): def cmd_decorator(func): cmd = subparsers.add_parser(name or func.__name__.replace('_', '-'), help=help_) command_settings[func.__name__] = { 'need_app': False } if arguments: command_settings[func.__name__]['need_app'] = arguments[0][0][0] == 'app'
def config(self, ref, diff=False, config=None, update=False, set_env=None, **kwargs): app, service = self.parse_app_ref(ref, kwargs, app_only=True) app_config = yield self._remote_exec('config', app) parser_env = set_env or app_config['env'] if diff or (not update and not set_env): old_config = YamlConfig(source=unicode(app_config['source']), app_name=app, env=parser_env) old_config.load(process=False) from collections import OrderedDict yaml.add_representer( unicode, yaml.representer.SafeRepresenter.represent_unicode) yaml.add_representer(OrderedDict, self.represent_ordereddict) olds = yaml.dump(old_config.config, default_flow_style=False) if not update and not diff and not set_env: x = PrettyTable(["Name", "Value"], hrules=ALL, align='l', header=False) x.align = "l" x.add_row(['Config', olds]) x.add_row(['Environment', app_config['env']]) x.add_row(['Path', app_config['path']]) print(x) else: if config: config_file = os.path.expanduser(config) else: config_file = 'mcloud.yml' new_config = YamlConfig(file=config_file, app_name=app, env=parser_env) new_config.load(process=False) if diff: yaml.add_representer( unicode, yaml.representer.SafeRepresenter.represent_unicode) yaml.add_representer(OrderedDict, self.represent_ordereddict) news = yaml.dump(new_config.config, default_flow_style=False) if olds == news: print('Configs are identical.') else: for line in unified_diff(olds.splitlines(1), news.splitlines(1)): if line.endswith('\n'): line = line[0:-1] if line.startswith('+'): print color_text(line, color='green') elif line.startswith('-'): print color_text(line, color='red') else: print line else: if set_env and not update: yield self._remote_exec('update', app, env=set_env) else: yield self._remote_exec('update', app, config=new_config.export(), env=set_env)
for name, command in config.get_commands().items(): cmd_instance = LocalCommand(config, command) cmd = subparsers.add_parser('*%s' % name, help=command['help']) cmd.add_argument('to', help='Host to use with command', default=None, choices=config.hosts, nargs='?') cmd.set_defaults(func=cmd_instance.call) if os.path.exists('mcloud.yml'): config = YamlConfig(file='mcloud.yml') config.load(process=False) load_commands(config) def cli(help_, arguments=None, by_ref=False, name=None): def cmd_decorator(func): cmd = subparsers.add_parser(name or func.__name__.replace('_', '-'), help=help_) command_settings[func.__name__] = {'need_app': False} if arguments: command_settings[ func.__name__]['need_app'] = arguments[0][0][0] == 'app'