Skip to content

Commit d153ce3

Browse files
Merge pull request #1898 from edsonarios/issue1897
Added new command - slcli cdn create
2 parents ddb1c2e + 153cb0a commit d153ce3

File tree

7 files changed

+190
-0
lines changed

7 files changed

+190
-0
lines changed

SoftLayer/CLI/cdn/create.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""Create a CDN domain mapping."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
6+
import SoftLayer
7+
from SoftLayer.CLI import environment
8+
from SoftLayer.CLI import exceptions
9+
from SoftLayer.CLI import formatting
10+
11+
12+
@click.command(cls=SoftLayer.CLI.command.SLCommand, )
13+
@click.option('--hostname', required=True, help="To route requests to your website, enter the hostname for your"
14+
"website, for example, www.example.com or app.example.com.")
15+
@click.option('--origin', required=True, help="Your server IP address or hostname.")
16+
@click.option('--origin-type', default="server", type=click.Choice(['server', 'storage']), show_default=True,
17+
help="The origin type. Note: If OriginType is storage then OriginHost is take as Endpoint")
18+
@click.option('--http', help="Http port")
19+
@click.option('--https', help="Https port")
20+
@click.option('--bucket-name', help="Bucket name")
21+
@click.option('--cname', help="Enter a globally unique subdomain. The full URL becomes the CNAME we use to configure"
22+
" your DNS. If no value is entered, we will generate a CNAME for you.")
23+
@click.option('--header', help="The edge server uses the host header in the HTTP header to communicate with the"
24+
" Origin host. It defaults to Hostname.")
25+
@click.option('--path', help="Give a path relative to the domain provided, which can be used to reach this Origin."
26+
" For example, 'articles/video' => 'www.example.com/articles/video")
27+
@click.option('--ssl', default="dvSan", type=click.Choice(['dvSan', 'wilcard']), help="A DV SAN Certificate allows"
28+
" HTTPS traffic over your personal domain, but it requires a domain validation to prove ownership."
29+
" A wildcard certificate allows HTTPS traffic only when using the CNAME given.")
30+
@environment.pass_env
31+
def cli(env, hostname, origin, origin_type, http, https, bucket_name, cname, header, path, ssl):
32+
"""Create a CDN domain mapping."""
33+
if not http and not https:
34+
raise exceptions.CLIAbort('Is needed http or https options')
35+
36+
manager = SoftLayer.CDNManager(env.client)
37+
cdn = manager.create_cdn(hostname, origin, origin_type, http, https, bucket_name, cname, header, path, ssl)
38+
39+
table = formatting.Table(['Name', 'Value'])
40+
table.add_row(['CDN Unique ID', cdn.get('uniqueId')])
41+
if bucket_name:
42+
table.add_row(['Bucket Name', cdn.get('bucketName')])
43+
table.add_row(['Hostname', cdn.get('domain')])
44+
table.add_row(['Header', cdn.get('header')])
45+
table.add_row(['IBM CNAME', cdn.get('cname')])
46+
table.add_row(['Akamai CNAME', cdn.get('akamaiCname')])
47+
table.add_row(['Origin Host', cdn.get('originHost')])
48+
table.add_row(['Origin Type', cdn.get('originType')])
49+
table.add_row(['Protocol', cdn.get('protocol')])
50+
table.add_row(['Http Port', cdn.get('httpPort')])
51+
table.add_row(['Https Port', cdn.get('httpsPort')])
52+
table.add_row(['Certificate Type', cdn.get('certificateType')])
53+
table.add_row(['Provider', cdn.get('vendorName')])
54+
table.add_row(['Path', cdn.get('path')])
55+
56+
env.fout(table)

SoftLayer/CLI/routes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
('cdn:origin-remove', 'SoftLayer.CLI.cdn.origin_remove:cli'),
8383
('cdn:purge', 'SoftLayer.CLI.cdn.purge:cli'),
8484
('cdn:delete', 'SoftLayer.CLI.cdn.delete:cli'),
85+
('cdn:create', 'SoftLayer.CLI.cdn.create:cli'),
8586

8687
('config', 'SoftLayer.CLI.config'),
8788
('config:setup', 'SoftLayer.CLI.config.setup:cli'),

SoftLayer/fixtures/SoftLayer_Network_CdnMarketplace_Configuration_Mapping.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,28 @@
7474
"vendorName": "akamai"
7575
}
7676
]
77+
createDomainMapping = [
78+
{
79+
"bucketName": "test-bucket-name",
80+
"akamaiCname": "wildcard.appdomain.mdc.edgekey.net",
81+
"cacheKeyQueryRule": "include-all",
82+
"certificateType": "WILDCARD_CERT",
83+
"cname": "test.cdn.appdomain.cloud",
84+
"createDate": "2020-09-29T15:19:01-06:00",
85+
"domain": "test.com",
86+
"header": "header.test.com",
87+
"httpPort": 80,
88+
"httpsPort": None,
89+
"modifyDate": "2021-06-24T09:02:22-06:00",
90+
"originHost": "10.32.12.125",
91+
"originType": "HOST_SERVER",
92+
"path": "/*",
93+
"performanceConfiguration": "General web delivery",
94+
"protocol": "HTTP",
95+
"respectHeaders": True,
96+
"serveStale": True,
97+
"status": "CNAME_CONFIGURATION",
98+
"uniqueId": "354034879028850",
99+
"vendorName": "akamai"
100+
}
101+
]

SoftLayer/managers/cdn.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,3 +278,62 @@ def delete_cdn(self, unique_id):
278278
"""
279279

280280
return self.cdn_configuration.deleteDomainMapping(unique_id)
281+
282+
def create_cdn(self, hostname=None, origin=None, origin_type=None, http=None, https=None, bucket_name=None,
283+
cname=None, header=None, path=None, ssl=None):
284+
"""Create CDN domain mapping for a particular customer.
285+
286+
:param str hostname: The unique ID associated with the CDN.
287+
:param str origin: ip address or hostname if origin_type=server, API endpoint for
288+
your S3 object storage if origin_type=storage
289+
:param str origin_type: it can be 'server' or 'storage' types.
290+
:param int http: http port
291+
:param int https: https port
292+
:param str bucket_name: name of the available resource
293+
:param str cname: globally unique subdomain
294+
:param str header: the edge server uses the host header to communicate with the origin.
295+
It defaults to hostname. (optional)
296+
:param str path: relative path to the domain provided, e.g. "/articles/video"
297+
:param str ssl: ssl certificate
298+
:returns: The cdn that is being created.
299+
"""
300+
types = {'server': 'HOST_SERVER', 'storage': 'OBJECT_STORAGE'}
301+
ssl_certificate = {'wilcard': 'WILDCARD_CERT', 'dvSan': 'SHARED_SAN_CERT'}
302+
303+
new_origin = {
304+
'domain': hostname,
305+
'origin': origin,
306+
'originType': types.get(origin_type),
307+
'vendorName': 'akamai',
308+
}
309+
310+
protocol = ''
311+
if http:
312+
protocol = 'HTTP'
313+
new_origin['httpPort'] = http
314+
if https:
315+
protocol = 'HTTPS'
316+
new_origin['httpsPort'] = https
317+
new_origin['certificateType'] = ssl_certificate.get(ssl)
318+
if http and https:
319+
protocol = 'HTTP_AND_HTTPS'
320+
321+
new_origin['protocol'] = protocol
322+
323+
if types.get(origin_type) == 'OBJECT_STORAGE':
324+
new_origin['bucketName'] = bucket_name
325+
new_origin['header'] = header
326+
327+
if cname:
328+
new_origin['cname'] = cname + '.cdn.appdomain.cloud'
329+
330+
if header:
331+
new_origin['header'] = header
332+
333+
if path:
334+
new_origin['path'] = '/' + path
335+
336+
origin = self.cdn_configuration.createDomainMapping(new_origin)
337+
338+
# The method createOriginPath() returns an array but there is only 1 object
339+
return origin[0]

docs/cli/cdn.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@ Interacting with CDN
3535
.. click:: SoftLayer.CLI.cdn.delete:cli
3636
:prog: cdn delete
3737
:show-nested:
38+
39+
.. click:: SoftLayer.CLI.cdn.create:cli
40+
:prog: cdn create
41+
:show-nested:

tests/CLI/modules/cdn_tests.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,35 @@ def test_delete_cdn(self):
128128
result = self.run_command(['cdn', 'delete', '123456'])
129129
self.assert_no_fail(result)
130130
self.assertIn("Cdn with uniqueId: 123456 was deleted.", result.output)
131+
132+
def test_create_cdn(self):
133+
result = self.run_command(['cdn', 'create', '--hostname', 'www.example.com',
134+
'--origin', '123.123.123.123', '--http', '80'])
135+
self.assert_no_fail(result)
136+
self.assertIn("CDN Unique ID", result.output)
137+
self.assertIn("354034879028850", result.output)
138+
self.assertIn("Hostname", result.output)
139+
self.assertIn("test.com", result.output)
140+
self.assertIn("header", result.output)
141+
self.assertIn("header.test.com", result.output)
142+
self.assertIn("Http Port", result.output)
143+
self.assertIn("80", result.output)
144+
self.assertIn("Path", result.output)
145+
self.assertIn("/*", result.output)
146+
147+
def test_create_cdn_without_hostname(self):
148+
result = self.run_command(['cdn', 'create'])
149+
self.assertEqual(2, result.exit_code)
150+
print(result.output)
151+
self.assertIn("Error: Missing option '--hostname'.", result.output)
152+
153+
def test_create_cdn_without_origin(self):
154+
result = self.run_command(['cdn', 'create', '--hostname', 'www.example.com'])
155+
self.assertEqual(2, result.exit_code)
156+
print(result.output)
157+
self.assertIn("Error: Missing option '--origin'.", result.output)
158+
159+
def test_create_cdn_without_http_or_https(self):
160+
result = self.run_command(['cdn', 'create', '--hostname', 'www.example.com', '--origin', '123.123.123.123'])
161+
self.assertEqual(2, result.exit_code)
162+
self.assertIn("Is needed http or https options", result.exception.message)

tests/managers/cdn_tests.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,16 @@ def test_delete_cdn(self):
160160
self.assert_called_with('SoftLayer_Network_CdnMarketplace_Configuration_Mapping',
161161
'deleteDomainMapping',
162162
args=args)
163+
164+
def test_create_cdn(self):
165+
hostname = "test.com"
166+
origin = "123.123.123.123"
167+
origin_type = "server"
168+
http = 80
169+
newCdn = ({"domain": hostname, "origin": origin, "originType": "HOST_SERVER",
170+
"vendorName": "akamai", "httpPort": http, "protocol": "HTTP"},)
171+
self.cdn_client.create_cdn(hostname, origin, origin_type, http)
172+
173+
self.assert_called_with('SoftLayer_Network_CdnMarketplace_Configuration_Mapping',
174+
'createDomainMapping',
175+
args=newCdn)

0 commit comments

Comments
 (0)