binauthz-attestation/parse_arguments.py (97 lines of code) (raw):
"""Parses the arguments passed to the bash script and returns them back to the bash script."""
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
import argparse
import re
import sys
# Technique for printing custom error and help
# Source: https://stackoverflow.com/a/4042861/862857
class CustomParser(argparse.ArgumentParser):
def error(self, message):
print('{}: error: {}'.format(self.prog, message), file=sys.stderr)
self.print_help()
sys.exit(1)
parser = CustomParser(prog='create_binauthz_attestation')
# By default, arguments with "--" are optional, so we have
# to make our own argument group so they are required
required_arguments = parser.add_argument_group('required arguments')
required_arguments.add_argument(
'--artifact-url',
type=str,
help='Registry URL for container image',
required=True)
attestor_args = parser.add_argument_group('Attestor arguments')
attestor_args.add_argument(
'--attestor',
type=str,
help='Fully qualified attestor name or just the attestor name',
required=True)
attestor_args.add_argument(
'--attestor-project',
type=str,
help='The project that the attestor is a part of')
pgp_args = parser.add_argument_group('PGP key arguments')
pgp_args.add_argument(
'--pgp-key-fingerprint',
type=str,
help='The fingerprint of the PGP key you plan to use')
# If the user is using KMS, they should provide:
kms_args = parser.add_argument_group('KMS key arguments')
kms_args.add_argument(
'--keyversion',
type=str,
help='The fully qualified keyversion or the version number of the KMS key')
kms_args.add_argument(
'--keyversion-key', type=str, help='The name of the KMS key')
kms_args.add_argument(
'--keyversion-keyring', type=str, help='The keyring for the KMS key')
kms_args.add_argument(
'--keyversion-location', type=str, help='The location of the KMS key')
kms_args.add_argument(
'--keyversion-project',
type=str,
help='The project that the KMS key belongs to')
args = parser.parse_args()
# Validate and parse attestor resource flags.
if '/' not in args.attestor:
if not args.attestor_project:
parser.error('The --attestor-project option is required if '
'--attestor is not a fully qualified '
'Attestor resource identifier')
else:
args.attestor = 'projects/{project}/attestors/{attestor}'.format(
project=args.attestor_project, attestor=args.attestor)
attestor_regex = re.compile(r'^projects/[a-z0-9-]*/attestors/[a-zA-Z0-9-_]*$')
if not attestor_regex.search(args.attestor):
parser.error('Attestor "{attestor}" is not '
'a valid attestor name'.format(attestor=args.attestor))
# Enforce mutual exclusion of key flag types.
keyversion_args = [
args.keyversion, args.keyversion_key, args.keyversion_keyring,
args.keyversion_location, args.keyversion_project
]
if args.pgp_key_fingerprint and any(keyversion_args):
parser.error('You cannot set --pgp-key-fingerprint and --keyversion related'
' options at the same time.')
if not args.pgp_key_fingerprint and not any(keyversion_args):
parser.error('Either --pgp-key-fingerprint or --keyversion related'
' options must be set.')
# Validate and parse keyversion resource flags.
if args.keyversion is not None and '/' not in args.keyversion:
if not all(keyversion_args):
parser.error(
'The --keyversion-key, --keyversion-keyring, --keyversion-location, '
'and --keyversion-project options are required if --keyversion '
'is not a fully qualified KMS key resource identifier.')
else:
args.keyversion = (
'projects/{project}/locations/{location}/keyRings/{keyRing}/'
'cryptoKeys/{cryptoKey}/cryptoKeyVersions/{keyversion}').format(
project=args.keyversion_project,
location=args.keyversion_location,
keyRing=args.keyversion_keyring,
cryptoKey=args.keyversion_key,
keyversion=args.keyversion)
keyversion_regex = re.compile(r'^projects/[a-z0-9-]*/locations/[a-z0-9-]*'
r'/keyRings/[a-zA-Z0-9-_]*/cryptoKeys/'
r'[a-zA-Z0-9-_]*/cryptoKeyVersions/[1-9][0-9]*$')
if args.keyversion is not None and not keyversion_regex.search(args.keyversion):
parser.error('"{}" is not a valid fully qualified KMS key identifier.'.format(
args.keyversion))
arguments_list = []
for arg_name, value in args.__dict__.items():
arguments_list.append('[{name}]="{value}"'.format(
name=arg_name, value=value or ''))
print('\n'.join(arguments_list))