Merge lp:~gandelman-a/charms/precise/nova-compute/https_endpoint into lp:~openstack-charmers/charms/precise/nova-compute/ha-support

Proposed by Adam Gandelman
Status: Merged
Merged at revision: 48
Proposed branch: lp:~gandelman-a/charms/precise/nova-compute/https_endpoint
Merge into: lp:~openstack-charmers/charms/precise/nova-compute/ha-support
Diff against target: 383 lines (+231/-20)
4 files modified
hooks/lib/openstack-common (+219/-18)
hooks/nova-compute-common (+1/-1)
hooks/nova-compute-relations (+10/-0)
revision (+1/-1)
To merge this branch: bzr merge lp:~gandelman-a/charms/precise/nova-compute/https_endpoint
Reviewer Review Type Date Requested Status
James Page Approve
Review via email: mp+150381@code.launchpad.net

Description of the change

Required nova-compute changes for HTTPS support.

To post a comment you must log in.
Revision history for this message
James Page (james-page) wrote :

Works for me!

review: Approve
52. By Adam Gandelman

Rebase against current ha-support branch.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'hooks/lib/openstack-common'
2--- hooks/lib/openstack-common 2013-03-08 21:13:57 +0000
3+++ hooks/lib/openstack-common 2013-03-08 21:37:22 +0000
4@@ -321,7 +321,6 @@
5
6 HAPROXY_CFG=/etc/haproxy/haproxy.cfg
7 HAPROXY_DEFAULT=/etc/default/haproxy
8-
9 ##########################################################################
10 # Description: Configures HAProxy services for Openstack API's
11 # Parameters:
12@@ -330,9 +329,8 @@
13 # assumes the name of the peer relation is 'cluster' and that every
14 # service unit in the peer relation is running the same services.
15 #
16-# The HAProxy service will listen on port + 10000.
17-# Example:
18-# configure_haproxy cinder_api:12345 nova_api:9999
19+# Example
20+# configure_haproxy cinder_api:8776:8756i nova_api:8774:8764
21 ##########################################################################
22 configure_haproxy() {
23 local address=`unit-get private-address`
24@@ -368,14 +366,18 @@
25 EOF
26 for service in $@; do
27 local service_name=$(echo $service | cut -d : -f 1)
28- local api_listen_port=$(echo $service | cut -d : -f 2)
29- local haproxy_listen_port=$(($api_listen_port + 10000))
30+ local haproxy_listen_port=$(echo $service | cut -d : -f 2)
31+ local api_listen_port=$(echo $service | cut -d : -f 3)
32+ juju-log "Adding haproxy configuration entry for $service "\
33+ "($haproxy_listen_port -> $api_listen_port)"
34 cat >> $HAPROXY_CFG << EOF
35 listen $service_name 0.0.0.0:$haproxy_listen_port
36 balance roundrobin
37 option tcplog
38 server $name $address:$api_listen_port check
39 EOF
40+ local r_id=""
41+ local unit=""
42 for r_id in `relation-ids cluster`; do
43 for unit in `relation-list -r $r_id`; do
44 local unit_name=${unit////-}
45@@ -388,6 +390,7 @@
46 done
47 done
48 echo "ENABLED=1" > $HAPROXY_DEFAULT
49+ service haproxy restart
50 }
51
52 ##########################################################################
53@@ -395,18 +398,20 @@
54 # Returns: 0 if configured, 1 if not configured
55 ##########################################################################
56 is_clustered() {
57+ local r_id=""
58+ local unit=""
59 for r_id in $(relation-ids ha); do
60 if [ -n "$r_id" ]; then
61 for unit in $(relation-list -r $r_id); do
62 clustered=$(relation-get -r $r_id clustered $unit)
63 if [ -n "$clustered" ]; then
64- echo "Unit is clustered"
65+ juju-log "Unit is haclustered"
66 return 0
67 fi
68 done
69 fi
70 done
71- echo "Unit is not clustered"
72+ juju-log "Unit is not haclustered"
73 return 1
74 }
75
76@@ -415,6 +420,7 @@
77 ##########################################################################
78 peer_units() {
79 local peers=""
80+ local r_id=""
81 for r_id in $(relation-ids cluster); do
82 peers="$peers $(relation-list -r $r_id)"
83 done
84@@ -433,11 +439,11 @@
85 echo "Comparing $JUJU_UNIT_NAME with peers: $peers"
86 local r_unit_no=$(echo $peer | cut -d / -f 2)
87 if (($r_unit_no<$l_unit_no)); then
88- echo "Not oldest peer; deferring"
89+ juju-log "Not oldest peer; deferring"
90 return 1
91 fi
92 done
93- echo "Oldest peer; might take charge?"
94+ juju-log "Oldest peer; might take charge?"
95 return 0
96 }
97
98@@ -451,13 +457,13 @@
99 eligible_leader() {
100 if is_clustered; then
101 if ! is_leader $1; then
102- echo 'Deferring action to CRM leader'
103+ juju-log 'Deferring action to CRM leader'
104 return 1
105 fi
106 else
107 peers=$(peer_units)
108 if [ -n "$peers" ] && ! oldest_peer "$peers"; then
109- echo 'Deferring action to oldest service unit.'
110+ juju-log 'Deferring action to oldest service unit.'
111 return 1
112 fi
113 fi
114@@ -469,14 +475,14 @@
115 # Returns: 0 if peered, 1 if not peered
116 ##########################################################################
117 is_peered() {
118- r_id=$(relation-ids cluster)
119+ local r_id=$(relation-ids cluster)
120 if [ -n "$r_id" ]; then
121 if [ -n "$(relation-list -r $r_id)" ]; then
122- echo "Unit peered"
123+ juju-log "Unit peered"
124 return 0
125 fi
126 fi
127- echo "Unit not peered"
128+ juju-log "Unit not peered"
129 return 1
130 }
131
132@@ -489,12 +495,207 @@
133 hostname=`hostname`
134 if [ -x /usr/sbin/crm ]; then
135 if crm resource show $1 | grep -q $hostname; then
136- echo "$hostname is cluster leader"
137+ juju-log "$hostname is cluster leader."
138 return 0
139 fi
140 fi
141- echo "$hostname is not cluster leader"
142- return 1
143+ juju-log "$hostname is not cluster leader."
144+ return 1
145+}
146+
147+##########################################################################
148+# Description: Determines whether enough data has been provided in
149+# configuration or relation data to configure HTTPS.
150+# Parameters: None
151+# Returns: 0 if HTTPS can be configured, 1 if not.
152+##########################################################################
153+https() {
154+ local r_id=""
155+ if [[ -n "$(config-get ssl_cert)" ]] &&
156+ [[ -n "$(config-get ssl_key)" ]] ; then
157+ return 0
158+ fi
159+ for r_id in $(relation-ids identity-service) ; do
160+ for unit in $(relation-list -r $r_id) ; do
161+ if [[ "$(relation-get -r $r_id https_keystone $unit)" == "True" ]] &&
162+ [[ -n "$(relation-get -r $r_id ssl_cert $unit)" ]] &&
163+ [[ -n "$(relation-get -r $r_id ssl_key $unit)" ]] &&
164+ [[ -n "$(relation-get -r $r_id ca_cert $unit)" ]] ; then
165+ return 0
166+ fi
167+ done
168+ done
169+ return 1
170+}
171+
172+##########################################################################
173+# Description: For a given number of port mappings, configures apache2
174+# HTTPs local reverse proxying using certficates and keys provided in
175+# either configuration data (preferred) or relation data. Assumes ports
176+# are not in use (calling charm should ensure that).
177+# Parameters: Variable number of proxy port mappings as
178+# $internal:$external.
179+# Returns: 0 if reverse proxy(s) have been configured, 0 if not.
180+##########################################################################
181+enable_https() {
182+ local port_maps="$@"
183+ local http_restart=""
184+ juju-log "Enabling HTTPS for port mappings: $port_maps."
185+
186+ # allow overriding of keystone provided certs with those set manually
187+ # in config.
188+ local cert=$(config-get ssl_cert)
189+ local key=$(config-get ssl_key)
190+ local ca_cert=""
191+ if [[ -z "$cert" ]] || [[ -z "$key" ]] ; then
192+ juju-log "Inspecting identity-service relations for SSL certificate."
193+ local r_id=""
194+ cert=""
195+ key=""
196+ ca_cert=""
197+ for r_id in $(relation-ids identity-service) ; do
198+ for unit in $(relation-list -r $r_id) ; do
199+ [[ -z "$cert" ]] && cert="$(relation-get -r $r_id ssl_cert $unit)"
200+ [[ -z "$key" ]] && key="$(relation-get -r $r_id ssl_key $unit)"
201+ [[ -z "$ca_cert" ]] && ca_cert="$(relation-get -r $r_id ca_cert $unit)"
202+ done
203+ done
204+ [[ -n "$cert" ]] && cert=$(echo $cert | base64 -di)
205+ [[ -n "$key" ]] && key=$(echo $key | base64 -di)
206+ [[ -n "$ca_cert" ]] && ca_cert=$(echo $ca_cert | base64 -di)
207+ else
208+ juju-log "Using SSL certificate provided in service config."
209+ fi
210+
211+ [[ -z "$cert" ]] || [[ -z "$key" ]] &&
212+ juju-log "Expected but could not find SSL certificate data, not "\
213+ "configuring HTTPS!" && return 1
214+
215+ apt-get -y install apache2
216+ a2enmod ssl proxy proxy_http | grep -v "To activate the new configuration" &&
217+ http_restart=1
218+
219+ mkdir -p /etc/apache2/ssl/$CHARM
220+ echo "$cert" >/etc/apache2/ssl/$CHARM/cert
221+ echo "$key" >/etc/apache2/ssl/$CHARM/key
222+ if [[ -n "$ca_cert" ]] ; then
223+ juju-log "Installing Keystone supplied CA cert."
224+ echo "$ca_cert" >/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt
225+ update-ca-certificates --fresh
226+
227+ # XXX TODO: Find a better way of exporting this?
228+ if [[ "$CHARM" == "nova-cloud-controller" ]] ; then
229+ [[ -e /var/www/keystone_juju_ca_cert.crt ]] &&
230+ rm -rf /var/www/keystone_juju_ca_cert.crt
231+ ln -s /usr/local/share/ca-certificates/keystone_juju_ca_cert.crt \
232+ /var/www/keystone_juju_ca_cert.crt
233+ fi
234+
235+ fi
236+ for port_map in $port_maps ; do
237+ local ext_port=$(echo $port_map | cut -d: -f1)
238+ local int_port=$(echo $port_map | cut -d: -f2)
239+ juju-log "Creating apache2 reverse proxy vhost for $port_map."
240+ cat >/etc/apache2/sites-available/${CHARM}_${ext_port} <<END
241+Listen $ext_port
242+NameVirtualHost *:$ext_port
243+<VirtualHost *:$ext_port>
244+ ServerName $(unit-get private-address)
245+ SSLEngine on
246+ SSLCertificateFile /etc/apache2/ssl/$CHARM/cert
247+ SSLCertificateKeyFile /etc/apache2/ssl/$CHARM/key
248+ ProxyPass / http://localhost:$int_port/
249+ ProxyPassReverse / http://localhost:$int_port/
250+ ProxyPreserveHost on
251+</VirtualHost>
252+<Proxy *>
253+ Order deny,allow
254+ Allow from all
255+</Proxy>
256+<Location />
257+ Order allow,deny
258+ Allow from all
259+</Location>
260+END
261+ a2ensite ${CHARM}_${ext_port} | grep -v "To activate the new configuration" &&
262+ http_restart=1
263+ done
264+ if [[ -n "$http_restart" ]] ; then
265+ service apache2 restart
266+ fi
267+}
268+
269+##########################################################################
270+# Description: Ensure HTTPS reverse proxying is disabled for given port
271+# mappings.
272+# Parameters: Variable number of proxy port mappings as
273+# $internal:$external.
274+# Returns: 0 if reverse proxy is not active for all portmaps, 1 on error.
275+##########################################################################
276+disable_https() {
277+ local port_maps="$@"
278+ local http_restart=""
279+ juju-log "Ensuring HTTPS disabled for $port_maps."
280+ ( [[ ! -d /etc/apache2 ]] || [[ ! -d /etc/apache2/ssl/$CHARM ]] ) && return 0
281+ for port_map in $port_maps ; do
282+ local ext_port=$(echo $port_map | cut -d: -f1)
283+ local int_port=$(echo $port_map | cut -d: -f2)
284+ if [[ -e /etc/apache2/sites-available/${CHARM}_${ext_port} ]] ; then
285+ juju-log "Disabling HTTPS reverse proxy for $CHARM $port_map."
286+ a2dissite ${CHARM}_${ext_port} | grep -v "To activate the new configuration" &&
287+ http_restart=1
288+ fi
289+ done
290+ if [[ -n "$http_restart" ]] ; then
291+ service apache2 restart
292+ fi
293+}
294+
295+
296+##########################################################################
297+# Description: Ensures HTTPS is either enabled or disabled for given port
298+# mapping.
299+# Parameters: Variable number of proxy port mappings as
300+# $internal:$external.
301+# Returns: 0 if HTTPS reverse proxy is in place, 1 if it is not.
302+##########################################################################
303+setup_https() {
304+ # configure https via apache reverse proxying either
305+ # using certs provided by config or keystone.
306+ [[ -z "$CHARM" ]] &&
307+ error_out "setup_https(): CHARM not set."
308+ if ! https ; then
309+ disable_https $@
310+ else
311+ enable_https $@
312+ fi
313+}
314+
315+##########################################################################
316+# Description: Determine correct API server listening port based on
317+# existence of HTTPS reverse proxy and/or haproxy.
318+# Paremeters: The standard public port for given service.
319+# Returns: The correct listening port for API service.
320+##########################################################################
321+determine_api_port() {
322+ local public_port="$1"
323+ local i=0
324+ ( [[ -n "$(peer_units)" ]] || is_clustered >/dev/null 2>&1 ) && i=$[$i + 1]
325+ https >/dev/null 2>&1 && i=$[$i + 1]
326+ echo $[$public_port - $[$i * 10]]
327+}
328+
329+##########################################################################
330+# Description: Determine correct proxy listening port based on public IP +
331+# existence of HTTPS reverse proxy.
332+# Paremeters: The standard public port for given service.
333+# Returns: The correct listening port for haproxy service public address.
334+##########################################################################
335+determine_haproxy_port() {
336+ local public_port="$1"
337+ local i=0
338+ https >/dev/null 2>&1 && i=$[$i + 1]
339+ echo $[$public_port - $[$i * 10]]
340 }
341
342 ##########################################################################
343
344=== modified file 'hooks/nova-compute-common'
345--- hooks/nova-compute-common 2013-01-18 12:37:32 +0000
346+++ hooks/nova-compute-common 2013-03-08 21:37:22 +0000
347@@ -130,7 +130,7 @@
348 && exit 0
349 set_or_update "network_api_class" "nova.network.quantumv2.api.API"
350 set_or_update "quantum_auth_strategy" "keystone"
351- set_or_update "quantum_url" "http://$(relation-get quantum_host):9696"
352+ set_or_update "quantum_url" "$(relation-get quantum_url)"
353 set_or_update "quantum_admin_tenant_name" "$(relation-get service_tenant)"
354 set_or_update "quantum_admin_username" "$(relation-get service_username)"
355 set_or_update "quantum_admin_password" "$(relation-get service_password)"
356
357=== modified file 'hooks/nova-compute-relations'
358--- hooks/nova-compute-relations 2013-01-25 15:19:57 +0000
359+++ hooks/nova-compute-relations 2013-03-08 21:37:22 +0000
360@@ -217,6 +217,16 @@
361 esac
362 fi
363
364+ # If Keytone is configured manage SSL certs, nova-compute needs a copy
365+ # of its CA installed.
366+ local ca_cert="$(relation-get ca_cert)"
367+ if [[ -n "$ca_cert" ]] ; then
368+ juju-log "Installing Keystone CA certificate."
369+ ca_cert="$(echo $ca_cert | base64 -di)"
370+ echo "$ca_cert" >/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt
371+ update-ca-certificates
372+ fi
373+
374 # restart on all changed events. nova-c-c may send out a uuid to trigger
375 # remote restarts of services here (after db migrations, for instance)
376 service_ctl all restart
377
378=== modified file 'revision'
379--- revision 2013-03-05 17:25:32 +0000
380+++ revision 2013-03-08 21:37:22 +0000
381@@ -1,1 +1,1 @@
382-84
383+86

Subscribers

People subscribed via source and target branches