cf-charmers team mailing list archive
-
cf-charmers team
-
Mailing list archive
-
Message #00641
[Merge] lp:~johnsca/charms/trusty/cloudfoundry/reconciler-auth into lp:~cf-charmers/charms/trusty/cloudfoundry/trunk
Cory Johns has proposed merging lp:~johnsca/charms/trusty/cloudfoundry/reconciler-auth into lp:~cf-charmers/charms/trusty/cloudfoundry/trunk.
Requested reviews:
Cloud Foundry Charmers (cf-charmers)
For more details, see:
https://code.launchpad.net/~johnsca/charms/trusty/cloudfoundry/reconciler-auth/+merge/243340
Uses the CF admin user username and password (admin / whatever-was-passed-into-cfdeploy).
--
Your team Cloud Foundry Charmers is requested to review the proposed merge of lp:~johnsca/charms/trusty/cloudfoundry/reconciler-auth into lp:~cf-charmers/charms/trusty/cloudfoundry/trunk.
=== modified file 'charmhelpers/core/services/base.py'
--- charmhelpers/core/services/base.py 2014-11-20 17:40:26 +0000
+++ charmhelpers/core/services/base.py 2014-12-01 22:39:38 +0000
@@ -2,7 +2,7 @@
import json
import hashlib
import inspect
-from collections import Iterable
+from collections import Iterable, OrderedDict
from charmhelpers.core import host
from charmhelpers.core import hookenv
@@ -108,7 +108,7 @@
self._ready_file = os.path.join(hookenv.charm_dir(), 'READY-SERVICES.json')
self._data_hash_file = os.path.join(hookenv.charm_dir(), 'DATA-HASHES.json')
self._ready = None
- self.services = {}
+ self.services = OrderedDict()
for service in services or []:
service_name = service['service']
self.services[service_name] = service
=== modified file 'hooks/common.py'
--- hooks/common.py 2014-11-07 21:18:42 +0000
+++ hooks/common.py 2014-12-01 22:39:38 +0000
@@ -7,6 +7,7 @@
import yaml
from urlparse import urlparse
+from charmhelpers.core import host
from charmhelpers.core import hookenv
from charmhelpers.core import services
@@ -17,6 +18,7 @@
from cloudfoundry.contexts import OrchestratorRelation
from cloudfoundry.contexts import CloudFoundryCredentials
from cloudfoundry.contexts import RequiredConfig
+from cloudfoundry.contexts import StoredContext
from cloudfoundry.path import path
from cloudfoundry.utils import wait_for
from cloudfoundry.utils import socket_open
@@ -66,7 +68,11 @@
bundle = generator.build_deployment(placement)['cloudfoundry']
wait_for(300, 5, socket_open)
hookenv.log(json.dumps(bundle))
- requests.post('http://localhost:8888/api/v1/', data=json.dumps(bundle))
+ creds = CloudFoundryCredentials().provide_data()
+ username = creds['admin-user']
+ password = creds['admin-password']
+ requests.post('http://localhost:8888/api/v1/', data=json.dumps(bundle),
+ auth=(username, password))
def cache_unit_addresses(s):
@@ -116,28 +122,29 @@
return
manager = services.ServiceManager([
{
- 'service': 'bundle',
+ 'service': 'nfs-kernel-server',
'required_data': [
- JujuAPICredentials(),
+ RequiredConfig('mirror_artifacts') == True, # noqa
RequiredConfig('artifacts_url') != '',
+ {'nfs_units': OrchestratorRelation.remote_units()},
],
- 'provided_data': [OrchestratorRelation(),
- CloudFoundryCredentials()],
'data_ready': [
- cache_unit_addresses,
- deploy,
+ precache_job_artifacts,
+ services.render_template('nfs-exports',
+ target='/etc/exports'),
],
- 'start': [],
- 'stop': [],
},
{
'service': 'reconciler',
'ports': [8888],
'required_data': [
JujuAPICredentials(),
+ CloudFoundryCredentials.remote_view(),
RequiredConfig('artifacts_url') != '',
{'charm_dir': hookenv.charm_dir(),
'environment_uuid': os.environ.get('JUJU_ENV_UUID')},
+ StoredContext('.reconciler_cookie_secret.yaml',
+ {'cookie_secret': host.pwgen(20)}),
],
'data_ready': [
services.render_template('reconciler-upstart.conf',
@@ -147,17 +154,18 @@
],
},
{
- 'service': 'nfs-kernel-server',
+ 'service': 'bundle',
'required_data': [
- RequiredConfig('mirror_artifacts') == True, # noqa
+ JujuAPICredentials(),
RequiredConfig('artifacts_url') != '',
- {'nfs_units': OrchestratorRelation.remote_units()},
],
+ 'provided_data': [OrchestratorRelation(), CloudFoundryCredentials()],
'data_ready': [
- precache_job_artifacts,
- services.render_template('nfs-exports',
- target='/etc/exports'),
+ cache_unit_addresses,
+ deploy,
],
+ 'start': [],
+ 'stop': [],
},
])
manager.manage()
=== modified file 'reconciler/app.py'
--- reconciler/app.py 2014-11-20 16:09:27 +0000
+++ reconciler/app.py 2014-12-01 22:39:38 +0000
@@ -40,6 +40,7 @@
import time
import subprocess
import hashlib
+import base64
import tornado.autoreload
import tornado.httpserver
@@ -233,6 +234,30 @@
return self.settings['config']
+def require_basic_auth(handler_class):
+ def wrap_execute(handler_execute):
+ def _check_auth(header):
+ global application
+ username = application.config['credentials']['app']['user']
+ password = application.config['credentials']['app']['password']
+ if not header.startswith('Basic '):
+ return False
+ auth = base64.decodestring(header[6:]).split(':')
+ return auth == [username, password]
+
+ def _execute(handler, *args, **kwargs):
+ if not _check_auth(handler.request.headers.get('Authorization', '')):
+ handler.set_status(401)
+ handler.set_header('WWW-Authenticate', 'Basic realm=Restricted')
+ handler._transforms = []
+ handler.finish()
+ return False
+ return handler_execute(handler, *args, **kwargs)
+ return _execute
+ handler_class._execute = wrap_execute(handler_class._execute)
+ return handler_class
+
+
def main():
define('config', default='/etc/juju-deployer/server.conf', type=path)
@@ -240,7 +265,7 @@
default_config = {
'server.address': '127.0.0.1',
'server.port': 8888,
- 'credentials.user': 'user-admin',
+ 'credentials.juju.user': 'user-admin',
'server.repository': 'build',
'runtime.observe': True,
'runtime.modify': True,
@@ -255,14 +280,14 @@
application = ReconcilerWebApp([
(r'/static/(.*)', tornado.web.StaticFileHandler,
{'path': static_resources}),
- (r"/dashboard.ws", DashboardIO),
- (r"/api/v1/", StateHandler),
- (r"/api/v1/status", StatusHandler),
- (r"/api/v1/history", HistoryHandler),
- (r"/api/v1/strategy", StrategyHandler),
- (r"/debug/api/v1/reset", ResetHandler),
- (r"/debug/api/v1/prev", PrevHandler),
- (r"/", MainHandler)
+ (r"/dashboard.ws", require_basic_auth(DashboardIO)),
+ (r"/api/v1/", require_basic_auth(StateHandler)),
+ (r"/api/v1/status", require_basic_auth(StatusHandler)),
+ (r"/api/v1/history", require_basic_auth(HistoryHandler)),
+ (r"/api/v1/strategy", require_basic_auth(StrategyHandler)),
+ (r"/debug/api/v1/reset", require_basic_auth(ResetHandler)),
+ (r"/debug/api/v1/prev", require_basic_auth(PrevHandler)),
+ (r"/", require_basic_auth(MainHandler))
],
autoreload=True,
config=config,
=== modified file 'reconciler/strategy.py'
--- reconciler/strategy.py 2014-11-11 18:22:53 +0000
+++ reconciler/strategy.py 2014-12-01 22:39:38 +0000
@@ -49,8 +49,8 @@
self._env = self.get_env(
env_name=c.get('juju.environment'),
api_address=api_address,
- user=c['credentials.user'],
- password=c['credentials.password'])
+ user=c['credentials.juju.user'],
+ password=c['credentials.juju.password'])
return self._env
@property
=== modified file 'templates/reconciler-config.conf'
--- templates/reconciler-config.conf 2014-11-06 23:37:55 +0000
+++ templates/reconciler-config.conf 2014-12-01 22:39:38 +0000
@@ -7,13 +7,20 @@
{% endif %}
},
"credentials": {
- "user": "user-admin",
- "password": "{{api_password}}"
+ "juju": {
+ "user": "user-admin",
+ "password": "{{api_password}}"
+ },
+ "app": {
+ "user": "{{credentials[0]['admin-user']}}",
+ "password": "{{credentials[0]['admin-password']}}"
+ }
},
"server": {
"address": "0.0.0.0",
"port": 8888,
- "repository": "build"
+ "repository": "build",
+ "cookie_secret": "{{cookie_secret}}"
},
"runtime": {
"observe": true,