Permalink
Switch branches/tags
v0.1.0 dockerhub-latest ansible-service-broker-1.4.2-1 ansible-service-broker-1.4.1-1 ansible-service-broker-1.3.20-1 ansible-service-broker-1.3.19-1 ansible-service-broker-1.3.18-1 ansible-service-broker-1.3.17-1 ansible-service-broker-1.3.16-1 ansible-service-broker-1.3.15-1 ansible-service-broker-1.3.14-1 ansible-service-broker-1.3.13-1 ansible-service-broker-1.3.12-1 ansible-service-broker-1.3.11-1 ansible-service-broker-1.3.10-1 ansible-service-broker-1.3.9-1 ansible-service-broker-1.3.8-1 ansible-service-broker-1.3.7-1 ansible-service-broker-1.3.6-1 ansible-service-broker-1.3.5-1 ansible-service-broker-1.3.4-1 ansible-service-broker-1.3.3-1 ansible-service-broker-1.3.2-1 ansible-service-broker-1.3.1-1 ansible-service-broker-1.2.21-1 ansible-service-broker-1.2.20-1 ansible-service-broker-1.2.19-1 ansible-service-broker-1.2.18-1 ansible-service-broker-1.2.17-1 ansible-service-broker-1.2.16-1 ansible-service-broker-1.2.15-1 ansible-service-broker-1.2.14-1 ansible-service-broker-1.2.13-1 ansible-service-broker-1.2.12-1 ansible-service-broker-1.2.11-1 ansible-service-broker-1.2.10-1 ansible-service-broker-1.2.9-1 ansible-service-broker-1.2.8-1 ansible-service-broker-1.2.7-1 ansible-service-broker-1.2.6-1 ansible-service-broker-1.2.5-1 ansible-service-broker-1.2.4-1 ansible-service-broker-1.2.3-1 ansible-service-broker-1.2.2-1 ansible-service-broker-1.2.1-1 ansible-service-broker-1.1.18-1 ansible-service-broker-1.1.17-1 ansible-service-broker-1.1.16-1 ansible-service-broker-1.1.15-1 ansible-service-broker-1.1.14-1 ansible-service-broker-1.1.13-1 ansible-service-broker-1.1.12-1 ansible-service-broker-1.1.11-1 ansible-service-broker-1.1.10-1 ansible-service-broker-1.1.9-1 ansible-service-broker-1.1.8-1 ansible-service-broker-1.1.7-1 ansible-service-broker-1.1.6-1 ansible-service-broker-1.1.5-1 ansible-service-broker-1.1.4-1 ansible-service-broker-1.1.3-1 ansible-service-broker-1.1.2-1 ansible-service-broker-1.1.1-1 ansible-service-broker-1.0.21-1 ansible-service-broker-1.0.20-1 ansible-service-broker-1.0.19-1 ansible-service-broker-1.0.18-1 ansible-service-broker-1.0.17-1 ansible-service-broker-1.0.15-1 ansible-service-broker-1.0.14-1 ansible-service-broker-1.0.13-1 ansible-service-broker-1.0.12-1 ansible-service-broker-1.0.11-1 ansible-service-broker-1.0.10-1 ansible-service-broker-1.0.9-1 ansible-service-broker-1.0.8-1 ansible-service-broker-1.0.7-1 ansible-service-broker-1.0.6-1 ansible-service-broker-1.0.5-1 ansible-service-broker-1.0.4-1 ansible-service-broker-1.0.3-1 ansible-service-broker-1.0.2-1 ansible-service-broker-1.0.1-1 ansible-service-broker-0.9.11-1 ansible-service-broker-0.9.10-1 ansible-service-broker-0.9.9-1 ansible-service-broker-0.9.8-1 ansible-service-broker-0.9.7-1 ansible-service-broker-0.9.6-1 ansible-service-broker-0.9.5-1 ansible-service-broker-0.9.4-1 ansible-service-broker-0.9.3-1 ansible-service-broker-0.9.2-1 ansible-service-broker-0.9.1-1
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 213 lines (168 sloc) 6.41 KB
#! /usr/bin/env python
import sys
import base64
import subprocess
# Output some nicer errors if a user doesn't have the required packages
try:
import yaml
except Exception:
print("No yaml parsing modules installed, try: pip install pyyaml")
sys.exit(1)
try:
import requests
except Exception:
print("requests module not installed, try: pip install requests")
sys.exit(1)
try:
from apb.engine import broker_request
except Exception:
print("apb module not installed, try: pip install apb")
sys.exit(1)
# Work around python2/3 input differences
try:
input = raw_input
except NameError:
pass
USAGE = """USAGE:
{command} NAME NAMESPACE IMAGE [BROKER_NAME] [KEY=VALUE]* [@FILE]*
NAME: the name of the secret to create/replace
NAMESPACE: the target namespace of the secret. It should be the namespace of the broker for most usecases
IMAGE: the docker image you would like to associate with the secret
BROKER_NAME: the name of the k8s ServiceBroker resource. Defaults to ansible-service-broker
KEY: a key to create inside the secret. This cannot contain an "=" sign
VALUE: the value for the KEY in the secret
FILE: a yaml loadable file containing key: value pairs. A file must begin with an "@" symbol to be loaded
EXAMPLE:
{command} mysecret ansible-service-broker docker.io/ansibleplaybookbundle/hello-world-apb key1=hello key2=world @additional_keys.yml
"""
DATA_SEPARATOR = "\n "
SECRET_TEMPLATE = """---
apiVersion: v1
kind: Secret
metadata:
name: {name}
namespace: {namespace}
data:
{data}
"""
def main():
name = sys.argv[1]
namespace = sys.argv[2]
apb = sys.argv[3]
if '=' not in sys.argv[4] and '@' not in sys.argv[4]:
broker_name = sys.argv[4]
idx = 4
else:
broker_name = None
idx = 3
keyvalues = list(map(
lambda x: x.split("=", 1),
filter(lambda x: "=" in x, sys.argv[idx:])
))
files = list(filter(lambda x: x.startswith("@"), sys.argv[idx:]))
data = keyvalues + parse_files(files)
runcmd('oc project {}'.format(namespace))
try:
runcmd('oc get dc asb')
except Exception:
raise Exception("Error: No broker deployment found in namespace {}".format(namespace))
create_secret(name, namespace, data)
changed = update_config(name, broker_name, apb)
if changed:
print("Rolling out a new broker...")
runcmd('oc rollout latest asb')
def parse_files(files):
params = []
for file in files:
file_name = file[1:]
with open(file_name, 'r') as f:
params.extend(yaml.load(f.read()).items())
return params
def create_secret(name, namespace, data):
encoded = [(quote(k), base64.b64encode(quote(v))) for (k, v) in data]
secret = SECRET_TEMPLATE.format(
name=name,
namespace=namespace,
data=DATA_SEPARATOR.join(map(": ".join, encoded))
)
with open('/tmp/{name}-secret'.format(name=name), 'w') as f:
f.write(secret)
try:
runcmd('oc create -f /tmp/{name}-secret'.format(name=name))
except Exception:
runcmd('oc replace -f /tmp/{name}-secret'.format(name=name))
print('Created secret: \n\n{}'.format(secret))
def quote(string):
return '"{}"'.format(string)
def update_config(name, broker_name, apb):
config = get_broker_config()
secret_entry = {"secret": name, "apb_name": fqname(apb, broker_name, config), "title": name}
if secret_entry not in config['data']['broker-config'].get('secrets', []):
config['data']['broker-config']['secrets'] = config['data']['broker-config'].get('secrets', []) + [secret_entry]
config_s = format_config(config)
with open('/tmp/broker-config', 'w') as f:
f.write(config_s)
runcmd('oc replace -f /tmp/broker-config'.format(name=name))
print('Updated broker config to \n\n{}'.format(config_s))
return True
else:
print("Skipping update to broker configuration becuase secret entry was already present")
return False
def format_config(config):
config['data']['broker-config'] = yaml.dump(config['data']['broker-config'])
for key in ('creationTimestamp', 'resourceVersion', 'selfLink', 'uid'):
del config['metadata'][key]
return yaml.dump(config)
def broker_auth(config):
credentials = {'basic_auth_username': None, 'basic_auth_password': None}
auth_settings = config['data']['broker-config']['broker'].get('auth')[0]
if auth_settings.get('type') == 'basic' and auth_settings.get('enabled'):
secret = yaml.load(runcmd('oc get secret asb-auth-secret -o yaml'))
credentials = {
"basic_auth_{}".format(k): base64.b64decode(v)
for (k, v) in secret['data'].items()
}
return credentials
def get_all_apbs(broker_name, config):
response = broker_request(None, "/v2/catalog", "get", verify=False, broker_name=broker_name, **broker_auth(config))
return response.json()['services']
def fqname(apb, broker_name, config):
search_pattern = apb.split('/')[-1].split(':')[0]
candidates = get_all_apbs(broker_name, config)
matches = [
str(candidate['name']) for candidate in candidates
if search_pattern in candidate['name']
]
if not matches:
print("ERROR: No matches found for {}".format(apb))
print("apbs found: \n\t- {}".format('\n\t- '.join(
map(lambda x: x['name'], candidates))
))
sys.exit(1)
elif len(matches) > 1:
print("Multiple apbs match...\n")
for i, match in enumerate(matches):
print('{}: {}'.format(i+1, match))
choice = int(input("\nWhich apb would you like to associate?: ")) - 1
match = matches[choice]
else:
match = matches[0]
print("Associating secret with {}".format(match))
return match
def get_broker_config():
config = yaml.load(runcmd("oc get configmap broker-config -o yaml"))
config['data']['broker-config'] = yaml.load(config['data']['broker-config'])
return config
def runcmd(cmd):
print("Running: {}".format(cmd))
return subprocess.check_output(cmd.split())
if __name__ == '__main__':
if len(sys.argv) < 5 or sys.argv[1] in ("-h", "--help"):
print(USAGE.format(command=sys.argv[0]))
sys.exit()
try:
main()
except Exception:
print("Invalid invocation")
print(USAGE.format(command=sys.argv[0]))
raise