Merge lp:~bjornt/landscape-charm/deploy-landscape-client into lp:~landscape/landscape-charm/trunk

Proposed by Björn Tillenius
Status: Merged
Approved by: Björn Tillenius
Approved revision: 320
Merged at revision: 317
Proposed branch: lp:~bjornt/landscape-charm/deploy-landscape-client
Merge into: lp:~landscape/landscape-charm/trunk
Diff against target: 137 lines (+133/-0)
1 file modified
dev/deploy-landscape-client (+133/-0)
To merge this branch: bzr merge lp:~bjornt/landscape-charm/deploy-landscape-client
Reviewer Review Type Date Requested Status
🤖 Landscape Builder test results Approve
Chad Smith Approve
Adam Collard (community) Approve
Review via email: mp+262313@code.launchpad.net

Commit message

Add a script for deploying landscape-client after deploying landscape-server.

The client will be configured with the right URLs and SSL certficate, so
that the deployed client will register with the deployed server.

Only the suboordinate server will be deployed. To actually get some
clients registered you have to deploy some service (like ubuntu)
yourself and relate landscape-client to it.

Description of the change

Add a script for deploying landscape-client after deploying landscape-server.

The client will be configured with the right URLs and SSL certficate, so
that the deployed client will register with the deployed server.

Only the suboordinate server will be deployed. To actually get some
clients registered you have to deploy some service (like ubuntu)
yourself and relate landscape-client to it.

To post a comment you must log in.
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: make ci-test
Result: Success
Revno: 315
Branch: lp:~bjornt/landscape-charm/deploy-landscape-client
Jenkins: https://ci.lscape.net/job/latch-test/1474/

review: Approve (test results)
Revision history for this message
Adam Collard (adam-collard) wrote :

I think this code is a bit too long to have it all in just main(), it would benefit from splitting into a few functions e.g.

get_landscape_unit()
get_ssl_cert(landscape_unit)
get_hostname(cert)

Revision history for this message
Adam Collard (adam-collard) wrote :

End goal should be to fix #1429046, is this just a step in that direction? Feels like a compromise.

review: Needs Information
316. By Björn Tillenius

Typo.

317. By Björn Tillenius

Split out functionality into smaller functions.

318. By Björn Tillenius

no ned for a space.

Revision history for this message
Björn Tillenius (bjornt) wrote :

I've addressed inline comments and have split up the function into smaller ones.

As explained in IRC, fixing bug 1429046 isn't trivial, so this script is useful in the meantime.

Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: make ci-test
Result: Success
Revno: 318
Branch: lp:~bjornt/landscape-charm/deploy-landscape-client
Jenkins: https://ci.lscape.net/job/latch-test/1483/

review: Approve (test results)
Revision history for this message
Adam Collard (adam-collard) wrote :

Script works well, there are a few things I would have done differently but nothing blocking. +1

review: Approve
Revision history for this message
Chad Smith (chad.smith) wrote :

+1 nothing but a doc comment and validating the openssl comment Adam made.

review: Approve
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: make ci-test
Result: Success
Revno: 318
Branch: lp:~bjornt/landscape-charm/deploy-landscape-client
Jenkins: https://ci.lscape.net/job/latch-test/1509/

review: Approve (test results)
319. By Björn Tillenius

Clarify that no relations are added.

Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: make ci-test
Result: Success
Revno: 319
Branch: lp:~bjornt/landscape-charm/deploy-landscape-client
Jenkins: https://ci.lscape.net/job/latch-test/1510/

review: Approve (test results)
320. By Björn Tillenius

No need to pass -e.

Revision history for this message
Björn Tillenius (bjornt) :
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: make ci-test
Result: Success
Revno: 320
Branch: lp:~bjornt/landscape-charm/deploy-landscape-client
Jenkins: https://ci.lscape.net/job/latch-test/1511/

review: Approve (test results)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'dev/deploy-landscape-client'
2--- dev/deploy-landscape-client 1970-01-01 00:00:00 +0000
3+++ dev/deploy-landscape-client 2015-06-19 09:11:30 +0000
4@@ -0,0 +1,133 @@
5+#!/usr/bin/python3
6+"""
7+This script looks at the current Juju environment and generates a
8+juju-deployer config for landscape-client that is configured to talk to
9+the deployed landscape-server service. The URLs and SSL certificate are
10+taken from the deployed landscape-server units.
11+
12+By default, landscape-client will be deployed, but you can choose to
13+only generate the juju-deployer config and deploy manually:
14+
15+ deploy-landscape-client --no-deploy > landscape-client.yaml
16+
17+The landscape-client charm is a subordinate one, so you will have to
18+related it to a principle services. For example, if you simply want some
19+test client, you can deploy 'ubuntu' and relate 'ubuntu' and
20+'landscape-client'.
21+"""
22+
23+# This import isn't strictly needed, since we don't need to support
24+# Python2, but this makes linting easier, since we have a mix of Python2
25+# and Python3 in the charm
26+from __future__ import print_function
27+
28+import argparse
29+import os.path
30+import shutil
31+import subprocess
32+import sys
33+import tempfile
34+
35+import yaml
36+
37+
38+def get_landscape_unit():
39+ """Get the name of any landscape-server unit."""
40+ status = yaml.load(subprocess.check_output(
41+ ["juju", "status", "--format", "yaml", "landscape-server"]))
42+ units = status["services"]["landscape-server"]["units"]
43+ # Any landscape-server unit will do.
44+ return next(iter(units.keys()))
45+
46+
47+def get_ssl_cert(landscape_unit, tempdir, ca_cert_name):
48+ """Fetch the SSL certificate from the Landscape unit.
49+
50+ The certficate is saved into tempdir, and the full path is returned.
51+ """
52+ ca_cert_name = "landscape_server_ca.crt"
53+ ca_cert_path = os.path.join(tempdir, ca_cert_name)
54+ subprocess.check_call(
55+ ["juju", "scp",
56+ "{}:/etc/ssl/certs/{}".format(landscape_unit, ca_cert_name),
57+ ca_cert_path])
58+ return ca_cert_path
59+
60+
61+def get_hostname(ca_cert_path, stderr):
62+ """Get the common name from a SSL certificate.
63+
64+ None is return if there is no CN in the certificate.
65+ """
66+ ca_subject = subprocess.check_output(
67+ ["openssl", "x509", "-in", ca_cert_path, "-subject", "-noout"])
68+ for subject in ca_subject.decode("utf-8").split("/"):
69+ subject = subject.strip()
70+ if subject.startswith("CN="):
71+ break
72+ else:
73+ error_msg = "Couldn't find the common name in {}: {}".format(
74+ ca_cert_path, ca_subject)
75+ print(error_msg, file=stderr)
76+ return None
77+
78+ _, host = subject.split("=", 1)
79+ return host
80+
81+
82+def generate_deploy_config(ca_cert_path, host):
83+ """Generate a juju-deployer config.
84+
85+ Return the YAML config as a string.
86+ """
87+ ca_base64 = subprocess.check_output(
88+ ["openssl", "base64", "-in", ca_cert_path]).decode("utf-8")
89+ deployer_config = {
90+ "landscape-client": {
91+ "series": "trusty",
92+ "services": {
93+ "landscape-client": {
94+ "charm": "cs:trusty/landscape-client",
95+ "options": {
96+ "account-name": "standalone",
97+ "url": "https://{}/message-system".format(host),
98+ "ping-url": "http://{}/ping".format(host),
99+ "ssl-public-key": "base64:{}".format(ca_base64),
100+ }}}}}
101+ return yaml.safe_dump(deployer_config)
102+
103+
104+def main(args, stdout=sys.stdout, stderr=sys.stderr):
105+ tempdir = tempfile.mkdtemp()
106+ landscape_unit = get_landscape_unit()
107+
108+ ca_cert_name = "landscape_server_ca.crt"
109+ print(
110+ "Copying {} from {}".format(ca_cert_name, landscape_unit), file=stderr)
111+ ca_cert_path = get_ssl_cert(landscape_unit, tempdir, ca_cert_name)
112+
113+ host = get_hostname(ca_cert_path, stderr)
114+ if host is None:
115+ return 1
116+
117+ print("Generating deployer config.", file=stderr)
118+ yaml_config = generate_deploy_config(ca_cert_path, host)
119+ config_path = os.path.join(tempdir, "landscape-client.yaml")
120+ with open(config_path, "w") as f:
121+ f.write(yaml_config)
122+ print(yaml_config, file=stdout)
123+
124+ if args.deploy:
125+ print("Deploying landscape-client.", file=stderr)
126+ subprocess.check_call(["juju-deployer", "-c", config_path])
127+ print("Cleaning up {}".format(tempdir), file=stderr)
128+ shutil.rmtree(tempdir)
129+
130+
131+if __name__ == "__main__":
132+ parser = argparse.ArgumentParser(description=__doc__)
133+ parser.add_argument(
134+ "--no-deploy", dest="deploy", action="store_false", default=True,
135+ help="Only generate deployer config, don't deploy service.")
136+ args = parser.parse_args()
137+ sys.exit(main(args))

Subscribers

People subscribed via source and target branches