Support adding API keys to client configs
Sets the groundwork for the remainder of #65
This commit is contained in:
parent
c26ee544a9
commit
10d892c698
|
@ -24,6 +24,7 @@ import socket
|
||||||
import click
|
import click
|
||||||
import tempfile
|
import tempfile
|
||||||
import os
|
import os
|
||||||
|
import stat
|
||||||
import subprocess
|
import subprocess
|
||||||
import difflib
|
import difflib
|
||||||
import re
|
import re
|
||||||
|
@ -63,7 +64,12 @@ def read_from_yaml(cfgfile):
|
||||||
scheme = 'https'
|
scheme = 'https'
|
||||||
else:
|
else:
|
||||||
scheme = 'http'
|
scheme = 'http'
|
||||||
return host, port, scheme
|
if strtobool(api_config['pvc']['api']['authentication']['enabled']):
|
||||||
|
# Always use the first token
|
||||||
|
api_key = api_config['pvc']['api']['authentication']['tokens'][0]['token']
|
||||||
|
else:
|
||||||
|
api_key = 'N/A'
|
||||||
|
return host, port, scheme, api_key
|
||||||
|
|
||||||
def get_config(store_data, cluster=None):
|
def get_config(store_data, cluster=None):
|
||||||
# This is generally static
|
# This is generally static
|
||||||
|
@ -79,7 +85,7 @@ def get_config(store_data, cluster=None):
|
||||||
# This is a reference to an API configuration; grab the details from its listen address
|
# This is a reference to an API configuration; grab the details from its listen address
|
||||||
cfgfile = cluster_details.get('cfgfile')
|
cfgfile = cluster_details.get('cfgfile')
|
||||||
if os.path.isfile(cfgfile):
|
if os.path.isfile(cfgfile):
|
||||||
host, port, scheme = read_from_yaml(cfgfile)
|
host, port, scheme, api_key = read_from_yaml(cfgfile)
|
||||||
else:
|
else:
|
||||||
return { 'badcfg': True }
|
return { 'badcfg': True }
|
||||||
else:
|
else:
|
||||||
|
@ -87,12 +93,14 @@ def get_config(store_data, cluster=None):
|
||||||
host = cluster_details['host']
|
host = cluster_details['host']
|
||||||
port = cluster_details['port']
|
port = cluster_details['port']
|
||||||
scheme = cluster_details['scheme']
|
scheme = cluster_details['scheme']
|
||||||
|
api_key = cluster_details['api_key']
|
||||||
|
|
||||||
config = dict()
|
config = dict()
|
||||||
config['debug'] = False
|
config['debug'] = False
|
||||||
config['cluster'] = cluster
|
config['cluster'] = cluster
|
||||||
config['api_host'] = '{}:{}'.format(host, port)
|
config['api_host'] = '{}:{}'.format(host, port)
|
||||||
config['api_scheme'] = scheme
|
config['api_scheme'] = scheme
|
||||||
|
config['api_key'] = api_key
|
||||||
config['api_prefix'] = prefix
|
config['api_prefix'] = prefix
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
@ -107,6 +115,8 @@ def update_store(store_path, store_data):
|
||||||
store_file = '{}/pvc-cli.json'.format(store_path)
|
store_file = '{}/pvc-cli.json'.format(store_path)
|
||||||
with open(store_file, 'w') as fh:
|
with open(store_file, 'w') as fh:
|
||||||
fh.write(json.dumps(store_data, sort_keys=True, indent=4))
|
fh.write(json.dumps(store_data, sort_keys=True, indent=4))
|
||||||
|
# Ensure file has 0600 permissions due to API key storage
|
||||||
|
os.chmod(store_file, 0o600)
|
||||||
|
|
||||||
home_dir = os.environ.get('HOME', None)
|
home_dir = os.environ.get('HOME', None)
|
||||||
if home_dir:
|
if home_dir:
|
||||||
|
@ -158,10 +168,14 @@ def cli_cluster():
|
||||||
'-s/-S', '--ssl/--no-ssl', 'ssl', is_flag=True, default=False, show_default=True,
|
'-s/-S', '--ssl/--no-ssl', 'ssl', is_flag=True, default=False, show_default=True,
|
||||||
help='Whether to use SSL or not.'
|
help='Whether to use SSL or not.'
|
||||||
)
|
)
|
||||||
|
@click.option(
|
||||||
|
'-k', '--api-key', 'api_key', required=False, default=None,
|
||||||
|
help='An API key to authenticate against the cluster.'
|
||||||
|
)
|
||||||
@click.argument(
|
@click.argument(
|
||||||
'name'
|
'name'
|
||||||
)
|
)
|
||||||
def cluster_add(address, port, ssl, name):
|
def cluster_add(address, port, ssl, name, api_key):
|
||||||
"""
|
"""
|
||||||
Add a new PVC cluster NAME, via its API connection details, to the configuration of the local CLI client. Replaces any existing cluster with this name.
|
Add a new PVC cluster NAME, via its API connection details, to the configuration of the local CLI client. Replaces any existing cluster with this name.
|
||||||
"""
|
"""
|
||||||
|
@ -176,7 +190,8 @@ def cluster_add(address, port, ssl, name):
|
||||||
existing_config[name] = {
|
existing_config[name] = {
|
||||||
'host': address,
|
'host': address,
|
||||||
'port': port,
|
'port': port,
|
||||||
'scheme': scheme
|
'scheme': scheme,
|
||||||
|
'api_key': api_key
|
||||||
}
|
}
|
||||||
# Update the store
|
# Update the store
|
||||||
update_store(store_path, existing_config)
|
update_store(store_path, existing_config)
|
||||||
|
@ -218,7 +233,8 @@ def cluster_list():
|
||||||
name_length = 5
|
name_length = 5
|
||||||
address_length = 10
|
address_length = 10
|
||||||
port_length = 5
|
port_length = 5
|
||||||
scheme_length = 5
|
scheme_length = 7
|
||||||
|
api_key_length = 8
|
||||||
|
|
||||||
for cluster in clusters:
|
for cluster in clusters:
|
||||||
cluster_details = clusters[cluster]
|
cluster_details = clusters[cluster]
|
||||||
|
@ -226,13 +242,16 @@ def cluster_list():
|
||||||
# This is a reference to an API configuration; grab the details from its listen address
|
# This is a reference to an API configuration; grab the details from its listen address
|
||||||
cfgfile = cluster_details.get('cfgfile')
|
cfgfile = cluster_details.get('cfgfile')
|
||||||
if os.path.isfile(cfgfile):
|
if os.path.isfile(cfgfile):
|
||||||
address, port, scheme = read_from_yaml(cfgfile)
|
address, port, scheme, api_key = read_from_yaml(cfgfile)
|
||||||
else:
|
else:
|
||||||
address, port, scheme = 'N/A', 'N/A', 'N/A'
|
address, port, scheme, api_key = 'N/A', 'N/A', 'N/A', 'N/A'
|
||||||
else:
|
else:
|
||||||
address = cluster_details.get('host', 'N/A')
|
address = cluster_details.get('host', 'N/A')
|
||||||
port = cluster_details.get('port', 'N/A')
|
port = cluster_details.get('port', 'N/A')
|
||||||
scheme = cluster_details.get('scheme', 'N/A')
|
scheme = cluster_details.get('scheme', 'N/A')
|
||||||
|
api_key = cluster_details.get('api_key', 'N/A')
|
||||||
|
if not api_key:
|
||||||
|
api_key = 'N/A'
|
||||||
|
|
||||||
_name_length = len(cluster) + 1
|
_name_length = len(cluster) + 1
|
||||||
if _name_length > name_length:
|
if _name_length > name_length:
|
||||||
|
@ -246,12 +265,15 @@ def cluster_list():
|
||||||
_scheme_length = len(scheme) + 1
|
_scheme_length = len(scheme) + 1
|
||||||
if _scheme_length > scheme_length:
|
if _scheme_length > scheme_length:
|
||||||
scheme_length = _scheme_length
|
scheme_length = _scheme_length
|
||||||
|
_api_key_length = len(api_key) + 1
|
||||||
|
if _api_key_length > api_key_length:
|
||||||
|
api_key_length = _api_key_length
|
||||||
|
|
||||||
# Display the data nicely
|
# Display the data nicely
|
||||||
click.echo("Available clusters:")
|
click.echo("Available clusters:")
|
||||||
click.echo()
|
click.echo()
|
||||||
click.echo(
|
click.echo(
|
||||||
'{bold}{name: <{name_length}} {address: <{address_length}} {port: <{port_length}} {scheme: <{scheme_length}}{end_bold}'.format(
|
'{bold}{name: <{name_length}} {address: <{address_length}} {port: <{port_length}} {scheme: <{scheme_length}} {api_key: <{api_key_length}}{end_bold}'.format(
|
||||||
bold=ansiprint.bold(),
|
bold=ansiprint.bold(),
|
||||||
end_bold=ansiprint.end(),
|
end_bold=ansiprint.end(),
|
||||||
name="Name",
|
name="Name",
|
||||||
|
@ -261,7 +283,9 @@ def cluster_list():
|
||||||
port="Port",
|
port="Port",
|
||||||
port_length=port_length,
|
port_length=port_length,
|
||||||
scheme="Scheme",
|
scheme="Scheme",
|
||||||
scheme_length=scheme_length
|
scheme_length=scheme_length,
|
||||||
|
api_key="API Key",
|
||||||
|
api_key_length=api_key_length
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -270,18 +294,22 @@ def cluster_list():
|
||||||
if cluster_details.get('cfgfile', None):
|
if cluster_details.get('cfgfile', None):
|
||||||
# This is a reference to an API configuration; grab the details from its listen address
|
# This is a reference to an API configuration; grab the details from its listen address
|
||||||
if os.path.isfile(cfgfile):
|
if os.path.isfile(cfgfile):
|
||||||
address, port, scheme = read_from_yaml(cfgfile)
|
address, port, scheme, api_key = read_from_yaml(cfgfile)
|
||||||
else:
|
else:
|
||||||
address = 'N/A'
|
address = 'N/A'
|
||||||
port = 'N/A'
|
port = 'N/A'
|
||||||
scheme = 'N/A'
|
scheme = 'N/A'
|
||||||
|
api_key = 'N/A'
|
||||||
else:
|
else:
|
||||||
address = cluster_details.get('host', 'N/A')
|
address = cluster_details.get('host', 'N/A')
|
||||||
port = cluster_details.get('port', 'N/A')
|
port = cluster_details.get('port', 'N/A')
|
||||||
scheme = cluster_details.get('scheme', 'N/A')
|
scheme = cluster_details.get('scheme', 'N/A')
|
||||||
|
api_key = cluster_details.get('api_key', 'N/A')
|
||||||
|
if not api_key:
|
||||||
|
api_key = 'N/A'
|
||||||
|
|
||||||
click.echo(
|
click.echo(
|
||||||
'{bold}{name: <{name_length}} {address: <{address_length}} {port: <{port_length}} {scheme: <{scheme_length}}{end_bold}'.format(
|
'{bold}{name: <{name_length}} {address: <{address_length}} {port: <{port_length}} {scheme: <{scheme_length}} {api_key: <{api_key_length}}{end_bold}'.format(
|
||||||
bold='',
|
bold='',
|
||||||
end_bold='',
|
end_bold='',
|
||||||
name=cluster,
|
name=cluster,
|
||||||
|
@ -291,7 +319,9 @@ def cluster_list():
|
||||||
port=port,
|
port=port,
|
||||||
port_length=port_length,
|
port_length=port_length,
|
||||||
scheme=scheme,
|
scheme=scheme,
|
||||||
scheme_length=scheme_length
|
scheme_length=scheme_length,
|
||||||
|
api_key=api_key,
|
||||||
|
api_key_length=api_key_length
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue