|
| 1 | +import click |
| 2 | +from py42.clients.trustedactivities import TrustedActivityType |
| 3 | + |
| 4 | +from code42cli.bulk import generate_template_cmd_factory |
| 5 | +from code42cli.bulk import run_bulk_process |
| 6 | +from code42cli.click_ext.groups import OrderedGroup |
| 7 | +from code42cli.errors import Code42CLIError |
| 8 | +from code42cli.file_readers import read_csv_arg |
| 9 | +from code42cli.options import format_option |
| 10 | +from code42cli.options import sdk_options |
| 11 | +from code42cli.output_formats import OutputFormatter |
| 12 | + |
| 13 | +resource_id_arg = click.argument("resource-id", type=int) |
| 14 | +type_option = click.option( |
| 15 | + "--type", |
| 16 | + help=f"Type of trusted activity. Valid types include {', '.join(TrustedActivityType.choices())}.", |
| 17 | + type=click.Choice(TrustedActivityType.choices()), |
| 18 | +) |
| 19 | +value_option = click.option( |
| 20 | + "--value", |
| 21 | + help="The value of the trusted activity, such as the domain or Slack workspace name.", |
| 22 | +) |
| 23 | +description_option = click.option( |
| 24 | + "--description", help="The description of the trusted activity." |
| 25 | +) |
| 26 | + |
| 27 | + |
| 28 | +def _get_trust_header(): |
| 29 | + return { |
| 30 | + "resourceId": "Resource Id", |
| 31 | + "type": "Type", |
| 32 | + "value": "Value", |
| 33 | + "description": "Description", |
| 34 | + "updatedAt": "Last Update Time", |
| 35 | + "updatedByUsername": "Last Updated By (Username)", |
| 36 | + "updatedByUserUid": "Last updated By (UserUID)", |
| 37 | + } |
| 38 | + |
| 39 | + |
| 40 | +@click.group(cls=OrderedGroup) |
| 41 | +@sdk_options(hidden=True) |
| 42 | +def trusted_activities(state): |
| 43 | + """Manage trusted activities and resources.""" |
| 44 | + pass |
| 45 | + |
| 46 | + |
| 47 | +@trusted_activities.command() |
| 48 | +@click.argument("type", type=click.Choice(TrustedActivityType.choices())) |
| 49 | +@click.argument("value") |
| 50 | +@description_option |
| 51 | +@sdk_options() |
| 52 | +def create(state, type, value, description): |
| 53 | + """Create a trusted activity. |
| 54 | +
|
| 55 | + VALUE is the name of the domain or Slack workspace. |
| 56 | + """ |
| 57 | + state.sdk.trustedactivities.create( |
| 58 | + type, value, description=description, |
| 59 | + ) |
| 60 | + |
| 61 | + |
| 62 | +@trusted_activities.command() |
| 63 | +@resource_id_arg |
| 64 | +@value_option |
| 65 | +@description_option |
| 66 | +@sdk_options() |
| 67 | +def update(state, resource_id, value, description): |
| 68 | + """Update a trusted activity. Requires the activity's resource ID.""" |
| 69 | + state.sdk.trustedactivities.update( |
| 70 | + resource_id, value=value, description=description, |
| 71 | + ) |
| 72 | + |
| 73 | + |
| 74 | +@trusted_activities.command() |
| 75 | +@resource_id_arg |
| 76 | +@sdk_options() |
| 77 | +def remove(state, resource_id): |
| 78 | + """Remove a trusted activity. Requires the activity's resource ID.""" |
| 79 | + state.sdk.trustedactivities.delete(resource_id) |
| 80 | + |
| 81 | + |
| 82 | +@trusted_activities.command("list") |
| 83 | +@click.option("--type", type=click.Choice(TrustedActivityType.choices())) |
| 84 | +@format_option |
| 85 | +@sdk_options() |
| 86 | +def _list(state, type, format): |
| 87 | + """List all trusted activities.""" |
| 88 | + pages = state.sdk.trustedactivities.get_all(type=type) |
| 89 | + formatter = OutputFormatter(format, _get_trust_header()) |
| 90 | + trusted_resources = [ |
| 91 | + resource for page in pages for resource in page["trustResources"] |
| 92 | + ] |
| 93 | + if trusted_resources: |
| 94 | + formatter.echo_formatted_list(trusted_resources) |
| 95 | + else: |
| 96 | + click.echo("No trusted activities found.") |
| 97 | + |
| 98 | + |
| 99 | +@trusted_activities.group(cls=OrderedGroup) |
| 100 | +@sdk_options(hidden=True) |
| 101 | +def bulk(state): |
| 102 | + """Tools for executing bulk trusted activity actions.""" |
| 103 | + pass |
| 104 | + |
| 105 | + |
| 106 | +TRUST_CREATE_HEADERS = [ |
| 107 | + "type", |
| 108 | + "value", |
| 109 | + "description", |
| 110 | +] |
| 111 | +TRUST_UPDATE_HEADERS = [ |
| 112 | + "resource_id", |
| 113 | + "value", |
| 114 | + "description", |
| 115 | +] |
| 116 | +TRUST_REMOVE_HEADERS = [ |
| 117 | + "resource_id", |
| 118 | +] |
| 119 | + |
| 120 | +trusted_activities_generate_template = generate_template_cmd_factory( |
| 121 | + group_name="trusted_activities", |
| 122 | + commands_dict={ |
| 123 | + "create": TRUST_CREATE_HEADERS, |
| 124 | + "update": TRUST_UPDATE_HEADERS, |
| 125 | + "remove": TRUST_REMOVE_HEADERS, |
| 126 | + }, |
| 127 | + help_message="Generate the CSV template needed for bulk trusted-activities commands", |
| 128 | +) |
| 129 | +bulk.add_command(trusted_activities_generate_template) |
| 130 | + |
| 131 | + |
| 132 | +@bulk.command( |
| 133 | + name="create", |
| 134 | + help="Bulk create trusted activities using a CSV file with " |
| 135 | + f"format: {','.join(TRUST_UPDATE_HEADERS)}.", |
| 136 | +) |
| 137 | +@read_csv_arg(headers=TRUST_CREATE_HEADERS) |
| 138 | +@sdk_options() |
| 139 | +def bulk_create(state, csv_rows): |
| 140 | + """Bulk create trusted activities.""" |
| 141 | + sdk = state.sdk |
| 142 | + |
| 143 | + def handle_row(type, value, description): |
| 144 | + if type not in TrustedActivityType.choices(): |
| 145 | + message = f"Invalid type {type}, valid types include {', '.join(TrustedActivityType.choices())}." |
| 146 | + raise Code42CLIError(message) |
| 147 | + if type is None: |
| 148 | + message = "'type' is a required field to create a trusted activity." |
| 149 | + raise Code42CLIError(message) |
| 150 | + if value is None: |
| 151 | + message = "'value' is a required field to create a trusted activity." |
| 152 | + raise Code42CLIError(message) |
| 153 | + sdk.trustedactivities.create(type, value, description) |
| 154 | + |
| 155 | + run_bulk_process( |
| 156 | + handle_row, csv_rows, progress_label="Creating trusting activities:", |
| 157 | + ) |
| 158 | + |
| 159 | + |
| 160 | +@bulk.command( |
| 161 | + name="update", |
| 162 | + help="Bulk update trusted activities using a CSV file with " |
| 163 | + f"format: {','.join(TRUST_UPDATE_HEADERS)}.", |
| 164 | +) |
| 165 | +@read_csv_arg(headers=TRUST_UPDATE_HEADERS) |
| 166 | +@sdk_options() |
| 167 | +def bulk_update(state, csv_rows): |
| 168 | + """Bulk update trusted activities.""" |
| 169 | + sdk = state.sdk |
| 170 | + |
| 171 | + def handle_row(resource_id, value, description): |
| 172 | + if resource_id is None: |
| 173 | + message = "'resource_id' is a required field to update a trusted activity." |
| 174 | + raise Code42CLIError(message) |
| 175 | + _check_resource_id_type(resource_id) |
| 176 | + sdk.trustedactivities.update(resource_id, value, description) |
| 177 | + |
| 178 | + run_bulk_process( |
| 179 | + handle_row, csv_rows, progress_label="Updating trusted activities:" |
| 180 | + ) |
| 181 | + |
| 182 | + |
| 183 | +@bulk.command( |
| 184 | + name="remove", |
| 185 | + help="Bulk remove trusted activities using a CSV file with " |
| 186 | + f"format: {','.join(TRUST_REMOVE_HEADERS)}.", |
| 187 | +) |
| 188 | +@read_csv_arg(headers=TRUST_REMOVE_HEADERS) |
| 189 | +@sdk_options() |
| 190 | +def bulk_remove(state, csv_rows): |
| 191 | + """Bulk remove trusted activities.""" |
| 192 | + sdk = state.sdk |
| 193 | + |
| 194 | + def handle_row(resource_id): |
| 195 | + if resource_id is None: |
| 196 | + message = "'resource_id' is a required field to remove a trusted activity." |
| 197 | + raise Code42CLIError(message) |
| 198 | + _check_resource_id_type(resource_id) |
| 199 | + sdk.trustedactivities.delete(resource_id) |
| 200 | + |
| 201 | + run_bulk_process( |
| 202 | + handle_row, csv_rows, progress_label="Removing trusted activities:", |
| 203 | + ) |
| 204 | + |
| 205 | + |
| 206 | +def _check_resource_id_type(resource_id): |
| 207 | + def raise_error(resource_id): |
| 208 | + message = f"Invalid resource ID {resource_id}. Must be an integer." |
| 209 | + raise Code42CLIError(message) |
| 210 | + |
| 211 | + try: |
| 212 | + if not float(resource_id).is_integer(): |
| 213 | + raise_error(resource_id) |
| 214 | + except ValueError: |
| 215 | + raise_error(resource_id) |
0 commit comments