Skip to content

My fancy pants cleanup tool for OCI compartments

License

Notifications You must be signed in to change notification settings

flynnkc/ociextirpater

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

95 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

README for ociextirpate

extirpate : ex·tir·pate : to completely erase or eradicate

What it is and does

The OCI Extirpater is a command line tool that deletes everything within a compartment in every subscribed OCI region.

How it does it

The tool uses the OCI SDK to

  1. find every compartment underneath the specified root
  2. find every object within that compartment
  3. delete the object

The code for each object type is actually quite small (see ociclients/template.py).

In short that code declares:

  • the class in the OCI SDK to be used
  • (optionally) the "composite class" to be used
  • the name (both singular and plural) for human-readable logging
  • the method in the class used to list and delete the object
  • (optionally) specific formatters to generate a "one-liner" for the object

A class may also override some of the stuff in OCIClient.py in cases where the client class works differently than typical.

Quick Start

NOTE: OCIExtirpate supports a number of command line options including allowing you to limit the resource types and regions it explores and cleans. Running ociextirpate.py without any command line options will show you command line help.

Running from your laptop

  1. Set up the OCI CLI following the instructions in the public documentation
  2. copy the code to your machine
    • if you have registered your ssh key in GitHub:
      • run "git clone ssh://github.com/therealcmj/ociextirpater.git"
    • if you have NOT registered you ssh key in GitHub:
      • run git clone https://github.com/therealcmj/ociextirpater.git
  3. cd into "ociextirpater"
  4. run "./ociextirpate.py -c ocid1.compartment.oc1..XXXX"
    • replacing ocid1.compartment.oc1..XXXX with the compartment you want to clean

Running in Cloud Shell

Since iterating over all child compartments, regions, and resources types is a slow process and Cloud Shell has a relatively short timeout before disconnecting it is generally preferable to run extirpater from your laptop or from a compute instance.

But if you want to run it from Cloud Shell that is supported:

  1. open Cloud Shell
  2. run git clone https://github.com/therealcmj/ociextirpater.git
    • You need to use https rather than ssh since you likely won't have an ssh key for your Cloud Shell registered in GitHub
  3. cd into "ociextirpater"
  4. run "./ociextirpate.py -c ocid1.compartment.oc1..XXXX -dt"
    • replacing ocid1.compartment.oc1..XXXX with the compartment you want to clean

Running as a Function

  1. Set up a development environment based on the Functions documentation.

  2. On Function Application APP_NAME or the underlying ociextirpater function, enter the following Configurations

    • EXTFN_COMPARTMENT for the compartment to extirpate, either standalone or as a comma separated string

      • example: ocid1.compartment.oc1..abcd,ocid1.compartment.oc1..1234
      • example: ocid1.tenancy.oc1..abcd
    • (optional) EXTIRPATER_PREFIX if you want to use a different prefix than the default of EXTFN

    • (optional) EXTFN_REGIONS a comma seperated list, for region(s) to extirpate (default all subscribed regions)

    • (optional) EXTFN_OBJECTS for objects to extirpate

    • (optional) EXTFN_FORCE to force deletion

    • (optional) EXTFN_DEBUG to activate debug mode

    • (optional) EXTFN_SKIP_DELETE_COMPARTMENT to skip deleting compartments

  3. Run fn deploy --app {APP_NAME}

  4. Run fn invoke {APP_NAME} ociextirpater

Use Resources Scheduler, OCI Events, or another method to automate invokation.

More info

Blog post and more information

Check out my blog post at https://www.ateam-oracle.com/post/cleanup-an-oci-compartment

Available Arguments

usage: ociextirpate.py [-h] [-cf CONFIG_FILE] [-cp CONFIG_PROFILE] [-ip] [-dt] [-log LOG_FILE] [-force]
                       [-debug] [-skip_tagged SKIP_TAGGED] [-skip_delete_compartment] [-rg REGIONS]
                       [-c COMPARTMENT] [-o OBJECTS] [-t THREADS]

options:
  -h, --help            show this help message and exit
  -cf CONFIG_FILE       OCI Config file
  -cp CONFIG_PROFILE    Config Profile inside the config file
  -ip                   Use Instance Principals for Authentication
  -dt                   Use Delegation Token for Authentication
  -log LOG_FILE         output log file
  -force                force delete without confirmation
  -debug                Enable debug
  -skip_tagged SKIP_TAGGED
                        Skip resources tagged specific ways [namespace.]name[=value]
  -skip_delete_compartment
                        Skip Deleting the compartment at the end
  -rg REGIONS           Regions to delete comma separated (defaults to all subscribed regions)
  -c COMPARTMENT        top level compartment id to delete
  -o OBJECTS            Object catagories to work on. See docs for info
  -t THREADS            Number of threads

Special cases

Compartments

Please note that deleting a compartment (1) can take up to 2 hours and (2) that you can only queue up to 5 deletions at a time.

In order to help customers avoid problems this script treats compartments as a special case. When deleting compartments the script:

  • requests deletion of only 2 compartments per run
  • marks a (theoretically) empty compartment with the freeform tag ExtirpateAttempted before attempting to delete it
  • skips any compartments with the above tag

You can adjust this behavior by editing ociextirpater/ociclients/compartments.py.

This is generally not an issue for me and my team because we have this script running as a regularly scheduled job. Even if we delete only 2 compartments each day eventually every empty compartment is removed. Or as they say "it'll just work itself out naturally".

Inspiration

This was inspired by Richard Garsthagen's work on OCI Super Delete. In fact, I even stole (most of) the command line arguments from his script. Making this almost a drop in replacement.

I wanted to try my hand at something similar but that was less "code" and more "declarative". Mostly because I thought it would be nice to be able to add new object types to be deleted by simply declaring them rather than needing to write a bunch of code.

In the end I'm not sure my approach was better or worse (OCIClient.py is practically unreadable) but it was a good learning experience!

What's next

  • adding more objects
  • trying to use the Search service instead of iterating over every object type

About

My fancy pants cleanup tool for OCI compartments

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 100.0%