Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ __pycache__/

*.swp

.idea/

# C extensions
*.so

Expand Down Expand Up @@ -102,3 +104,6 @@ ENV/

# mypy
.mypy_cache/

# exuberant ctags
tags
85 changes: 80 additions & 5 deletions infraboxcli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
import os
import sys

from infraboxcli.push import push
from infraboxcli.run import run
from infraboxcli.graph import graph
from infraboxcli.validate import validate
from infraboxcli.init import init
from infraboxcli.list_jobs import list_jobs
from infraboxcli.log import logger
from infraboxcli.init import init
from infraboxcli.pull import pull
from infraboxcli.push import push
from infraboxcli.run import run
from infraboxcli.validate import validate

from infraboxcli.dashboard import user
from infraboxcli.dashboard import project

version = '0.6.3'

Expand Down Expand Up @@ -90,10 +93,73 @@ def main():
parser_run.add_argument("--local-cache", required=False, type=str,
default="/tmp/{}/infrabox/local-cache".format(username),
help="Path to the local cache")

parser_run.add_argument("--memory", required=False, type=float,
help="Override a memory limit for your job")
parser_run.add_argument("--cpu", required=False, type=float,
help="Override a cpu limit for your job")
parser_run.set_defaults(no_rm=False)
parser_run.set_defaults(func=run)

# Collaborators
parser_collaborators = sub_parser.add_parser('collaborators', help='Add or remove collaborators for your project')
sub_collaborators = parser_collaborators.add_subparsers()

parser_list_collaborators = sub_collaborators.add_parser('list', help='Show collaborators list')
parser_list_collaborators.add_argument('--verbose', required=False, default=True, type=str2bool)
parser_list_collaborators.set_defaults(func=project.list_collaborators)

parser_add_collaborator = sub_collaborators.add_parser('add', help='Add a collaborator')
parser_add_collaborator.add_argument('--username', required=True, type=str,
help='Username of the collaborator you want to add')
parser_add_collaborator.set_defaults(func=project.add_collaborator)

parser_remove_collaborator = sub_collaborators.add_parser('remove', help='Remove a collaborator')
parser_remove_collaborator.add_argument('--username', required=True, type=str,
help='Username of the collaborator you want to remove')
parser_remove_collaborator.set_defaults(func=project.remove_collaborator)

# Secrets
parser_secrets = sub_parser.add_parser('secrets', help='Create or delete secrets')
sub_secrets = parser_secrets.add_subparsers()

parser_create_secret = sub_secrets.add_parser('create', help='Create a secret')
parser_create_secret.add_argument('--name', required=True, type=str, help='Name of the secret')
parser_create_secret.add_argument('--value', required=True, type=str, help='Value of the secret')
parser_create_secret.set_defaults(func=project.add_secret)

parser_delete_secret = sub_secrets.add_parser('delete', help='Delete a secret')
parser_delete_secret.add_argument('--name', required=True, type=str, help='Name of the secret you want to delete')
parser_delete_secret.set_defaults(func=project.delete_secret)

# Tokens
parsers_project_tokens = sub_parser.add_parser('project-token', help='Manage your project tokens')
sub_project_tokens = parsers_project_tokens.add_subparsers()

parser_list_project_tokens = sub_project_tokens.add_parser('list', help='Show all your project tokens')
parser_list_project_tokens.add_argument('--verbose', required=False, default=True, type=str2bool)
parser_list_project_tokens.set_defaults(func=project.list_project_tokens)

parser_add_project_token = sub_project_tokens.add_parser('create', help='Create a project token')
parser_add_project_token.add_argument('--description', required=True, type=str,
help='Description of the project token you want to create')
#TODO<Steffen> when scope push/pull functionality is implemented, uncomment following 2 lines
#parser_add_project_token.add_argument('--scope_push', required=False, default=True, type=str2bool, help='Scope push')
#parser_add_project_token.add_argument('--scope_pull', required=False, default=True, type=str2bool, help='Scope pull')
parser_add_project_token.set_defaults(func=project.add_project_token)

parser_remove_project_token = sub_project_tokens.add_parser('delete', help='Delete a project token')
parser_remove_project_token.add_argument('--id', required=False, type=str,
help='Id of the project token you want to delete')
parser_remove_project_token.add_argument('--description', required=False, type=str,
help='Description of the project token you want to delete')
parser_remove_project_token.set_defaults(func=project.delete_project_token)

# User
parser_login = sub_parser.add_parser('login', help='Login to infrabox')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add optional parameters for email and password so we can use it in scripts

parser_login.add_argument('--email', required=False, default=None, type=str, help='Email of the user')
parser_login.add_argument('--password', required=False, default=None, type=str, help='Password of the user')
parser_login.set_defaults(func=user.login)

# Parse args
args = parser.parse_args()

Expand Down Expand Up @@ -139,3 +205,12 @@ def main():

# Run command
args.func(args)


def str2bool(v):
if v.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
raise argparse.ArgumentTypeError('Boolean value expected.')
Empty file.
24 changes: 24 additions & 0 deletions infraboxcli/dashboard/cli_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import requests

session = requests.Session()


def get(url, headers=None, cookies_handler=None):
response = session.get(url, headers=headers)
if cookies_handler:
cookies_handler(session.cookies.get_dict())
return response


def post(url, data, headers=None, cookies_handler=None):
response = session.post(url, json=data, headers=headers)
if cookies_handler:
cookies_handler(session.cookies.get_dict())
return response


def delete(url, headers=None, cookies_handler=None):
response = session.delete(url, headers=headers)
if cookies_handler:
cookies_handler(session.cookies.get_dict())
return response
43 changes: 43 additions & 0 deletions infraboxcli/dashboard/external.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import pickle
from os.path import expanduser

home = expanduser("~")

def save_user_token(dict):
try:
f = open(home + '/.infra.data', 'rb')
obj = pickle.load(f)
f.close()

except:
obj = {}

obj['current_user_token'] = dict['token']

f = open(home + '/.infra.data', 'wb')
pickle.dump(obj, f)
f.close()


def load_current_user_token():
try:
f = open(home + '/.infra.data', 'rb')
obj = pickle.load(f)
f.close()
curr_token = obj['current_user_token']
except:
raise EnvironmentError('Could not load current user token. Please log in')

return curr_token


def load_current_project_token():
try:
f = open(home + '/.infra.data', 'rb')
obj = pickle.load(f)
f.close()
curr_token = obj['current_project_token']
except:
raise EnvironmentError('Could not load current project token. Please set current project')

return curr_token
166 changes: 166 additions & 0 deletions infraboxcli/dashboard/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
from infraboxcli.dashboard.cli_client import get, post, delete
from infraboxcli.dashboard.user import get_user_headers
import infraboxcli.env

api_projects_endpoint_url = '/api/v1/projects/'


def delete_project(args):
infraboxcli.env.check_env_cli_token(args)
url = args.url + api_projects_endpoint_url + args.project_id
response = get(url, get_user_headers())

return response


def list_collaborators(args):
infraboxcli.env.check_env_cli_token(args)
url = args.url + api_projects_endpoint_url + args.project_id + '/collaborators'
response = get(url, get_user_headers())

if args.verbose:
print('=== Collaborators ===')
for collaborator in response.json():
print('Username: %s' % collaborator['username'])
print('E-mail: %s' % collaborator['email'])
print('---')

return response


def add_collaborator(args):
infraboxcli.env.check_env_cli_token(args)
url = args.url + api_projects_endpoint_url + args.project_id + '/collaborators'
data = { 'username': args.username }

response = post(url, data, get_user_headers())
print(response.json()['message'])

return response


def remove_collaborator(args):
infraboxcli.env.check_env_cli_token(args)

args.verbose = False
all_project_collaborators = list_collaborators(args).json()
collaborator_id = None
for collaborator in all_project_collaborators:
if collaborator['username'] == args.username:
collaborator_id = collaborator['id']
break

if collaborator_id is None:
print('Specified user is not in collaborators list.')
return

url = args.url + api_projects_endpoint_url + args.project_id + '/collaborators/' + collaborator_id
response = delete(url, get_user_headers())
print(response.json()['message'])

return response


def add_secret(args):
infraboxcli.env.check_env_cli_token(args)
url = args.url + api_projects_endpoint_url + args.project_id + '/secrets'
data = {'name': args.name, 'value': args.value}

response = post(url, data, get_user_headers())

return response


def delete_secret(args):
infraboxcli.env.check_env_cli_token(args)
url = args.url + api_projects_endpoint_url + args.project_id + '/secrets/' + args.name
response = delete(url, get_user_headers())

return response


def list_project_tokens(args):
infraboxcli.env.check_env_cli_token(args)
url = args.url + api_projects_endpoint_url + args.project_id + '/tokens'

response = get(url, get_user_headers())
if args.verbose:
print('=== Project tokens ===')
for project_token in response.json():
print('Description: %s' % project_token['description'])
print('Id: %s' % project_token['id'])
print('Scope push: %s' % project_token['scope_push'])
print('Scope pull: %s' % project_token['scope_pull'])
print('---')

return response


def get_project_token_id_by_description(args):
args.verbose = False
all_project_tokens = list_project_tokens(args).json()

for project_token in all_project_tokens:
if args.description == project_token['description']:
return project_token['id']

return None


def add_project_token(args):
infraboxcli.env.check_env_cli_token(args)
url = args.url + api_projects_endpoint_url + args.project_id + '/tokens'

data = {
'description': args.description,
#TODO<Steffen> when scope push/pull functionality is implemented,
# delete following 2 lines and uncomment next 2 lines
'scope_push': True,
'scope_pull': True
#'scope_push': args.scope_push,
#'scope_pull': args.scope_pull
}

response = post(url, data, get_user_headers())

if response.status_code != 200:
print(response.json()['message'])
return

# Print project token to the CLI
print('=== Authentication Token ===')
print('Please save your token at a secure place. We will not show it to you again.\n\n')
print(response.json()['data']['token'])

return response


def delete_project_token(args):
if args.id:
delete_project_token_by_id(args)
elif args.description:
delete_project_token_by_description(args)
else:
print('Please, provide either token id or description.')


def delete_project_token_by_description(args):
infraboxcli.env.check_env_cli_token(args)
token_id = get_project_token_id_by_description(args)

if not token_id:
print('Token with such a description does not exist.')
return

args.id = token_id
return delete_project_token_by_id(args)


def delete_project_token_by_id(args):
infraboxcli.env.check_env_cli_token(args)
url = args.url + api_projects_endpoint_url + args.project_id + '/tokens/' + args.id
response = delete(url, get_user_headers())

print(response.json()['message'])

return response
32 changes: 32 additions & 0 deletions infraboxcli/dashboard/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import getpass
import json

from infraboxcli.dashboard.cli_client import post, get
from infraboxcli.dashboard.external import load_current_user_token, save_user_token

api_endpoint_url = '/api/v1/'

def get_user_token():
return load_current_user_token()

def get_user_headers():
return {'Authorization': 'token %s' % get_user_token()}

def login(args):
email = args.email
password = args.password

if email is None:
email = raw_input("Email: ")
# Don't allow to pass password without email
password = None

if password is None:
password = getpass.getpass('Password: ')

data = { "email": email, "password": password}

url = args.url + api_endpoint_url + 'account/login'
response = post(url, data, cookies_handler=save_user_token)

return response
Loading