1# -------------------------------------------------------------------------------------------- 2# Copyright (c) Microsoft Corporation. All rights reserved. 3# Licensed under the MIT License. See License.txt in the project root for license information. 4# -------------------------------------------------------------------------------------------- 5 6from msrestazure.tools import is_valid_resource_id, resource_id 7 8from azure.cli.core.commands.client_factory import get_subscription_id 9from azure.cli.core.util import sdk_no_wait 10 11from knack.util import CLIError 12 13 14def list_policy_events( 15 cmd, 16 client, 17 management_group_name=None, 18 resource_group_name=None, 19 resource=None, 20 namespace=None, 21 resource_type_parent=None, 22 resource_type=None, 23 policy_set_definition_name=None, 24 policy_definition_name=None, 25 policy_assignment_name=None, 26 from_value=None, 27 to_value=None, 28 order_by_clause=None, 29 select_clause=None, 30 top_value=None, 31 filter_clause=None, 32 apply_clause=None): 33 34 from azure.mgmt.policyinsights.models import QueryOptions 35 36 query_options = QueryOptions( 37 top=top_value, 38 order_by=order_by_clause, 39 select=select_clause, 40 from_property=from_value, 41 to=to_value, 42 filter=filter_clause, 43 apply=apply_clause) 44 45 subscription_id = get_subscription_id(cmd.cli_ctx) 46 47 if policy_assignment_name: 48 if resource_group_name: 49 events = client.list_query_results_for_resource_group_level_policy_assignment( 50 subscription_id, 51 resource_group_name, 52 policy_assignment_name, 53 query_options) 54 else: 55 events = client.list_query_results_for_subscription_level_policy_assignment( 56 subscription_id, 57 policy_assignment_name, 58 query_options) 59 elif policy_definition_name: 60 events = client.list_query_results_for_policy_definition( 61 subscription_id, 62 policy_definition_name, 63 query_options) 64 elif policy_set_definition_name: 65 events = client.list_query_results_for_policy_set_definition( 66 subscription_id, 67 policy_set_definition_name, 68 query_options) 69 elif resource: 70 if not is_valid_resource_id(resource): 71 if resource_type_parent: 72 resource_type_parent = _remove_leading_and_trailing_slash(resource_type_parent) 73 resource_type = "{}/{}".format(resource_type_parent, resource_type) 74 resource = resource_id( 75 subscription=subscription_id, 76 resource_group=resource_group_name, 77 namespace=namespace, 78 type=resource_type, 79 name=resource) 80 events = client.list_query_results_for_resource( 81 resource, 82 query_options) 83 elif resource_group_name: 84 events = client.list_query_results_for_resource_group( 85 subscription_id, 86 resource_group_name, 87 query_options) 88 elif management_group_name: 89 events = client.list_query_results_for_management_group( 90 management_group_name, 91 query_options) 92 else: 93 events = client.list_query_results_for_subscription( 94 subscription_id, 95 query_options) 96 97 return events 98 99 100def list_policy_states( 101 cmd, 102 client, 103 all_results=False, 104 management_group_name=None, 105 resource_group_name=None, 106 resource=None, 107 namespace=None, 108 resource_type_parent=None, 109 resource_type=None, 110 policy_set_definition_name=None, 111 policy_definition_name=None, 112 policy_assignment_name=None, 113 from_value=None, 114 to_value=None, 115 order_by_clause=None, 116 select_clause=None, 117 top_value=None, 118 filter_clause=None, 119 apply_clause=None, 120 expand_clause=None): 121 122 from azure.mgmt.policyinsights.models import QueryOptions 123 124 query_options = QueryOptions( 125 top=top_value, 126 order_by=order_by_clause, 127 select=select_clause, 128 from_property=from_value, 129 to=to_value, 130 filter=filter_clause, 131 apply=apply_clause, 132 expand=expand_clause) 133 134 policy_states_resource = 'latest' 135 if all_results is True: 136 policy_states_resource = 'default' 137 138 subscription_id = get_subscription_id(cmd.cli_ctx) 139 140 if policy_assignment_name: 141 if resource_group_name: 142 states = client.list_query_results_for_resource_group_level_policy_assignment( 143 policy_states_resource, 144 subscription_id, 145 resource_group_name, 146 policy_assignment_name, 147 query_options) 148 else: 149 states = client.list_query_results_for_subscription_level_policy_assignment( 150 policy_states_resource, 151 subscription_id, 152 policy_assignment_name, 153 query_options) 154 elif policy_definition_name: 155 states = client.list_query_results_for_policy_definition( 156 policy_states_resource, 157 subscription_id, 158 policy_definition_name, 159 query_options) 160 elif policy_set_definition_name: 161 states = client.list_query_results_for_policy_set_definition( 162 policy_states_resource, 163 subscription_id, 164 policy_set_definition_name, 165 query_options) 166 elif resource: 167 if not is_valid_resource_id(resource): 168 if resource_type_parent: 169 resource_type_parent = _remove_leading_and_trailing_slash(resource_type_parent) 170 resource_type = "{}/{}".format(resource_type_parent, resource_type) 171 resource = resource_id( 172 subscription=subscription_id, 173 resource_group=resource_group_name, 174 namespace=namespace, 175 type=resource_type, 176 name=resource) 177 states = client.list_query_results_for_resource( 178 policy_states_resource, 179 resource, 180 query_options) 181 elif resource_group_name: 182 states = client.list_query_results_for_resource_group( 183 policy_states_resource, 184 subscription_id, 185 resource_group_name, 186 query_options) 187 elif management_group_name: 188 states = client.list_query_results_for_management_group( 189 policy_states_resource, 190 management_group_name, 191 query_options) 192 else: 193 states = client.list_query_results_for_subscription( 194 policy_states_resource, 195 subscription_id, 196 query_options) 197 198 return states 199 200 201def summarize_policy_states( 202 cmd, 203 client, 204 management_group_name=None, 205 resource_group_name=None, 206 resource=None, 207 namespace=None, 208 resource_type_parent=None, 209 resource_type=None, 210 policy_set_definition_name=None, 211 policy_definition_name=None, 212 policy_assignment_name=None, 213 from_value=None, 214 to_value=None, 215 top_value=None, 216 filter_clause=None): 217 218 from azure.mgmt.policyinsights.models import QueryOptions 219 220 query_options = QueryOptions( 221 top=top_value, 222 from_property=from_value, 223 to=to_value, 224 filter=filter_clause) 225 226 subscription_id = get_subscription_id(cmd.cli_ctx) 227 228 if policy_assignment_name: 229 if resource_group_name: 230 summary = client.summarize_for_resource_group_level_policy_assignment( 231 subscription_id, 232 resource_group_name, 233 policy_assignment_name, 234 query_options) 235 else: 236 summary = client.summarize_for_subscription_level_policy_assignment( 237 subscription_id, 238 policy_assignment_name, 239 query_options) 240 elif policy_definition_name: 241 summary = client.summarize_for_policy_definition( 242 subscription_id, 243 policy_definition_name, 244 query_options) 245 elif policy_set_definition_name: 246 summary = client.summarize_for_policy_set_definition( 247 subscription_id, 248 policy_set_definition_name, 249 query_options) 250 elif resource: 251 resource = _build_resource_id( 252 subscription_id, 253 resource, 254 resource_group_name, 255 namespace, 256 resource_type_parent, 257 resource_type) 258 summary = client.summarize_for_resource( 259 resource, 260 query_options) 261 elif resource_group_name: 262 summary = client.summarize_for_resource_group( 263 subscription_id, 264 resource_group_name, 265 query_options) 266 elif management_group_name: 267 summary = client.summarize_for_management_group( 268 management_group_name, 269 query_options) 270 else: 271 summary = client.summarize_for_subscription( 272 subscription_id, 273 query_options) 274 275 return summary.value[0] 276 277 278def trigger_policy_scan( 279 cmd, 280 client, 281 resource_group_name=None, 282 no_wait=False): 283 284 subscription_id = get_subscription_id(cmd.cli_ctx) 285 if resource_group_name: 286 return sdk_no_wait(no_wait, client.begin_trigger_resource_group_evaluation, 287 subscription_id, resource_group_name) 288 289 return sdk_no_wait(no_wait, client.begin_trigger_subscription_evaluation, 290 subscription_id) 291 292 293def get_policy_remediation( 294 cmd, 295 client, 296 remediation_name, 297 management_group_name=None, 298 resource_group_name=None, 299 resource=None, 300 namespace=None, 301 resource_type_parent=None, 302 resource_type=None): 303 304 return _execute_remediation_operation( 305 cmd, 306 client, 307 "get_at_resource", 308 management_group_name, 309 resource_group_name, 310 resource, 311 namespace, 312 resource_type_parent, 313 resource_type, 314 remediation_name) 315 316 317def list_policy_remediations( 318 cmd, 319 client, 320 management_group_name=None, 321 resource_group_name=None, 322 resource=None, 323 namespace=None, 324 resource_type_parent=None, 325 resource_type=None): 326 327 return _execute_remediation_operation( 328 cmd, 329 client, 330 "list_for_resource", 331 management_group_name, 332 resource_group_name, 333 resource, 334 namespace, 335 resource_type_parent, 336 resource_type) 337 338 339def delete_policy_remediation( 340 cmd, 341 client, 342 remediation_name, 343 management_group_name=None, 344 resource_group_name=None, 345 resource=None, 346 namespace=None, 347 resource_type_parent=None, 348 resource_type=None): 349 350 return _execute_remediation_operation( 351 cmd, 352 client, 353 "delete_at_resource", 354 management_group_name, 355 resource_group_name, 356 resource, 357 namespace, 358 resource_type_parent, 359 resource_type, 360 remediation_name) 361 362 363def cancel_policy_remediation( 364 cmd, 365 client, 366 remediation_name, 367 management_group_name=None, 368 resource_group_name=None, 369 resource=None, 370 namespace=None, 371 resource_type_parent=None, 372 resource_type=None): 373 374 return _execute_remediation_operation( 375 cmd, 376 client, 377 "cancel_at_resource", 378 management_group_name, 379 resource_group_name, 380 resource, 381 namespace, 382 resource_type_parent, 383 resource_type, 384 remediation_name) 385 386 387def list_policy_remediation_deployments( 388 cmd, 389 client, 390 remediation_name, 391 management_group_name=None, 392 resource_group_name=None, 393 resource=None, 394 namespace=None, 395 resource_type_parent=None, 396 resource_type=None): 397 398 return _execute_remediation_operation( 399 cmd, 400 client, 401 "list_deployments_at_resource", 402 management_group_name, 403 resource_group_name, 404 resource, 405 namespace, 406 resource_type_parent, 407 resource_type, 408 remediation_name) 409 410 411def create_policy_remediation( 412 cmd, 413 client, 414 remediation_name, 415 policy_assignment, 416 definition_reference_id=None, 417 location_filters=None, 418 management_group_name=None, 419 resource_group_name=None, 420 resource=None, 421 namespace=None, 422 resource_type_parent=None, 423 resource_type=None, 424 resource_discovery_mode=None): 425 426 subscription_id = get_subscription_id(cmd.cli_ctx) 427 scope = _build_remediation_scope( 428 management_group_name, 429 subscription_id, 430 resource_group_name, 431 resource, 432 resource_type_parent, 433 resource_type, 434 namespace) 435 436 from azure.mgmt.policyinsights.models import Remediation 437 remediation = Remediation(policy_definition_reference_id=definition_reference_id) 438 439 # Get the full resource ID of the referenced policy assignment 440 if (not is_valid_resource_id(policy_assignment) and 441 not policy_assignment.lower().startswith("/providers/microsoft.management/managementgroups/")): 442 from ._client_factory import cf_policy 443 policy_assignment_client = cf_policy(cmd.cli_ctx).policy_assignments 444 policy_assignments = policy_assignment_client.list() 445 policy_assignment_ids = [p.id for p in policy_assignments if p.name.lower() == policy_assignment.lower()] 446 if not policy_assignment_ids: 447 raise CLIError("No policy assignment with the name '{}' found.".format(policy_assignment)) 448 if len(policy_assignment_ids) > 1: 449 raise CLIError("Multiple policy assignment with the name '{}' found. " 450 "Specify the policy assignment ID.".format(policy_assignment)) 451 policy_assignment = policy_assignment_ids[0] 452 remediation.policy_assignment_id = policy_assignment 453 454 # Ensure locations in the location filters are using their short name 455 if location_filters: 456 locations_list = [] 457 for location_arg in location_filters: 458 locations_list.append(location_arg.replace(' ', '')) 459 from azure.mgmt.policyinsights.models import RemediationFilters 460 remediation.filters = RemediationFilters(locations=locations_list) 461 462 if resource_discovery_mode: 463 remediation.resource_discovery_mode = resource_discovery_mode 464 465 return client.create_or_update_at_resource( 466 resource_id=_remove_leading_and_trailing_slash(scope), 467 remediation_name=remediation_name, 468 parameters=remediation) 469 470 471def show_policy_metadata(cmd, client, resource_name): # pylint: disable=unused-argument 472 return client.get_resource(resource_name=resource_name) 473 474 475def list_policy_metadata(cmd, client, top_value=None): # pylint: disable=unused-argument 476 if top_value is not None: 477 from azure.mgmt.policyinsights.models import QueryOptions 478 page_iter = client.list(QueryOptions(top=top_value)).by_page() 479 results = [] 480 481 while len(results) < top_value: 482 try: 483 results += list(next(page_iter)) 484 except StopIteration: 485 break 486 487 return results[:top_value] 488 489 return list(client.list()) 490 491 492def _execute_remediation_operation( 493 cmd, 494 client, 495 operation_name, 496 management_group_name=None, 497 resource_group_name=None, 498 resource=None, 499 namespace=None, 500 resource_type_parent=None, 501 resource_type=None, 502 remediation_name=None): 503 504 subscription_id = get_subscription_id(cmd.cli_ctx) 505 scope = _build_remediation_scope( 506 management_group_name, 507 subscription_id, 508 resource_group_name, 509 resource, 510 resource_type_parent, 511 resource_type, 512 namespace) 513 514 operation = getattr(client, operation_name) 515 if remediation_name is None: 516 return operation(resource_id=_remove_leading_and_trailing_slash(scope)) 517 return operation(resource_id=_remove_leading_and_trailing_slash(scope), remediation_name=remediation_name) 518 519 520def _build_resource_id( 521 subscription_id, 522 resource, 523 resource_group_name=None, 524 namespace=None, 525 resource_type_parent=None, 526 resource_type=None): 527 528 if not is_valid_resource_id(resource): 529 if resource_type_parent: 530 resource_type_parent = _remove_leading_and_trailing_slash(resource_type_parent) 531 resource_type = "{}/{}".format(resource_type_parent, resource_type) 532 533 resource = resource_id( 534 subscription=subscription_id, 535 resource_group=resource_group_name, 536 namespace=namespace, 537 type=resource_type, 538 name=resource) 539 540 return resource 541 542 543def _build_remediation_scope( 544 management_group=None, 545 subscription=None, 546 resource_group_name=None, 547 resource=None, 548 resource_type_parent=None, 549 resource_type=None, 550 namespace=None): 551 552 if management_group: 553 return "/providers/Microsoft.Management/managementGroups/{}".format(management_group) 554 if resource: 555 return _build_resource_id(subscription, resource, resource_group_name, 556 namespace, resource_type_parent, resource_type) 557 return resource_id(subscription=subscription, resource_group=resource_group_name) 558 559 560def _remove_leading_and_trailing_slash(s): 561 if s: 562 if s.startswith('/'): 563 s = s[1:] 564 if s.endswith('/'): 565 s = s[:-1] 566 567 return s 568