From 7ac7f2c0682fa63d2416a393339b0b3d2ea9d091 Mon Sep 17 00:00:00 2001 From: rsonghuster Date: Mon, 26 Aug 2019 19:36:57 +0800 Subject: [PATCH] fc support tag on service --- fc2/client.py | 84 +++++++++++++++++++++++++++++++++++++++- test/get_account_test.py | 2 - test/service_test.py | 54 ++++++++++++++++++++++++++ test/tag_test.py | 57 +++++++++++++++++++++++++++ test/trigger_test.py | 9 +++-- 5 files changed, 200 insertions(+), 6 deletions(-) create mode 100644 test/tag_test.py diff --git a/fc2/client.py b/fc2/client.py index abc9ddf..823b23c 100644 --- a/fc2/client.py +++ b/fc2/client.py @@ -343,7 +343,7 @@ def get_service(self, serviceName, headers={}, qualifier=None): r = self._do_request(method, path, headers) return FcHttpResponse(r.headers, r.json()) - def list_services(self, limit=None, nextToken=None, prefix=None, startKey=None, headers={}): + def list_services(self, limit=None, nextToken=None, prefix=None, startKey=None, headers={}, tags=None): """ List the services in the current account. :param limit: (optional, integer) the total number of the returned services. @@ -382,6 +382,10 @@ def list_services(self, limit=None, nextToken=None, prefix=None, startKey=None, paramlst = [('limit', limit), ('prefix', prefix), ('nextToken', nextToken), ('startKey', startKey)] params = dict((k, v) for k, v in paramlst if v) + + if tags: + for k, v in tags.items(): + params["tag_" + k] = v r = self._do_request(method, path, headers, params=params) return FcHttpResponse(r.headers, r.json()) @@ -1337,7 +1341,85 @@ def delete_alias(self, serviceName, aliasName, headers={}): headers = self._build_common_headers(method, path, headers) self._do_request(method, path, headers) + + def tag_resource(self, resourceArn, tags, headers={}): + """ + Tag on a resource, Currently only services are supported + :param resourceArn: (required string), Resource ARN. Either full ARN or partial ARN + :param tags:(required dict), A list of tag keys. At least 1 tag is required. At most 20. Tag key is required, but tag value is optional + :param headers, optional + 1, 'x-fc-trace-id': string (a uuid to do the request tracing) + 2, user define key value + :return: FcHttpResponse + headers: dict + data: dict, including all aliase information. + { + 'requestId': 'string' + } + """ + method = 'POST' + path = '/{0}/tag'.format(self.api_version) + headers = self._build_common_headers(method, path, headers) + payload = { + 'resourceArn': resourceArn, + 'tags': tags + } + r = self._do_request(method, path, headers, body=json.dumps(payload).encode('utf-8')) + return FcHttpResponse(r.headers, r.json()) + + def untag_resource(self, resourceArn, tagKeys, deleteAll=False, headers={}): + """ + unTag on a resource, Currently only services are supported + :param resourceArn: (required string), Resource ARN. Either full ARN or partial ARN + :param tagKeys:(optinal dict), A list of tag keys. + :param deletaAll: (optinal bool), when tagKeys is empty and deleteAll be True can take effect. + :param headers, optional + 1, 'x-fc-trace-id': string (a uuid to do the request tracing) + 2, user define key value + :return: FcHttpResponse + headers: dict + data: dict, including all aliase information. + { + 'requestId': 'string' + } + """ + method = 'DELETE' + path = '/{0}/tag'.format(self.api_version) + headers = self._build_common_headers(method, path, headers) + payload = { + 'resourceArn': resourceArn, + 'tagKeys': tagKeys, + 'all': deleteAll + } + r = self._do_request(method, path, headers, body=json.dumps(payload).encode('utf-8')) + return FcHttpResponse(r.headers, r.json()) + + def get_resource_tags(self, resourceArn, headers={}): + """ + get a resource's tags, Currently only services are supported + :param resourceArn: (required string), Resource ARN. Either full ARN or partial ARN + :param headers, optional + 1, 'x-fc-trace-id': string (a uuid to do the request tracing) + 2, user define key value + :return: FcHttpResponse + headers: dict + data: dict, including all aliase information. + { + "requestId": "rid", + "resourceArn": "acs:fc:cn-shanghai:1221968287646227:services/foo", + "tags": { + "key1": "value1", + "key2": "" + } + } + """ + method = 'GET' + path = '/{0}/tag'.format(self.api_version) + headers = self._build_common_headers(method, path, headers) + params = {"resourceArn": resourceArn} + r = self._do_request(method, path, headers, params=params) + return FcHttpResponse(r.headers, r.json()) class FcHttpResponse(object): def __init__(self, headers, data): diff --git a/test/get_account_test.py b/test/get_account_test.py index 0aa96e7..8444bce 100644 --- a/test/get_account_test.py +++ b/test/get_account_test.py @@ -3,8 +3,6 @@ import fc2 import logging - - class TestGetAccountSetting(unittest.TestCase): def __init__(self, *args, **kwargs): super(TestGetAccountSetting, self).__init__(*args, **kwargs) diff --git a/test/service_test.py b/test/service_test.py index 3cb1681..72e32a8 100644 --- a/test/service_test.py +++ b/test/service_test.py @@ -21,6 +21,8 @@ def __init__(self, *args, **kwargs): self.groupId = os.environ['GROUP_ID'] self.nasServerAddr = os.environ['NAS_SERVER_ADDR'] self.nasMountDir = os.environ['NAS_MOUNT_DIR'] + self.region = os.environ['REGION'] + self.account_id = os.environ['ACCOUNT_ID'] self.client = fc2.Client( endpoint=os.environ['ENDPOINT'], accessKeyID=os.environ['ACCESS_KEY_ID'], @@ -182,26 +184,44 @@ def _clear_list_service(self): prefix = 'test_list_' # Cleanup the resources. try: + resourceArn = "acs:fc:{0}:{1}:services/{2}".format( + self.region, self.account_id, prefix + 'abc') + self.client.untag_resource(resourceArn, [], True) self.client.delete_service(prefix + 'abc') except: pass try: + resourceArn = "acs:fc:{0}:{1}:services/{2}".format( + self.region, self.account_id, prefix + 'abd') + self.client.untag_resource(resourceArn, [], True) self.client.delete_service(prefix + 'abd') except: pass try: + resourceArn = "acs:fc:{0}:{1}:services/{2}".format( + self.region, self.account_id, prefix + 'ade') + self.client.untag_resource(resourceArn, [], True) self.client.delete_service(prefix + 'ade') except: pass try: + resourceArn = "acs:fc:{0}:{1}:services/{2}".format( + self.region, self.account_id, prefix + 'bcd') + self.client.untag_resource(resourceArn, [], True) self.client.delete_service(prefix + 'bcd') except: pass try: + resourceArn = "acs:fc:{0}:{1}:services/{2}".format( + self.region, self.account_id, prefix + 'bde') + self.client.untag_resource(resourceArn, [], True) self.client.delete_service(prefix + 'bde') except: pass try: + resourceArn = "acs:fc:{0}:{1}:services/{2}".format( + self.region, self.account_id, prefix + 'zzz') + self.client.untag_resource(resourceArn, [], True) self.client.delete_service(prefix + 'zzz') except: pass @@ -215,6 +235,15 @@ def test_list(self): self.client.create_service(prefix + 'bcd') self.client.create_service(prefix + 'bde') self.client.create_service(prefix + 'zzz') + resourceArn = "acs:fc:{0}:{1}:services/{2}".format( + self.region, self.account_id, prefix + 'abc') + self.client.tag_resource(resourceArn, {"k1": "v1", "k3": "v3"}) + resourceArn = "acs:fc:{0}:{1}:services/{2}".format( + self.region, self.account_id, prefix + 'abd') + self.client.tag_resource(resourceArn, {"k2": "v2", "k3": "v3"}) + resourceArn = "acs:fc:{0}:{1}:services/{2}".format( + self.region, self.account_id, prefix + 'ade') + self.client.tag_resource(resourceArn, {"k1": "v1", "k3": "v4"}) r = self.client.list_services(limit=2, startKey=prefix + 'b') r = r.data @@ -250,6 +279,31 @@ def test_list(self): self.assertEqual(len(services), 2) self.assertTrue(services[0]['serviceName'], prefix + 'abc') self.assertTrue(services[1]['serviceName'], prefix + 'abd') + + r = self.client.list_services(prefix=prefix + 'a', tags={"k3": "v3"}) + r = r.data + services = r['services'] + self.assertEqual(len(services), 2) + self.assertTrue(services[0]['serviceName'], prefix + 'abc') + self.assertTrue(services[1]['serviceName'], prefix + 'abd') + + r = self.client.list_services(prefix=prefix + 'a', tags={"k3": ""}) + r = r.data + services = r['services'] + self.assertEqual(len(services), 3) + + r = self.client.list_services( + prefix=prefix + 'a', tags={"k3": "v3", "k1": "v1"}) + r = r.data + services = r['services'] + self.assertEqual(len(services), 1) + self.assertTrue(services[0]['serviceName'], prefix + 'abc') + + r = self.client.list_services( + prefix=prefix + 'a', tags={"k3": "v3", "k1": "v1", "k2": "v2"}) + r = r.data + services = r['services'] + self.assertEqual(len(services), 0) # list services with prefix and startKey r = self.client.list_services(limit=2, prefix=prefix + 'ab', startKey=prefix + 'abd') diff --git a/test/tag_test.py b/test/tag_test.py new file mode 100644 index 0000000..c352fd5 --- /dev/null +++ b/test/tag_test.py @@ -0,0 +1,57 @@ +import unittest +import os +import fc2 +import logging + +class TestTag(unittest.TestCase): + def __init__(self, *args, **kwargs): + super(TestTag, self).__init__(*args, **kwargs) + self.access_key_id = os.environ['ACCESS_KEY_ID'] + self.access_key_secret = os.environ['ACCESS_KEY_SECRET'] + self.endpoint = os.environ['ENDPOINT'] + self.region = os.environ['REGION'] + self.account_id = os.environ['ACCOUNT_ID'] + + self.client = fc2.Client( + endpoint=self.endpoint, + accessKeyID=self.access_key_id, + accessKeySecret=self.access_key_secret, + ) + + def test_all_tag_op(self): + prefix = "test_tag_" + for i in range(3): + try: + self.client.delete_service(prefix + str(i)) + except: + pass + + for i in range(3): + self.client.create_service(prefix + str(i)) + resourceArn = "acs:fc:{0}:{1}:services/{2}".format(self.region, self.account_id, prefix + str(i)) + self.client.tag_resource(resourceArn, { "k3": "v3"}) + if i % 2 == 0: + self.client.tag_resource(resourceArn, {"k1": "v1"}) + else: + self.client.tag_resource(resourceArn, {"k2": "v2"}) + + resp = self.client.get_resource_tags(resourceArn).data + self.assertEqual(resourceArn, resp['resourceArn']) + if i % 2 == 0: + self.assertEqual(resp['tags'], {"k1": "v1", "k3" : "v3"}) + else: + self.assertEqual(resp['tags'], {"k2": "v2", "k3": "v3"}) + + self.client.untag_resource(resourceArn, ["k3"]) + + resp = self.client.get_resource_tags(resourceArn).data + self.assertEqual(resourceArn, resp['resourceArn']) + if i % 2 == 0: + self.assertEqual(resp['tags'], {"k1": "v1"}) + else: + self.assertEqual(resp['tags'], {"k2": "v2"}) + + self.client.untag_resource(resourceArn, [], True) + resp = self.client.get_resource_tags(resourceArn).data + self.assertEqual(resourceArn, resp['resourceArn']) + self.assertEqual(0, len(resp['tags'])) diff --git a/test/trigger_test.py b/test/trigger_test.py index 27c52fa..4d450c5 100644 --- a/test/trigger_test.py +++ b/test/trigger_test.py @@ -20,10 +20,13 @@ def __init__(self, *args, **kwargs): self.invocation_role_sls = os.environ['INVOCATION_ROLE_SLS'] self.log_project = os.environ['LOG_PROJECT'] self.log_store = os.environ['LOG_STORE'] - self.service_name = 'test_trigger_service' - self.function_name = 'test_trigger_function' + self.service_name = 'test_trigger_service' + \ + ''.join(random.choice(string.ascii_lowercase) for _ in range(8)) + self.function_name = 'test_trigger_function' + \ + ''.join(random.choice(string.ascii_lowercase) for _ in range(8)) self.http_function_name = 'test_http_function' - self.trigger_name = 'test_trigger' + ''.join(random.choice(string.ascii_lowercase) for _ in range(8)) + self.trigger_name = 'test_trigger' + \ + ''.join(random.choice(string.ascii_lowercase) for _ in range(8)) self.client = fc2.Client( endpoint=self.endpoint,