Skip to content
This repository has been archived by the owner on Sep 9, 2024. It is now read-only.

Create hostfactory token vanilla flow 12446 #339

Merged
merged 15 commits into from
Sep 30, 2021
23 changes: 22 additions & 1 deletion conjur/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@
import json
import logging
from typing import Optional
# Third party
from datetime import datetime, timedelta

# Third Parties
import requests
Copy link
Contributor

Choose a reason for hiding this comment

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

should be under # Third Parties


# Internals
from conjur.api.endpoints import ConjurEndpoint
from conjur.wrapper.http_wrapper import HttpVerb, invoke_endpoint
from conjur.errors import InvalidResourceException, MissingRequiredParameterException
# pylint: disable=too-many-instance-attributes
from conjur.resource import Resource


# pylint: disable=unspecified-encoding
class Api():
"""
Expand Down Expand Up @@ -221,6 +224,24 @@ def get_variables(self, *variable_ids) -> dict:

return remapped_keys_dict

def create_token(self, create_token_data: str) -> requests.Response:
"""
This method is used to create token/s for hosts with restrictions.
"""
if create_token_data is None:
raise MissingRequiredParameterException('create_token_data cannot be empty!')
Copy link
Contributor

Choose a reason for hiding this comment

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

@eranha is this a user facing log? If so, this doesn't really explain anything

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@sigalsax I consider it as an argument exception (runtime so to speak) it is intended for the developer


params = {}
params.update(self._default_params)

return invoke_endpoint(HttpVerb.POST,
ConjurEndpoint.HOST_FACTORY_TOKENS,
params,
create_token_data,
api_token=self.api_token,
ssl_verify=self._ssl_verify,
headers={'Content-Type': 'application/x-www-form-urlencoded'})
Copy link
Contributor

Choose a reason for hiding this comment

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

can we return a JSON or a string instead of the response itself? Would be clearer

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The documentation of the logic class
`HostFactoryLogic

This class holds the business logic for executing and manipulating
returned data`

Copy link
Contributor

Choose a reason for hiding this comment

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

i dont follow

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@sigalsax The logic responsible to manipulate the response


def set_variable(self, variable_id: str, value: str) -> str:
"""
This method is used to set a secret (aka "variable") to a value of
Expand Down
9 changes: 9 additions & 0 deletions conjur/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import logging
from typing import Optional

# Third Party
import requests

# Internals
from conjur.logic.credential_provider.credential_store_factory import CredentialStoreFactory
from conjur.errors import CertificateVerificationException, ConfigurationMissingException, \
Expand Down Expand Up @@ -180,6 +183,12 @@ def get_many(self, *variable_ids) -> Optional[bytes]:
"""
return self._api.get_variables(*variable_ids)

def create_token(self, create_token_data: str) -> requests.Response:
"""
Create token/s for hosts with restrictions
Copy link
Contributor

Choose a reason for hiding this comment

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

we create only a single token, correct?

Suggested change
Create token/s for hosts with restrictions
Create token for hosts with restrictions

Copy link
Contributor Author

@eranha eranha Sep 29, 2021

Choose a reason for hiding this comment

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

You pass an argument count and get the multiple tokens in response

"""
return self._api.create_token(create_token_data)

def set(self, variable_id: str, value: str) -> str:
"""
Sets a variable to a specific value based on its ID
Expand Down
1 change: 1 addition & 0 deletions conjur/api/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ class ConjurEndpoint(Enum):
ROTATE_API_KEY = "{url}/authn/{account}/api_key"
CHANGE_PASSWORD = "{url}/authn/{account}/password"
WHOAMI = "{url}/whoami"
HOST_FACTORY_TOKENS = "{url}/host_factory_tokens"
132 changes: 132 additions & 0 deletions conjur/argument_parser/_hostfactory_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""
Module For the hostfactoryParser
"""
import argparse
from conjur.argument_parser.parser_utils import command_description, command_epilog, formatter, \
title_formatter
from conjur.wrapper.argparse_wrapper import ArgparseWrapper


# pylint: disable=too-few-public-methods
class HostFactoryParser:
"""Partial class of the ArgParseBuilder.
This class add the HostFactory subparser to the ArgParseBuilder parser."""

def __init__(self):
self.resource_subparsers = None # here to reduce warnings on resource_subparsers not exist
raise NotImplementedError("this is partial class of ArgParseBuilder")

def add_hostfactory_parser(self):
"""
Method adds hostfactory parser functionality to parser
"""
hostfactory_parser = self._create_hostfactory_parser()
hostfactory_subparser = hostfactory_parser.add_subparsers(title="Subcommand", dest='action')
hostfactory_create_menu_item = self._add_hostfactory_create(hostfactory_subparser)
self._add_hostfactory_create_token(hostfactory_create_menu_item)
self._add_hostfactory_options(hostfactory_parser)

return self

def _create_hostfactory_parser(self):
hostfactory_name = 'hostfactory - Manage hosts and tokens'
hostfactory_usage = 'conjur [global options] hostfactory <subcommand> [options] [args]'

hostfactory_parser = self.resource_subparsers \
.add_parser('hostfactory',
help='Allows creating hosts dynamically and manage hostfactory tokens',
description=command_description(hostfactory_name,
hostfactory_usage),
epilog=command_epilog(
'conjur hostfactory create token --hostfactoryid my_factory '
Copy link
Contributor

Choose a reason for hiding this comment

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

not a blocker but this should be verified by Sapir (if it needs a -)

'--cidr 10.10.1.2/31 '
'--duration-days 2\t\t\t '
'Creates one or more identical tokens for hosts with restrictions\n',
command='hostfactory',
subcommands=['create']),
usage=argparse.SUPPRESS,
add_help=False,
formatter_class=formatter)
return hostfactory_parser

@staticmethod
def _add_hostfactory_create(hostfactory_subparser: ArgparseWrapper):
hostfactory_create_name = 'create - Create token/s for hosts ' \
'with restrictions'
hostfactory_create_usage = 'conjur [global options] hostfactory ' \
'create <subcommand> [options] [args]'

create_cmd = hostfactory_subparser \
.add_parser(name="create",
help='Creates a token or creates a host using a token',
description=command_description(
hostfactory_create_name, hostfactory_create_usage),
epilog=command_epilog(
'conjur hostfactory create token --hostfactoryid my_factory '
'--cidr 10.10.1.2/31 '
'--duration-days 2\t\t\t '
'Create creates one or more identical tokens '
'for hosts with restrictions\t\t',
command='create',
subcommands=['token']
),
usage=argparse.SUPPRESS,
add_help=False,
formatter_class=formatter)
hostfactory_create = create_cmd.add_argument_group(
title=title_formatter("Options"))
hostfactory_create.add_argument('-h', '--help', action='help',
help='Display help screen and exit')
return create_cmd.add_subparsers(title="Subcommand", dest='action')

@staticmethod
def _add_hostfactory_create_token(menu: ArgparseWrapper):
hostfactory_create_token_name = 'token - Create token/s for hosts ' \
'with restrictions'
hostfactory_create_token_usage = 'conjur [global options] hostfactory ' \
'create token [options] [args]'

hostfactory_create_subcommand_parser = menu \
.add_parser(name="token",
help='Create token/s for hosts with restrictions',
description=command_description(
hostfactory_create_token_name, hostfactory_create_token_usage),
epilog=command_epilog(
'conjur hostfactory create token --hostfactoryid my_factory '
'--cidr 10.10.1.2/31 '
'--duration-days 2\t\t '
'Creates one or more identical tokens for hosts with restrictions\t\t',
command='token',
),
usage=argparse.SUPPRESS,
add_help=False,
formatter_class=formatter)
# Options
create_token = hostfactory_create_subcommand_parser.add_argument_group(
title=title_formatter("Options"))
create_token.add_argument('-action_type', default='create_token', help=argparse.SUPPRESS)
create_token.add_argument('-i', '--hostfactoryid', metavar='VALUE',
help='(Mandatory) the ID of the host factory.')
create_token.add_argument('--cidr', metavar='VALUE',
help='(Optional) the CIDR address that contains '
'all IPs that can use this token to create hosts. '
'You can specify multiple cidr, '
'separated by commas (for example '
'--cidr "10.0.10.0/24,'
'10.0.11.1/32,10.0.20.0/24")')
create_token.add_argument('-d', '--duration-days', metavar='VALUE', type=int,
help='(Optional) the number of days the token will be valid.')
create_token.add_argument('-H', '--duration-hours', metavar='VALUE', type=int,
Copy link
Contributor

Choose a reason for hiding this comment

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

was anything decided here regarding the -H?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@sigalsax not that I know of

help='(Optional) the number of hours the token will be valid.')
create_token.add_argument('-m', '--duration-minutes', metavar='VALUE', type=int,
help='(Optional) the number of minutes the token will be valid.')
create_token.add_argument('-c', '--count', metavar='VALUE', type=int,
help='(Optional) the number of times the token can be used.')
create_token.add_argument('-h', '--help', action='help',
help='Display help screen and exit')

@staticmethod
def _add_hostfactory_options(parser: ArgparseWrapper):
options = parser.add_argument_group(title=title_formatter("Options"))
options.add_argument('-h', '--help', action='help',
help='Display help screen and exit')
4 changes: 3 additions & 1 deletion conjur/argument_parser/argparse_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Module For the argparseBuilder
"""
import argparse

from conjur.wrapper import ArgparseWrapper

from conjur.argument_parser.parser_utils import formatter, header, main_epilog, title_formatter
Expand All @@ -15,6 +16,7 @@
from conjur.argument_parser._user_parser import UserParser
from conjur.argument_parser._variable_parser import VariableParser
from conjur.argument_parser._whoami_parser import WhoamiParser
from conjur.argument_parser._hostfactory_parser import HostFactoryParser


# pylint: disable=line-too-long
Expand All @@ -27,6 +29,7 @@ class ArgParseBuilder(InitParser,
UserParser,
VariableParser,
WhoamiParser,
HostFactoryParser,
ScreenOptionsParser):
"""
This class simplifies and encapsulates the way we build the help screens.
Expand All @@ -50,7 +53,6 @@ def __init__(self):
formatter_class=formatter)
self.resource_subparsers = self.parser.add_subparsers(dest='resource', title=title_formatter("Commands"))


def build(self) -> ArgparseWrapper:
"""
Method that return the final parser
Expand Down
Loading