Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
import six
from cliff import show, lister
from osc_lib import exceptions
from osc_lib import utils as osc_utils
from datetime import datetime

from workloadmgrclient import utils
from workloadmgrclient.v1 import WorkloadmgrCommand
from workloadmgrclient.v1.validators import validate_int_value


validate_fields = {
    "interval": {"lower_bound": 1, "upper_bound": None},
    "retention_policy_value": {"lower_bound": 1, "upper_bound": 365},
    # '-1' for 'NEVER' and '0' for 'ALWAYS'
    "fullbackup_interval": {"lower_bound": -1, "upper_bound": 999},
}

class PolicyCommand(WorkloadmgrCommand):
    resource = "workload_policy"

    @staticmethod
    def produce_policy_output(objects=None):
        if objects:
            utils.print_list(objects, ["ID", "Name", "Description", "Status"])
            # print assigned project if only one policy to display
            if len(objects) == 1 and objects[0].policy_assignments:
                utils.print_list(
                    objects[0].policy_assignments, ["project_id", "project_name"]
                )
        return


class ListPolicy(PolicyCommand, lister.Lister):
    """List all available policies."""

    def take_action(self, parsed_args):
        client = self.get_client()
        policy_objs = client.list() or []
        headers = ["ID", "Name", "Description", "Status"]
        columns = ["id", "name", "description", "status"]
        return (
            headers,
            (osc_utils.get_item_properties(s, columns) for s in policy_objs),
        )


class ShowPolicy(PolicyCommand, show.ShowOne):
    """Show a policy."""

    @staticmethod
    def _add_arguments(parser):
        parser.add_argument(
            "policy_id", metavar="<policy_id>", help="ID of the policy."
        )

    def action_return(self, policy_obj):
        if policy_obj:
            data = {}
            for field_value in policy_obj.field_values:
                data[field_value["policy_field_name"]] = field_value["value"]
            # TODO check for after project assignment
            self.produce_policy_output([policy_obj])
            return zip(*sorted(six.iteritems(data)))

    def take_action(self, parsed_args):
        client = self.get_client()
        policy_obj = client.get(parsed_args.policy_id)
        return self.action_return(policy_obj)


class CreatePolicy(ShowPolicy):
    """Creates a policy."""

    @staticmethod
    def _add_arguments(parser):
        parser.add_argument(
            "display_name", metavar="<display_name>", help="policy name."
        )
        parser.add_argument(
            "--policy-fields",
            metavar="<key=key-name>",
            action="append",
            dest="policy_fields",
            required=True,
            default=[],
            help="Specify following key value pairs for policy fields "
            "Specify option multiple times to include multiple keys. "
            " 'start_time' : '10:30 PM' (must be positive number) "
            "--policy-fields start_time='10:30 PM'",
        )
        parser.add_argument(
            "--hourly",
            metavar="<key=key-name>",
            action="append",
            nargs="*",
            default=[],
            help="Specify following key value pairs for hourly jobschedule "
            "interval=<n> where n is no of hours range between (0 - 23)"
            "retention=<snapshots count>"
            "snapshot_type=<full|incremental>"
            "For example --hourly interval='5' retention='1' snapshot_type='incremental' "
            "If you don't specify this option, following default value"
            " 'interval' : '1' "
            " 'retention' : '30' "
            " 'snapshot_type' : 'incremental' ",
        )

        parser.add_argument(
            "--daily",
            metavar="<key=key-name>",
            action="append",
            nargs="*",
            default=[],
            help="Specify following key value pairs for daily jobschedule "
            "backup_time='1:30 PM,12:30 PM,00:30 AM'"
            "retention=<snapshots count>"
            "snapshot_type=<full|incremental>"
            "For example --daily backup_time='01:00 PM,02:00 PM,11:00 PM' retention='1' snapshot_type='incremental' "
            " meaning of above input : everyday 1 PM, 2PM,11PM incremental snapshot get trigger, only 1 snapshot remain per day ",
        )

        parser.add_argument(
            "--weekly",
            metavar="<key=key-name>",
            action="append",
            nargs="*",
            default=[],
            help="Specify following key value pairs for weekly jobschedule "
            "backup_day=[mon,tue,wed,thu,fri,sat,sun]"
            "retention=<snapshots count>"
            "snapshot_type=<full|incremental>"
            "For example --weekly backup_day='sun' retention='1' snapshot_type=incremental "
            " meaning of above input : incremental snapshot get trigger on every sun day on backup_time specified on daily option",
        )

        parser.add_argument(
            "--monthly",
            metavar="<key=key-name>",
            action="append",
            nargs="*",
            default=[],
            help="Specify following key value pairs for monthly jobschedule "
            "month_backup_day=<1-31|last>, 'last': last day of the month"
            "retention=<snapshots count>"
            "snapshot_type=<full|incremental>"
            "For example --monthly month_backup_day=1 retention=1 snapshot_type=incremental "
            " meaning of above input : every month 1st day of the month, 1 snapshot remain on every end of month, snapshot type incremental ",
        )

        parser.add_argument(
            "--yearly",
            metavar="<key=key-name>",
            action="append",
            nargs="*",
            default=[],
            help="Specify following key value pairs for yearly jobschedule "
            "backup_month=[jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec]"
            "retention=<snapshots count>"
            "snapshot_type=<full|incremental>"
            "For example --yearly month_of_the_year='jan' retention='1' snapshot_type=full "
            " meaning of above input : every year Jan 1 full snapshot reamin for retention",
        )

        parser.add_argument(
            "--manual",
            metavar="<key=key-name>",
            nargs="+",
            default=[],
            help="Specify following key value pairs for manual jobschedule \n"
            "retention=<snapshots count> "
            "retention_days_to_keep=<num of days> \n"
            "retention_days_to_keep only available for immutable Backup Targets\n"
            "For example --manual retention=30 retention_days_to_keep=30 "
            "meaning of above input : manually trigger snapshot get deleted after retention value hit",
        )

        parser.add_argument(
            "--display-description",
            metavar="<display_description>",
            help="Optional policy description. (Default=No description)",
            default="No description",
        )
        parser.add_argument(
            "--metadata",
            metavar="<key=key-name>",
            action="append",
            dest="metadata",
            default=[],
            help="Specify a key value pairs to include in the policy create metadata "
            "Specify option multiple times to include multiple keys. "
            "key=value",
        )

    def take_action(self, parsed_args):
        client = self.get_client()
        try:
            policy_fields = {}
            err_msg = None

            for policy_field_str in parsed_args.policy_fields:
                err_msg = (
                    "Invalid policy argument '%s'. policy arguments must be of the "
                    "form --policy-fields <key=value>" % policy_field_str
                )
                for kv_str in policy_field_str.split(","):
                    try:
                        k, v = kv_str.split("=", 1)
                    except ValueError:
                        raise exceptions.CommandError(err_msg)
                    if k =='start_time':
                        try:
                            datetime.strptime(v, '%I:%M %p')
                        except ValueError:
                            raise exceptions.CommandError("Invalid policy argument 'start_time'. start_time must be in format '%I:%M %p' eg. '3:00 PM', 10:30 AM")
                    if k in policy_fields:
                        policy_fields[k] = v
                    else:
                        policy_fields.setdefault(k, v)

            policy_fields.update(utils.validate_policy_param(parsed_args))
            if parsed_args.manual:
                data_dict = dict(item.split("=") for item in parsed_args.manual)
                policy_fields['manual'] = data_dict.get('retention', 30)
                policy_fields['retentionmanual'] = data_dict.get('retention_days_to_keep', 30)
                
            metadata = {}
            for metadata_str in parsed_args.metadata:
                for kv_str in metadata_str.split(","):
                    try:
                        k, v = kv_str.split("=", 1)
                    except ValueError:
                        err_msg = (
                            "Invalid metadata argument '%s'. metadata arguments must be of the "
                            "form --metadata <key=value>" % metadata_str
                        )
                        raise exceptions.CommandError(err_msg)

                    if k in metadata:
                        metadata[k] = v
                    else:
                        metadata.setdefault(k, v)

            policy_obj = self._perform_operation(
                client, parsed_args, policy_fields, metadata
            )
            return self.action_return(policy_obj)
        except Exception as ex:
            raise exceptions.CommandError(str(ex))

    def _perform_operation(self, client, args, policy_fields, metadata):
        return client.create(
            args.display_name, args.display_description, policy_fields, metadata
        )


class UpdatePolicy(CreatePolicy):
    """Update a policy."""

    @staticmethod
    def _add_arguments(parser):
        parser.add_argument(
            "policy_id", metavar="<policy_id>", help="ID of the policy."
        )
        parser.add_argument(
            "--display-name", metavar="<display-name>", help="policy name."
        )
        parser.add_argument(
            "--display-description",
            metavar="<display-description>",
            help="Optional policy description.",
        )
        parser.add_argument(
            "--policy-fields",
            metavar="<key=key-name>",
            action="append",
            dest="policy_fields",
            default=[],
            help="Specify following key value pairs for policy fields "
            "Specify option multiple times to include multiple keys. "
            " 'start_time' : '10:30 PM' (must be positive number) "
            "--policy-fields start_time='10:30 PM'",
        )

        parser.add_argument(
            "--hourly",
            metavar="<key=key-name>",
            action="append",
            nargs="*",
            default=[],
            help="Specify following key value pairs for hourly jobschedule "
            "interval=<n> where n is no of hours range between (0 - 23)"
            "retention=<snapshots count>"
            "snapshot_type=<full|incremental>"
            "For example --hourly interval='5' retention='1' snapshot_type='incremental' "
            "If you don't specify this option, following default value"
            " 'interval' : '1' "
            " 'retention' : '30' "
            " 'snapshot_type' : 'incremental' ",
        )

        parser.add_argument(
            "--daily",
            metavar="<key=key-name>",
            action="append",
            nargs="*",
            default=[],
            help="Specify following key value pairs for daily jobschedule "
            "backup_time='1:30 PM,12:30 PM,00:30 AM'"
            "retention=<snapshots count>"
            "snapshot_type=<full|incremental>"
            "For example --daily backup_time='01:00, 02:00, 21:00' retention='1' snapshot_type='incremental' "
            " meaning of above input : everyday 1 PM, 2PM, 11 PM incremental snapshot get trigger, only 1 snapshot remain per day ",
        )

        parser.add_argument(
            "--weekly",
            metavar="<key=key-name>",
            action="append",
            nargs="*",
            default=[],
            help="Specify following key value pairs for weekly jobschedule "
            "backup_day=[mon,tue,wed,thu,fri,sat,sun]"
            "retention=<snapshots count>"
            "snapshot_type=<full|incremental>"
            "For example --weekly backup_day='sun' retention='1' snapshot_type=incremental "
            " meaning of above input : incremental snapshot get trigger on every sun day on backup_time specified on daily option",
        )
        parser.add_argument(
            "--monthly",
            metavar="<key=key-name>",
            action="append",
            nargs="*",
            default=[],
            help="Specify following key value pairs for monthly jobschedule "
            "month_backup_day=<1-31|last>, 'last': last day of the month"
            "retention=<snapshots count>"
            "snapshot_type=<full|incremental>"
            "For example --monthly month_backup_day=1 retention=1 snapshot_type=incremental "
            " meaning of above input : every month 1st day of the month, 1 snapshot remain on every end of month, snapshot type incremental ",
        )

        parser.add_argument(
            "--yearly",
            metavar="<key=key-name>",
            action="append",
            nargs="*",
            default=[],
            help="Specify following key value pairs for yearly jobschedule "
            "backup_month=[jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec]"
            "retention=<snapshots count>"
            "snapshot_type=<full|incremental>"
            "For example --yearly month_of_the_year='jan' retention='1' snapshot_type=full "
            " meaning of above input : every year Jan 1 full snapshot reamin for retention",
        )

        parser.add_argument(
            "--manual",
            metavar="<key=key-name>",
            nargs="+",
            default=[],
            help="Specify following key value pairs for manual jobschedule \n"
            "retention=<snapshots count> "
            "retention_days_to_keep=<num of days> \n"
            "retention_days_to_keep only available for immutable Backup Targets\n"
            "For example --manual retention=30 retention_days_to_keep=30 "
            "meaning of above input : manually trigger snapshot get deleted after retention value hit",
        )


        parser.add_argument(
            "--metadata",
            metavar="<key=key-name>",
            action="append",
            dest="metadata",
            default=[],
            help="Specify a key value pairs to include in the policy update metadata "
            "Specify option multiple times to include multiple keys. "
            "key=value",
        )

    def _perform_operation(self, client, args, policy_fields, metadata):
        return client.update(
            args.policy_id,
            args.display_name,
            args.display_description,
            policy_fields,
            metadata,
        )


class DeletePolicy(PolicyCommand):
    """Remove a policy."""

    @staticmethod
    def _add_arguments(parser):
        parser.add_argument(
            "policy_id", metavar="<policy_id>", help="ID of the policy."
        )

    def take_action(self, parsed_args):
        client = self.get_client()
        client.delete(parsed_args.policy_id)


class AssignPolicy(ShowPolicy):
    """Assign/Remove policy to given projects."""

    @staticmethod
    def _add_arguments(parser):
        parser.add_argument(
            "policy_id", metavar="<policy_id>", help="ID of the policy."
        )
        parser.add_argument(
            "--add_project",
            metavar="<project_id>",
            action="append",
            dest="add_project",
            default=[],
            help="ID of the projects to assign policy. "
            "--add_project <project_id> --add_project <project_id>",
        )
        parser.add_argument(
            "--remove_project",
            metavar="<project_id>",
            action="append",
            dest="remove_project",
            default=[],
            help="ID of the projects to remove policy. "
            "--remove_project <project_id> --remove_project <project_id>",
        )

    def take_action(self, parsed_args):
        client = self.get_client()
        result = client.assign(
            parsed_args.policy_id, parsed_args.add_project, parsed_args.remove_project
        )

        if len(result["failed_ids"]) > 0:
            msg = "Please verify failed project id's are valid"
            utils.print_data_vertically([result["failed_ids"]], ["Failed_projects"])
            raise exceptions.CommandError(msg)
        else:
            return self.action_return(result["policy"])


class ListAssignedPolicy(PolicyCommand, lister.Lister):
    """List assigned policies on given project."""

    @staticmethod
    def _add_arguments(parser):
        parser.add_argument(
            "project_id",
            metavar="<project_id>",
            help="ID of the project to list assigned policies.",
        )

    def take_action(self, parsed_args):
        client = self.get_client()
        policy_objs = client.get_assigned_policies(parsed_args.project_id) or []
        headers = ["ID", "Name", "Deleted", "CreatedAt"]
        columns = ["policy_id", "policy_name", "deleted", "created_at"]
        return (
            headers,
            (osc_utils.get_dict_properties(s, columns) for s in policy_objs),
        )