diff --git a/SoftLayer/CLI/cdn/purge.py b/SoftLayer/CLI/cdn/purge.py index 7738600a3..bcf055064 100644 --- a/SoftLayer/CLI/cdn/purge.py +++ b/SoftLayer/CLI/cdn/purge.py @@ -5,6 +5,7 @@ import SoftLayer from SoftLayer.CLI import environment +from SoftLayer.CLI import formatting @click.command() @@ -12,7 +13,22 @@ @click.argument('content_url', nargs=-1) @environment.pass_env def cli(env, account_id, content_url): - """Purge cached files from all edge nodes.""" + """Purge cached files from all edge nodes. + + Examples: + slcli cdn purge 97794 http://example.com/cdn/file.txt + slcli cdn purge 97794 http://example.com/cdn/file.txt https://dal01.example.softlayer.net/image.png + """ manager = SoftLayer.CDNManager(env.client) - manager.purge_content(account_id, content_url) + content_list = manager.purge_content(account_id, content_url) + + table = formatting.Table(['url', 'status']) + + for content in content_list: + table.add_row([ + content['url'], + content['statusCode'] + ]) + + env.fout(table) diff --git a/SoftLayer/fixtures/SoftLayer_Network_ContentDelivery_Account.py b/SoftLayer/fixtures/SoftLayer_Network_ContentDelivery_Account.py index 28e043bc8..643df9c10 100644 --- a/SoftLayer/fixtures/SoftLayer_Network_ContentDelivery_Account.py +++ b/SoftLayer/fixtures/SoftLayer_Network_ContentDelivery_Account.py @@ -32,6 +32,10 @@ loadContent = True -purgeContent = True +purgeContent = [ + {'url': 'http://z/img/0z020.png', 'statusCode': 'SUCCESS'}, + {'url': 'http://y/img/0z010.png', 'statusCode': 'FAILED'}, + {'url': 'http://', 'statusCode': 'INVALID_URL'} +] -purgeCache = True +purgeCache = [{'url': 'http://example.com', 'statusCode': 'SUCCESS'}] diff --git a/SoftLayer/managers/cdn.py b/SoftLayer/managers/cdn.py index 994ab8fab..19a88efb7 100644 --- a/SoftLayer/managers/cdn.py +++ b/SoftLayer/managers/cdn.py @@ -129,17 +129,16 @@ def purge_content(self, account_id, urls): be purged. :param urls: a string or a list of strings representing the CDN URLs that should be purged. - :returns: true if all purge requests were successfully submitted; - otherwise, returns the first error encountered. + :returns: a list of SoftLayer_Container_Network_ContentDelivery_PurgeService_Response objects + which indicates if the purge for each url was SUCCESS, FAILED or INVALID_URL. """ if isinstance(urls, six.string_types): urls = [urls] + content_list = [] for i in range(0, len(urls), MAX_URLS_PER_PURGE): - result = self.account.purgeCache(urls[i:i + MAX_URLS_PER_PURGE], - id=account_id) - if not result: - return result + content = self.account.purgeCache(urls[i:i + MAX_URLS_PER_PURGE], id=account_id) + content_list.extend(content) - return True + return content_list diff --git a/tests/CLI/modules/cdn_tests.py b/tests/CLI/modules/cdn_tests.py index d15259ab5..b39e8b8eb 100644 --- a/tests/CLI/modules/cdn_tests.py +++ b/tests/CLI/modules/cdn_tests.py @@ -49,9 +49,9 @@ def test_load_content(self): def test_purge_content(self): result = self.run_command(['cdn', 'purge', '1234', 'http://example.com']) - + expected = [{"url": "http://example.com", "status": "SUCCESS"}] self.assert_no_fail(result) - self.assertEqual(result.output, "") + self.assertEqual(json.loads(result.output), expected) def test_list_origins(self): result = self.run_command(['cdn', 'origin-list', '1234']) diff --git a/tests/managers/cdn_tests.py b/tests/managers/cdn_tests.py index 6f4387760..8de4bd508 100644 --- a/tests/managers/cdn_tests.py +++ b/tests/managers/cdn_tests.py @@ -5,6 +5,7 @@ :license: MIT, see LICENSE for more details. """ import math +import mock from SoftLayer import fixtures from SoftLayer.managers import cdn @@ -110,25 +111,30 @@ def test_purge_content(self): math.ceil(len(urls) / float(cdn.MAX_URLS_PER_PURGE))) def test_purge_content_failure(self): - urls = ['http://z/img/0x004.png', + urls = ['http://', 'http://y/img/0x002.png', 'http://x/img/0x001.png'] - mock = self.set_mock('SoftLayer_Network_ContentDelivery_Account', - 'purgeCache') - mock.return_value = False + contents = [ + {'url': urls[0], 'statusCode': 'INVALID_URL'}, + {'url': urls[1], 'statusCode': 'FAILED'}, + {'url': urls[2], 'statusCode': 'FAILED'} + ] - self.cdn_client.purge_content(12345, urls) - calls = self.calls('SoftLayer_Network_ContentDelivery_Account', - 'purgeCache') - self.assertEqual(len(calls), - math.ceil(len(urls) / float(cdn.MAX_URLS_PER_PURGE))) + self.cdn_client.account = mock.Mock() + self.cdn_client.account.purgeCache.return_value = contents + + result = self.cdn_client.purge_content(12345, urls) + + self.assertEqual(contents, result) def test_purge_content_single(self): url = 'http://geocities.com/Area51/Meteor/12345/under_construction.gif' + self.cdn_client.account = mock.Mock() + self.cdn_client.account.purgeCache.return_value = [{'url': url, 'statusCode': 'SUCCESS'}] - self.cdn_client.purge_content(12345, url) - self.assert_called_with('SoftLayer_Network_ContentDelivery_Account', - 'purgeCache', - args=([url],), - identifier=12345) + expected = [{'url': url, 'statusCode': 'SUCCESS'}] + + result = self.cdn_client.purge_content(12345, url) + + self.assertEqual(expected, result)