def request_config(self, client: ConfigClient, filter_options: str) -> Any: self.line("<options=bold>\U000023f3 contacting server...</>") try: auth = None if self.option("auth"): username, password = self.option("auth").split(":") auth = HTTPBasicAuth(username, password) elif self.option("digest"): username, password = self.option("digest").split(":") auth = HTTPDigestAuth(username, password) # type: ignore client.get_config(auth=auth) # type: ignore except ValueError: emoji = random.choice(self.EMOJI_ERRORS) self.line( f"<options=bold>{emoji} bad credentials format for auth method. Format expected: user:password {emoji}</>" ) raise SystemExit(1) except ConnectionError: emoji = random.choice(self.EMOJI_ERRORS) self.line( f"<options=bold>{emoji} failed to contact server... {emoji}</>" ) raise SystemExit(1) self.print_contact_server_ok() content = self.get_config(client, filter_options) self.has_content(content, filter_options) return content
def setUp(self): """Mock of responses generated by Spring Cloud Config.""" self.config_example = { "health": { "config": { "enabled": False } }, "spring": { "cloud": { "consul": { "discovery": { "health-check-interval": "10s", "health-check-path": "/manage/health", "instance-id": "pecas-textos:${random.value}", "prefer-ip-address": True, "register-health-check": True }, "host": "discovery", "port": 8500 } } } } self.obj = ConfigClient( app_name='test-app', url='{address}/{branch}/{app_name}-{profile}.yaml')
def __attrs_post_init__(self) -> None: if not self.oauth2: self.oauth2 = OAuth2( access_token_uri=self.cfenv.configserver_access_token_uri(), client_id=self.cfenv.configserver_client_id(), client_secret=self.cfenv.configserver_client_secret()) if not self.client: self.client = ConfigClient(address=self.cfenv.configserver_uri(), app_name=self.cfenv.application_name) self.oauth2.configure()
def request_config(self, client: ConfigClient, filter_options: str) -> Any: self.line("<options=bold>\U000023f3 contacting server...</>") try: client.get_config() except ConnectionError: emoji = random.choice(self.EMOJI_ERRORS) self.line(f"<options=bold>{emoji} failed to contact server... {emoji}</>") raise SystemExit(1) self.print_contact_server_ok() content = self.get_config(client, filter_options) self.has_content(content, filter_options) return content
def handle(self): client = ConfigClient( address=os.getenv("CONFIGSERVER_ADDRESS", self.option("address")), fail_fast=False, ) try: resp = client.encrypt(self.argument("data"), path=self.option("path")) except Exception: self.line("<options=bold>failed to contact server... </>") raise SystemExit(1) if not self.option("raw") == "yes": self.line(f"'{{cipher}}{resp}'") else: self.line(resp)
def __attrs_post_init__(self) -> None: if not self.oauth2: self.oauth2 = OAuth2( access_token_uri=self.cfenv.configserver_access_token_uri(), client_id=self.cfenv.configserver_client_id(), client_secret=self.cfenv.configserver_client_secret(), ) if not self.client: self.client = ConfigClient( address=self.cfenv.configserver_uri(), app_name=self.cfenv.application_name, profile=self.cfenv.space_name.lower(), oauth2=self.oauth2, )
def handle(self): client = ConfigClient( address=os.getenv("CONFIGSERVER_ADDRESS", self.option("address")), fail_fast=False, ) try: data = re.match(r"^.?{cipher}?(?P<name>\w.*)", self.argument("data")).group("name") except AttributeError: data = self.argument("data") try: resp = client.decrypt(data, path=self.option("path")) except Exception: self.line("<options=bold>failed to contact server... </>") raise SystemExit(1) self.line(resp)
def handle(self) -> None: filter_options = self.argument("filter") or "" host = os.getenv("CONFIGSERVER_ADDRESS", self.option("address")) url = os.getenv("CONFIGSERVER_CUSTOM_URL") if not url: url = f"{host}/{self.option('branch')}/{self.argument('app')}-{self.option('profile')}.json" client = ConfigClient( address=os.getenv("CONFIGSERVER_ADDRESS", self.option("address")), branch=os.getenv("BRANCH", self.option("branch")), app_name=os.getenv("APP_NAME", self.argument("app")), profile=os.getenv("PROFILE", self.option("profile")), url=self.option("url") or url, fail_fast=False, ) if self.option("file"): self.request_file(client, filter_options) raise SystemExit(0) content = self.request_config(client, filter_options) if self.option("json"): self.save_file("output.json", content) else: self.std_output(filter_options, content)
class CF: cfenv = attr.ib( type=CFenv, factory=CFenv, validator=attr.validators.instance_of(CFenv), ) oauth2 = attr.ib(type=OAuth2, default=None) client = attr.ib(type=ConfigClient, default=None) def __attrs_post_init__(self) -> None: if not self.oauth2: self.oauth2 = OAuth2( access_token_uri=self.cfenv.configserver_access_token_uri(), client_id=self.cfenv.configserver_client_id(), client_secret=self.cfenv.configserver_client_secret(), ) if not self.client: self.client = ConfigClient( address=self.cfenv.configserver_uri(), app_name=self.cfenv.application_name, profile=self.cfenv.space_name.lower(), ) self.oauth2.configure() @property def vcap_services(self): return self.cfenv.vcap_services @property def vcap_application(self): return self.cfenv.vcap_application def get_config(self) -> None: header = {"Authorization": f"Bearer {self.oauth2.token}"} self.client.get_config(headers=header) @property def config(self) -> Dict: return self.client.config def get_attribute(self, value: str) -> Any: return self.client.get_attribute(value) def get_keys(self) -> KeysView: return self.client.get_keys()
def __init__(self, app: web.Application, key: str = "config", client=ConfigClient()) -> None: self._validate_app(app) self._validate_client(client) client.get_config() app[str(key)] = _Config(client.config)
def test_custom_url_property(self): obj = ConfigClient(app_name='test-app', branch='development', url="{address}/{branch}/{profile}-{app_name}.json") self.assertIsInstance(obj.url, str) self.assertEqual(obj.branch, 'development') self.assertEqual( obj.url, "http://localhost:8888/development/development-test-app.json")
def configure_custom_client(self, MockRequests): custom_client = ConfigClient( address="http://localhost:8888/configuration", app_name="myapp") custom_oauth2 = OAuth2( access_token_uri="http://localhost/token", client_id="id", client_secret="secret", ) return CF(oauth2=custom_oauth2, client=custom_client)
def test_custom_properties(self): oauth2 = OAuth2( access_token_uri='http://localhost/token', client_id='id', client_secret='secret' ) client = ConfigClient(address='http://localhost', app_name='test_app') cf = CF(oauth2=oauth2, client=client) self.assertEqual(cf.client, client) self.assertEqual(cf.oauth2, oauth2)
def request_file(self, client: ConfigClient, filter_options: str) -> None: self.line("<options=bold>\U000023f3 contacting server...</>") try: response = client.get_file(filter_options) except RequestFailedException: emoji = random.choice(self.EMOJI_ERRORS) self.line(f"<options=bold>{emoji} failed to contact server... {emoji}</>") raise SystemExit(1) with open(f"{filter_options}", "w") as f: f.write(response) self.line(f"file saved: <info>{filter_options}</info>")
def configure_custom_client(self, MockRequests): custom_client = ConfigClient( address='http://localhost:8888/configuration', app_name='myapp' ) custom_oauth2 = OAuth2( access_token_uri='http://localhost/token', client_id='id', client_secret='secret' ) return CF(oauth2=custom_oauth2, client=custom_client)
def test_custom_properties(self, monkeypatch): monkeypatch.setattr(requests, "post", ResponseMock) oauth2 = OAuth2( access_token_uri="http://localhost/token", client_id="id", client_secret="secret", ) client = ConfigClient(address="http://localhost", app_name="test_app") cf = CF(oauth2=oauth2, client=client) assert cf.client, client assert cf.oauth2, oauth2
def client_with_auth(self, monkeypatch, mocker): monkeypatch.setattr(requests, "post", conftest.response_mock_success) mocker.patch.object(requests, "get") requests.get.return_value = conftest.ResponseMock() return ConfigClient( app_name="test_app", oauth2=OAuth2( access_token_uri= "https://p-spring-cloud-services.uaa.sys.example.com/oauth/token", client_id="p-config-server-example-client-id", client_secret="EXAMPLE_SECRET", ), )
class CF: cfenv = attr.ib( type=CFenv, factory=CFenv, validator=attr.validators.instance_of(CFenv), ) oauth2 = attr.ib(type=OAuth2, default=None) client = attr.ib(type=ConfigClient, default=None) def __attrs_post_init__(self) -> None: if not self.oauth2: self.oauth2 = OAuth2( access_token_uri=self.cfenv.configserver_access_token_uri(), client_id=self.cfenv.configserver_client_id(), client_secret=self.cfenv.configserver_client_secret(), ) if not self.client: self.client = ConfigClient( address=self.cfenv.configserver_uri(), app_name=self.cfenv.application_name, profile=self.cfenv.space_name.lower(), oauth2=self.oauth2, ) @property def vcap_services(self): return self.cfenv.vcap_services @property def vcap_application(self): return self.cfenv.vcap_application def get_config(self, **kwargs) -> None: self.client.get_config(**kwargs) @property def config(self) -> Dict: return self.client.config def get_attribute(self, value: str) -> Any: return self.client.get_attribute(value) def get(self, key, default: Any = ""): return self.client.get(key, default) def get_keys(self) -> KeysView: return self.client.get_keys() def keys(self) -> KeysView: return self.client.keys()
class TestConfigClient(unittest.TestCase): """Unit tests to spring module.""" def setUp(self): """Mock of responses generated by Spring Cloud Config.""" self.config_example = { "health": { "config": { "enabled": False } }, "spring": { "cloud": { "consul": { "discovery": { "health-check-interval": "10s", "health-check-path": "/manage/health", "instance-id": "pecas-textos:${random.value}", "prefer-ip-address": True, "register-health-check": True }, "host": "discovery", "port": 8500 } } } } self.obj = ConfigClient( app_name='test-app', url='{address}/{branch}/{app_name}-{profile}.yaml') def test_get_config_failed(self): """Test failed to connect on ConfigClient.""" with self.assertRaises(SystemExit): self.obj.get_config() @patch('config.spring.requests.get', return_value=ResponseMock()) def test_get_config(self, RequestMock): self.obj.get_config() self.assertDictEqual(self.obj.config, self.config_example) @patch('config.spring.requests.get', return_value=ResponseMock(code=402, ok=False)) def test_get_config_response_failed(self, RequestMock): with self.assertRaises(SystemExit): self.obj.get_config() def test_config_property(self): self.assertIsInstance(self.obj.config, dict) def test_default_url_property(self): self.assertIsInstance(self.obj.url, str) self.assertEqual( self.obj.url, "http://*****:*****@patch('config.spring.requests.get', return_value=ResponseMock()) def test_decorator(self, RequestMock): @config_client(app_name='myapp') def inner_method(c=None): self.assertIsInstance(c, ConfigClient) return c response = inner_method() self.assertIsNotNone(response) def test_decorator_failed(self): @config_client() def inner_method(c=None): self.assertEqual(ConfigClient(), c) with self.assertRaises(SystemExit): inner_method() def test_fix_valid_url_extension(self): self.assertEqual( self.obj.url, "http://*****:*****@patch('config.spring.requests.get', return_value=ResponseMock()) def test_create_config_client_with_singleton(self, RequestMock): client1 = create_config_client(app_name='simpleweb000') client2 = create_config_client(app_name='simpleweb999') self.assertEqual(client1, client2)
def test_fix_url_extension_without_profile(self): client = ConfigClient(app_name="simpleweb000", url="{address}/{branch}/{app_name}") self.assertEqual(client.url, "http://localhost:8888/master/simpleweb000.json")
def inner_method(c=None): self.assertEqual(ConfigClient(), c)
def test_fail_fast_disabled(self, monkeypatch): monkeypatch.setattr(requests, "get", Exception) client = ConfigClient(app_name="test_app", fail_fast=False) with pytest.raises(ConnectionError): client.get_config()
def test_url_setter(self, pattern, expected): client = ConfigClient(app_name="test_app") client.url = pattern assert client.url == expected
def client(self, monkeypatch): return ConfigClient(app_name="test_app")
def client(self, monkeypatch, scope="module"): return ConfigClient(app_name="test_app")
def test_integration_with_config_client_inst(self, app, resp_mock): AioHttpConfig(app, client=ConfigClient(app_name="myapp")) assert isinstance(app["config"], dict)
class TestConfigClient(unittest.TestCase): """Unit tests to spring module.""" def setUp(self): """Mock of responses generated by Spring Cloud Config.""" self.config_example = { "health": { "config": { "enabled": False } }, "spring": { "cloud": { "consul": { "discovery": { "health-check-interval": "10s", "health-check-path": "/manage/health", "instance-id": "pecas-textos:${random.value}", "prefer-ip-address": True, "register-health-check": True }, "host": "discovery", "port": 8500 } } } } self.obj = ConfigClient( app_name='test-app', url='{address}/{branch}/{app_name}-{profile}.yaml') def test_get_config_failed(self): """Test failed to connect on ConfigClient.""" with self.assertRaises(SystemExit): self.obj.get_config() @patch('urllib.request.urlopen', return_value=ResponseMock()) def test_get_config(self, RequestMock): self.obj.get_config() self.assertDictEqual(self.obj.config, self.config_example) @patch('urllib.request.urlopen', return_value=ResponseMock(code=402)) def test_get_config_response_failed(self, RequestMock): with self.assertRaises(Exception): self.obj.get_config() def test_config_property(self): self.assertIsInstance(self.obj.config, dict) def test_default_url_property(self): self.assertIsInstance(self.obj.url, str) self.assertEqual( self.obj.url, "http://*****:*****@unittest.skip('skipping due singleton use.') def test_custom_url_property(self): obj = ConfigClient(app_name='test-app', branch='development', url="{address}/{branch}/{profile}-{app_name}.json") self.assertIsInstance(obj.url, str) self.assertEqual(obj.branch, 'development') self.assertEqual( obj.url, "http://*****:*****@patch('urllib.request.urlopen', return_value=ResponseMock()) def test_decorator(self, RequestMock): @config_client(app_name='myapp') def inner_method(c=None): self.assertEqual(ConfigClient(), c) return c response = inner_method() self.assertIsNotNone(response) def test_decorator_failed(self): @config_client() def inner_method(c=None): self.assertEqual(ConfigClient(), c) with self.assertRaises(SystemExit): inner_method() def test_fix_valid_url_extension(self): self.assertTrue(self.obj.url.endswith('json'))
def test_custom_url_property(self): client = ConfigClient( app_name="test_app", url="{address}/{branch}/{profile}-{app_name}.yaml", ) assert client.url == "http://localhost:8888/master/development-test_app.json"
def test_integration_with_config_client_inst(self, app, resp_mock): FlaskConfig(app, ConfigClient(app_name="myapp")) assert isinstance(app.config, _Config)
def get_config(self, client: ConfigClient, filter_options: str) -> Any: if self.option("all"): content = client.config else: content = client.get_attribute(f"{filter_options}") return content