Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions cloudsmith_cli/cli/commands/policy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# -*- coding: utf-8 -*-
from .license import licence as policy_license # noqa
from .vulnerability import vulnerability as policy_vulnerability # noqa
313 changes: 313 additions & 0 deletions cloudsmith_cli/cli/commands/policy/license.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,313 @@
# -*- coding: utf-8 -*-
"""CLI/Commands - create, retrieve, update or delete license policies."""
from __future__ import absolute_import, print_function, unicode_literals

import json

import click
import six

from ....core.api import orgs as api
from ... import command, decorators, utils, validators
from ...exceptions import handle_api_exceptions
from ...utils import fmt_bool, fmt_datetime, maybe_spinner
from .command import policy


def print_license_policies(policies):
"""Print license policies as a table or output in another format."""

headers = [
"Name",
"Description",
"Allow Unknown Licenses",
"Quarantine On Violation",
"SPDX Identifiers",
"Created",
"Updated",
"Identifier",
]

rows = [
[
click.style(policy["name"], fg="cyan"),
click.style(policy["description"], fg="yellow"),
click.style(fmt_bool(policy["allow_unknown_licenses"]), fg="yellow"),
click.style(fmt_bool(policy["on_violation_quarantine"]), fg="yellow"),
click.style(six.text_type(policy["spdx_identifiers"]), fg="blue"),
click.style(fmt_datetime(policy["created_at"]), fg="blue"),
click.style(fmt_datetime(policy["updated_at"]), fg="blue"),
click.style(policy["slug_perm"], fg="green"),
]
for policy in policies
]

click.echo()
utils.pretty_print_table(headers, rows)
click.echo()

num_results = len(rows)
list_suffix = "license polic%s" % ("y" if num_results == 1 else "ies")
utils.pretty_print_list_info(num_results=num_results, suffix=list_suffix)


@policy.group(cls=command.AliasGroup, name="license", aliases=[])
Comment thread
Leeoc marked this conversation as resolved.
@decorators.common_cli_config_options
@decorators.common_cli_output_options
@decorators.common_api_auth_options
@decorators.initialise_api
@click.pass_context
def licence(*args, **kwargs):
"""
Manage license policies for an organization.

See the help for subcommands for more information on each.
"""


@licence.command(name="list", aliases=["ls"])
Comment thread
Leeoc marked this conversation as resolved.
@decorators.common_cli_config_options
@decorators.common_cli_list_options
@decorators.common_cli_output_options
@decorators.common_api_auth_options
@decorators.initialise_api
@click.argument(
"owner", metavar="OWNER", callback=validators.validate_owner, required=True
)
@click.pass_context
def ls(ctx, opts, owner, page, page_size):
Comment thread
Leeoc marked this conversation as resolved.
"""
List license policies.

This requires appropriate permissions for the owner (a member of the
organisation and a valid API key).

- OWNER: Specify the OWNER namespace (i.e. org)

Example: 'your-org'

Full CLI example:

$ cloudsmith policy license list your-org
"""
owner = owner[0]

# Use stderr for messages if the output is something else (e.g. # JSON)
use_stderr = opts.output != "pretty"

click.echo("Getting license policies ... ", nl=False, err=use_stderr)

context_msg = "Failed to get license policies!"
with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
with maybe_spinner(opts):
policies, page_info = api.list_license_policies(
owner=owner, page=page, page_size=page_size
)

click.secho("OK", fg="green", err=use_stderr)

if utils.maybe_print_as_json(opts, policies, page_info):
return

print_license_policies(policies)


@licence.command(aliases=["new"])
Comment thread
Leeoc marked this conversation as resolved.
@decorators.common_cli_config_options
@decorators.common_cli_output_options
@decorators.common_api_auth_options
@decorators.initialise_api
@click.argument("owner", default=None, required=True)
@click.argument("policy_config_file", type=click.File("rb"), required=True)
@click.pass_context
def create(ctx, opts, owner, policy_config_file):
"""
Create a new license policy in a namespace.

- OWNER: Specify the OWNER namespace (i.e. user or org) where you want
to create a license policy.

Example: 'your-org'

- POLICY_CONFIG_FILE: Config file specifying the settings for the
license policy to be created.

\b
Example:
{
"name": "your-license-policy",
"description": "your license policy description",
"spdx_identifiers" : ["your_licenses"],
"allow_unknown_licenses": false,
"quarantine_on_violation": true
}

Full CLI example:

$ cloudsmith policy license create your-org policy-config-file.json
"""
# Use stderr for messages if the output is something else (e.g. JSON)
use_stderr = opts.output != "pretty"
policy_config = json.load(policy_config_file)

policy_name = policy_config.get("name", None)
if policy_name is None:
raise click.BadParameter(
"Name is a required field for creating a license policy.", param="name"
)

spdx_identifiers = policy_config.get("spdx_identifiers", None)
if spdx_identifiers is None:
raise click.BadParameter(
"SPDX Identifiers is a required field for creating a license policy.",
param="spdx_identifiers",
)
Comment thread
Leeoc marked this conversation as resolved.

click.secho(
"Creating %(name)s license policy for the %(owner)s namespace ..."
% {
"name": click.style(policy_name, bold=True),
"owner": click.style(owner, bold=True),
},
nl=False,
err=use_stderr,
)

context_msg = "Failed to create the license policy!"
with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
Comment thread
Leeoc marked this conversation as resolved.
with maybe_spinner(opts):
policies = [api.create_license_policy(owner, policy_config)]

click.secho("OK", fg="green", err=use_stderr)

if utils.maybe_print_as_json(opts, policies):
return

print_license_policies(policies)


@licence.command()
Comment thread
Leeoc marked this conversation as resolved.
@decorators.common_cli_config_options
@decorators.common_cli_output_options
@decorators.common_api_auth_options
@decorators.initialise_api
@click.argument("owner", default=None, required=True)
@click.argument("identifier", default=None, required=True)
@click.argument("policy_config_file", type=click.File("rb"), required=True)
@click.pass_context
def update(ctx, opts, owner, identifier, policy_config_file):
Comment thread
Leeoc marked this conversation as resolved.
"""
Update a license policy.

- OWNER: Specify the OWNER namespace (i.e. user or org) where you want
to update a license policy.

Example: 'your-org'

- IDENTIFIER: Specify the license policy IDENTIFIER (i.e. slug_perm)
for the license policy which you wish to update.

Example: 'your-license-policy'

- POLICY_CONFIG_FILE: Config file specifying the settings for the
license policy to be updated.

\b
Example:
{
"name": "your-license-policy",
"description": "your license policy description",
"spdx_identifiers" : ["your_licenses"],
"allow_unknown_licenses": false,
"quarantine_on_violation": true
}

Full CLI example:

$ cloudsmith policy license update your-org your-license-policy policy-config-file.json
"""
# Use stderr for message if the output is something else (e.g. JSON)
use_stderr = opts.output != "pretty"

policy_config = json.load(policy_config_file)

click.secho(
"Updating %(slug_perm)s license policy in the %(owner)s namespace ..."
% {
"slug_perm": click.style(identifier, bold=True),
"owner": click.style(owner, bold=True),
},
nl=False,
err=use_stderr,
)

context_msg = "Failed to update the license policy!"
with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
Comment thread
Leeoc marked this conversation as resolved.
with maybe_spinner(opts):
policies = [api.update_license_policy(owner, identifier, policy_config)]

click.secho("OK", fg="green", err=use_stderr)

if utils.maybe_print_as_json(opts, policies):
return

print_license_policies(policies)


@licence.command(aliases=["rm"])
Comment thread
Leeoc marked this conversation as resolved.
@decorators.common_cli_config_options
@decorators.common_cli_output_options
@decorators.common_api_auth_options
@decorators.initialise_api
@click.argument("owner", metavar="OWNER")
@click.argument("identifier", default=None, required=True)
@click.option(
"-y",
"--yes",
default=False,
is_flag=True,
help="Assume yes as default answer to questions (this is dangerous!)",
)
@click.pass_context
def delete(ctx, opts, owner, identifier, yes):
Comment thread
Leeoc marked this conversation as resolved.
"""
Delete a license policy from a namespace.

- OWNER: Specify the OWNER namespace (i.e. org).

Example: 'your-org'

- IDENTIFIER: Specify the license policy IDENTIFIER (i.e. slug_perm)
for the license policy which you wish to delete.

Example: 'your-license-policy'

Full CLI example:

$ cloudsmith policy license delete your-org your-license-policy
"""

delete_args = {
"namespace": click.style(owner, bold=True),
"slug_perm": click.style(identifier, bold=True),
}

prompt = (
"delete the %(slug_perm)s license policy from the %(namespace)s namespace"
% delete_args
)

if not utils.confirm_operation(prompt, assume_yes=yes):
return

click.secho(
"Deleting %(slug_perm)s from the %(namespace)s namespace ... " % delete_args,
nl=False,
)

context_msg = "Failed to delete the license policy!"
with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
with maybe_spinner(opts):
api.delete_license_policy(owner=owner, slug_perm=identifier)

click.secho("OK", fg="green")
Loading