From b65c7844e34a8e096c3c6e8c888c0db391590667 Mon Sep 17 00:00:00 2001 From: Shawn Huckabay Date: Thu, 9 Nov 2023 10:37:07 -0600 Subject: [PATCH] Sandbox Management - Terminate Old Applied Policies (#61) * initial * update * update * update * name * update --- .../CHANGELOG.md | 5 + .../terminate_old_applied_policies/README.md | 31 ++ .../terminate_old_applied_policies.pt | 265 ++++++++++++++++++ 3 files changed, 301 insertions(+) create mode 100644 sandbox_management/terminate_old_applied_policies/CHANGELOG.md create mode 100644 sandbox_management/terminate_old_applied_policies/README.md create mode 100644 sandbox_management/terminate_old_applied_policies/terminate_old_applied_policies.pt diff --git a/sandbox_management/terminate_old_applied_policies/CHANGELOG.md b/sandbox_management/terminate_old_applied_policies/CHANGELOG.md new file mode 100644 index 00000000..16ca1ac7 --- /dev/null +++ b/sandbox_management/terminate_old_applied_policies/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## v0.1 + +- Initial Release diff --git a/sandbox_management/terminate_old_applied_policies/README.md b/sandbox_management/terminate_old_applied_policies/README.md new file mode 100644 index 00000000..4c08d1c7 --- /dev/null +++ b/sandbox_management/terminate_old_applied_policies/README.md @@ -0,0 +1,31 @@ +# Sandbox Management - Terminate Old Applied Policies + +## What It Does + +This policy will terminate old applied policies that meet the criteria specified by the user. This is to assist in keeping testing, development, and sandbox environments clean of old policies that are no longer being used. + +## Functional Description + +This policy uses the [Flexera Automation Policy API](https://reference.rightscale.com/governance-policies) to retrieve a list of applied policies. The policies are then filtered for just the ones that meet the user-specified criteria and terminated. + +## Input Parameters + +This policy has the following input parameters required when launching the policy. + +- *Termination Age (Days)* - How many days ago a policy must have been applied before it is terminated. +- *Created / Updated* - Whether to use the date the applied policy was created or the date it was last updated to determine its age. +- *Terminate Aggregates* - Whether or not to also terminate policy aggregates e.g. org-level applied policies. Note that this will not be scoped to the project you are running this policy in and will always be based on the `created_at` date for policy aggregates regardless of the value of the `Created / Updated` parameter. +- *Policy Ignore List* - A list of policy template names to never terminate despite their age. +- *Applied Policy Ignore List* - A list of applied policy names to never terminate despite their age. + +## Policy Actions + +- Terminate old applied policies. + +## Prerequisites + +This Policy Template uses [Credentials](https://docs.flexera.com/flexera/EN/Automation/ManagingCredentialsExternal.htm) for authenticating to datasources -- in order to apply this policy you must have a Credential registered in the system that is compatible with this policy. If there are no Credentials listed when you apply the policy, please contact your Flexera Org Admin and ask them to register a Credential that is compatible with this policy. The information below should be consulted when creating the credential(s). + +- [**Flexera Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm) (*provider=flexera*) with access to view and terminate applied policies. + +The [Provider-Specific Credentials](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm) page in the docs has detailed instructions for setting up Credentials for the most common providers. diff --git a/sandbox_management/terminate_old_applied_policies/terminate_old_applied_policies.pt b/sandbox_management/terminate_old_applied_policies/terminate_old_applied_policies.pt new file mode 100644 index 00000000..32071720 --- /dev/null +++ b/sandbox_management/terminate_old_applied_policies/terminate_old_applied_policies.pt @@ -0,0 +1,265 @@ +name "Sandbox Management - Terminate Old Applied Policies" +rs_pt_ver 20180301 +type "policy" +short_description "Automatically terminates all policies applied longer ago than a user-specified number of days. See the [README](https://github.com/flexera-public/optima-tools/tree/master/sandbox_management/terminate_old_policies) and [docs.flexera.com/flexera/EN/Automation](https://docs.flexera.com/flexera/EN/Automation/AutomationGS.htm) to learn more." +long_description "" +severity "low" +category "Utility" +default_frequency "weekly" +info( + version: "0.1", + provider: "Flexera" +) + +############################################################################### +# Parameters +############################################################################### + +parameter "param_days_back" do + type "number" + category "Policy Settings" + label "Termination Age (Days)" + description "How many days ago a policy must have been applied before it is terminated." + min_value 1 + default 30 +end + +parameter "param_created_updated" do + type "string" + category "Policy Settings" + label "Created / Updated" + description "Whether to use the date the applied policy was created or the date it was last updated to determine its age." + allowed_values "Created", "Updated" + default "Updated" +end + +parameter "param_aggregates" do + type "string" + category "Policy Settings" + label "Terminate Aggregates" + description "Whether or not to also terminate policy aggregates e.g. org-level applied policies." + allowed_values "Yes", "No" + default "No" +end + +parameter "param_filter" do + type "list" + category "Policy Settings" + label "Policy Ignore List" + description "A list of policy template names to never terminate despite their age." + default [] +end + +parameter "param_applied_filter" do + type "list" + category "Policy Settings" + label "Applied Policy Ignore List" + description "A list of applied policy names to never terminate despite their age." + default [] +end + +############################################################################### +# Authentication +############################################################################### + +credentials "auth_flexera" do + schemes "oauth2" + label "Flexera" + description "Select Flexera One OAuth2 credentials" + tags "provider=flexera" +end + +############################################################################### +# Datasources & Scripts +############################################################################### + +datasource "ds_applied_policies" do + request do + auth $auth_flexera + host rs_governance_host + path join(["/api/governance/projects/", rs_project_id, "/applied_policies"]) + verb "GET" + header "User-Agent", "RS Policies" + header "Api-Version", "1.0" + query "show_meta_child_policies", "true" + end + result do + encoding "json" + collect jmes_path(response, "items") do + field "category", jmes_path(col_item, "category") + field "created_at", jmes_path(col_item, "created_at") + field "description", jmes_path(col_item, "description") + field "href", jmes_path(col_item, "href") + field "id", jmes_path(col_item, "id") + field "name", jmes_path(col_item, "name") + field "status", jmes_path(col_item, "status") + field "updated_at", jmes_path(col_item, "updated_at") + field "template_id", jmes_path(col_item, "policy_template.id") + field "template_name", jmes_path(col_item, "policy_template.name") + end + end +end + +datasource "ds_filtered_applied_policies" do + run_script $js_filtered_applied_policies, $ds_applied_policies, $param_days_back, $param_created_updated, $param_filter, $param_applied_filter, policy_id +end + +script "js_filtered_applied_policies", type: "javascript" do + parameters "ds_applied_policies", "param_days_back", "param_created_updated", "param_filter", "param_applied_filter", "self_id" + result "result" + code <<-EOS + today = new Date() + + result = _.filter(ds_applied_policies, function(policy) { + terminate_policy = true + + // Prevent policy from terminating itself + if (policy['id'] == self_id) { terminate_policy = false } + + // Prevent policy from terminating newly applied/updated policies + if (param_created_updated == 'Created') { policy_date = new Date(policy['created_at']) } + if (param_created_updated == 'Updated') { policy_date = new Date(policy['updated_at']) } + + policy_age = Math.round((today - policy_date) / 1000 / 60 / 60 / 24) + + if (policy_age < param_days_back) { terminate_policy = false } + + // Prevent policy from terminating user-specified policies + if (param_filter.length > 0) { + if (_.contains(param_filter, policy['template_name']) && typeof(policy['template_name']) == 'string' && policy['template_name'] != '') { + terminate_policy = false + } + } + + if (param_applied_filter.length > 0) { + if (_.contains(param_applied_filter, policy['name'])) { terminate_policy = false } + } + + // Prevent policy from terminating org-level policies + if (typeof(policy['template_id']) != 'string' || policy['template_id'] == '') { + terminate_policy = false + } + + return terminate_policy + }) +EOS +end + +datasource "ds_terminate_applied_policies" do + iterate $ds_filtered_applied_policies + request do + auth $auth_flexera + host rs_governance_host + path val(iter_item, 'href') + verb "DELETE" + header "User-Agent", "RS Policies" + header "Api-Version", "1.0" + ignore_status [400, 401, 402, 403, 404, 405] + end + result do + encoding "text" + end +end + +datasource "ds_policy_aggregates" do + request do + auth $auth_flexera + host rs_governance_host + path join(["/api/governance/orgs/", rs_org_id, "/policy_aggregates"]) + verb "GET" + header "User-Agent", "RS Policies" + header "Api-Version", "1.0" + end + result do + encoding "json" + collect jmes_path(response, "items") do + field "category", jmes_path(col_item, "category") + field "created_at", jmes_path(col_item, "created_at") + field "description", jmes_path(col_item, "description") + field "href", jmes_path(col_item, "href") + field "id", jmes_path(col_item, "id") + field "name", jmes_path(col_item, "name") + field "status", jmes_path(col_item, "status") + field "updated_at", jmes_path(col_item, "updated_at") + field "template_id", jmes_path(col_item, "published_template.id") + field "template_name", jmes_path(col_item, "published_template.name") + end + end +end + + +datasource "ds_filtered_policy_aggregates" do + run_script $js_filtered_policy_aggregates, $ds_policy_aggregates, $param_days_back, $param_filter, $param_applied_filter, $param_aggregates, policy_id +end + +script "js_filtered_policy_aggregates", type: "javascript" do + parameters "ds_policy_aggregates", "param_days_back", "param_filter", "param_applied_filter", "param_aggregates", "self_id" + result "result" + code <<-EOS + today = new Date() + + result = _.filter(ds_policy_aggregates, function(policy) { + terminate_policy = param_aggregates == 'Yes' + + // Prevent policy from terminating itself + if (policy['id'] == self_id) { terminate_policy = false } + + // Prevent policy from terminating newly applied/updated policies + policy_date = new Date(policy['created_at']) + policy_age = Math.round((today - policy_date) / 1000 / 60 / 60 / 24) + + if (policy_age < param_days_back) { terminate_policy = false } + + // Prevent policy from terminating user-specified policies + if (param_filter.length > 0) { + if (_.contains(param_filter, policy['template_name']) && typeof(policy['template_name']) == 'string' && policy['template_name'] != '') { + terminate_policy = false + } + } + + if (param_applied_filter.length > 0) { + if (_.contains(param_applied_filter, policy['name'])) { terminate_policy = false } + } + + return terminate_policy + }) +EOS +end + +datasource "ds_terminate_aggregates" do + iterate $ds_filtered_policy_aggregates + request do + auth $auth_flexera + host rs_governance_host + path val(iter_item, 'href') + verb "DELETE" + header "User-Agent", "RS Policies" + header "Api-Version", "1.0" + ignore_status [400, 401, 402, 403, 404, 405] + end + result do + encoding "text" + end +end + +datasource "ds_terminate_all" do + run_script $js_terminate_all, $ds_terminate_applied_policies, $ds_terminate_aggregates +end + +script "js_terminate_all", type: "javascript" do + parameters "ds_terminate_applied_policies", "ds_terminate_aggregates" + result "result" + code "result = []" +end + +############################################################################### +# Policy +############################################################################### + +policy "pol_terminate_policies" do + validate $ds_terminate_all do + summary_template "{{ len data }} Applied Policies Terminated" + detail_template "" + check eq(0, 0) + end +end