Giter VIP home page Giter VIP logo

cortex-cli's Introduction

Cortexapps CLI

A command-line interface for Cortexapps.

made-with-python PyPI version shields.io PyPI download month PyPI license PyPI pyversions

Installation

pypi.org

pip install cortexapps-cli

Using a python virtual environment:

VENV_DIR=~/.venv/cortex
python3 -m venv $VENV_DIR
source $VENV_DIR/bin/activate
pip install cortexapps-cli

homebrew

brew tap cortexapps/tap
brew install cortexapps-cli

Usage

Config file

The CLI requires an API key for all operations. This key is stored in a config file whose default location is ~/.cortex/config. This path can be overridden with the -c flag.

Minimal contents of the file:

[default]
api_key = REPLACE_WITH_YOUR_CORTEX_API_KEY

If you have multiple Cortex instances, you can create a section for each, for example:

[default]
api_key = REPLACE_WITH_YOUR_CORTEX_API_KEY

[my-test]
api_key = REPLACE_WITH_YOUR_CORTEX_API_KEY
base_url = https://app.cortex.mycompany.com

NOTE: if not supplied, base_url defaults to https://app.getcortexapp.com.

The CLI will retrieve configuration data from the [default] section unless you pass the -t/--tenant flag.

For example, to list all entities in the my-test tenant, run the following command:

cortex -t my-test catalog list

If the config file does not exist, the CLI will prompt you to create it.

Environment Variables

The CLI supports the following environment variables. If provided, the Cortex config file will not be read.

Example:

export CORTEX_API_KEY=<YOUR_API_KEY>

Commands

Run cortex -h to see a list of all commands:

Run cortex <subcommand> -h to see a list of all commands for each subcommand.

For example:

cortex audit-logs -h
usage: cortex CLI audit-logs [-h] {get} ...

positional arguments:
  {get}       audit logs help
    get       retrieve audit logs

options:
  -h, --help  show this help message and exit

Examples

Almost all CLI responses return JSON or YAML. Tools like jq and yq will be helpful to extract content from these responses.

Export from one tenant; import into another

This example shows how to export from a tenant named myTenant-dev and import those contents into a tenant named myTenant.

Your cortex config file will require api keys for both tenants. It would look like this:

[myTenant]
api_key = <your API Key for myTenant>

[myTenant-dev]
api_key = <your API Key for myTenant-dev>

Export

cortex -t myTenant-dev backup export
Getting resource definitions
 -->  my-resource-1
 Getting catalog entities
 -->  my-domain-1
 -->  my-service-1
 -->  my-service-2
 Getting IP Allowlist definitions
 Getting scorecards
 -->  my-scorecard-1
 Getting teams
 -->  my-team-1
 -->  my-team-2

 Export complete!
 Contents available in /Users/myUser/.cortex/export/2023-11-19-14-58-14

Import

cortex -t myTenant backup import -d <directory created by export>

NOTE: some content will not be exported, including integration configurations and resources that are automatically imported by Cortex. Cortex does not have access to any keys, so it cannot export any integration configurations.

-------------------------------------------Export all services from one tenant; import into another -------------------------------------------

This example shows how to export services from a tenant named myTenant-dev and import those services into a tenant named myTenant. It is similar to the full export example "Export from one tenant; import into another", but only exports/imports services.

Your cortex config file will require api keys for both tenants. It would look like this:

[myTenant]
api_key = <your API Key for myTenant>

[myTenant-dev]
api_key = <your API Key for myTenant-dev>

Option 1: export service YAMLs to a directory and then import them

This option is helpful in case you want to save the entity YAML files. It makes it easy to restart or retry an import because you will have all YAMLs saved on disk.

Export

mkdir -p /tmp/cortex-export
cd /tmp/cortex-export
for service in `cortex -t myTenant catalog list -t service | jq -r ".entities[].tag" | sort`
do
   cortex -t myTenant catalog descriptor -y -t ${service} > ${service}.yaml
done

Import

cd /tmp/cortex-export
for file in `ls -1 *.yaml`
do
   cortex -t myTenant-dev catalog create -f ${file}
done

Option 2: combine the export and import in a single command

This option is simpler and doesn't require any disk operations. However, if it fails for any reason you have to run the entire export/import in its entirety.

for service in `cortex -t myTenant catalog list -t service | jq -r ".entities[].tag" | sort`
do
   echo "Processing service: ${service}"
   cortex -t myTenant catalog descriptor -y -t ${service} | cortex -t myTenant-dev catalog create -f-
done

-------------------------------------------Export all domains from one tenant; import into another -------------------------------------------

This example shows how to export domains from a tenant named myTenant-dev and import those domains into a tenant named myTenant. It is similar to the full export example "Export from one tenant; import into another", but only exports/imports domains.

Your cortex config file will require api keys for both tenants. It would look like this:

[myTenant]
api_key = <your API Key for myTenant>

[myTenant-dev]
api_key = <your API Key for myTenant-dev>

Option 1: export domain YAMLs to a directory and then import them

This option is helpful in case you want to save the entity YAML files. It makes it easy to restart or retry an import because you will have all YAMLs saved on disk.

Export

mkdir -p /tmp/cortex-export
cd /tmp/cortex-export
for domain in `cortex -t myTenant catalog list -t domain | jq -r ".entities[].tag" | sort`
do
   echo "creating ${domain}.yaml"
   cortex -t myTenant catalog descriptor -y -t ${domain} > ${domain}.yaml
done

Import

cd /tmp/cortex-export
for file in `ls -1 *.yaml`
do
   cortex -t myTenant-dev catalog create -f ${file}
done

Option 2: combine the export and import in a single command

This option is simpler and doesn't require any disk operations. However, if it fails for any reason you have to run the entire export/import in its entirety.

for domain in `cortex -t myTenant catalog list -t domain | jq -r ".entities[].tag" | sort`
do
   echo "Processing domain: ${domain}"
   cortex -t myTenant catalog descriptor -y -t ${domain} | cortex -t myTenant-dev catalog create -f-
done

Iterate over all domains

for domain in `cortex catalog list -t domain | jq -r ".entities[].tag" | sort`; do echo "domain = $domain"; done

Iterate over all teams

for team in `cortex catalog list -t team | jq -r ".entities[].tag" | sort`; do echo "team = $team"; done

Iterate over all services

for service in `cortex catalog list -t service | jq -r ".entities[].tag" | sort`; do echo "service = $service"; done

Get git details for a service

cortex catalog details -t my-service-1 | jq ".git"
{
  "repository": "my-org/my-service-1",
  "alias": null,
  "basepath": null,
  "provider": "github"
}

Add a suffix to all x-cortex-tag values for services

for service in `cortex catalog list -t service | jq -r ".entities[].tag" | sort`; do
   cortex catalog descriptor -y -t ${service} | yq '.info.x-cortex-tag |= . + "-suffix"' | cortex catalog create -f-
done

This example combines several CLI commands:

  • the for loop iterates over all services
  • the descriptor for each service is retrieved in YAML format
  • the YAML descriptor is piped to yq where the value of x-cortex-tag is retrieved and modified to add "-suffix" to the end
  • the modified YAML is then piped to the cortex catalog command to update the entity in cortex

NOTE: Any cortex commands that accept a file as input can also receive input from stdin by specifying a "-" after the -f parameter.

Add a group to all domains

for domain in `cortex catalog list -t domain | jq -r ".entities[].tag" | sort`; do
   cortex catalog descriptor -y -t ${domain} | yq -e '.info.x-cortex-groups += [ "my-new-group" ]' | cortex catalog create -f-
done

Remove a group from domains

for domain in `cortex catalog list -t domain -g my-old-group | jq -r ".entities[].tag" | sort`; do
   cortex catalog descriptor -y -t ${domain} | yq -e '.info.x-cortex-groups -= [ "my-old-group" ]' | cortex catalog create -f-
done

Add a domain parent to a single service

cortex catalog descriptor -y -t my-service | yq -e '.info.x-cortex-domain-parents += { "tag": "my-new-domain" }' | cortex catalog create -f-

Add a github group as an owner to a service

cortex catalog descriptor -y -t my-service | yq -e '.info.x-cortex-owners += { "name": "my-org/my-team", "type": "GROUP", "provider": "GITHUB" }' | cortex catalog create -f-

Modify all github basepath values for domain entitities, changing '-' to '_'

for domain in `cortex catalog list -t domain | jq -r ".entities[].tag"`; do 
   cortex catalog descriptor -y -t ${domain} | yq ".info.x-cortex-git.github.basepath |= sub(\"-\", \"_\")" | cortex catalog create -f-
done

Modify deploys based on selection criteria

This example fixes a typo in the deployment environment field, changing PYPI.org to PyPI.org.

It loops over each selected array element based on the search criteria, removes the uuid attribute (because that is not included in the payload), assigns the environment attribute to the correct value and invokes the CLI with that input.

cortex deploys list -t cli > /tmp/deploys.json
for uuid in `cat /tmp/deploys.json | jq -r '.deployments[] | select(.environment=="PYPI.org") | .uuid'`
do
   cat /tmp/deploys.json | jq ".deployments[] | select (.uuid==\"${uuid}\") | del(.uuid) | .environment = \"PyPI.org\"" | cortex deploys update-by-uuid -t cli -u ${uuid} -f-
done

Create a backup of all scorecards

for tag in `cortex scorecards list | jq -r ".scorecards[].tag"`
do
   echo "backing up: ${tag}"
   cortex scorecards descriptor -t ${tag} > ${tag}.yaml
done

Create a copy of all scorecards in draft mode

This recipe creates a draft scorecard for all existing scorecards. It creates each scorecard with a suffix for the scorecard tag of "-draft" and it appends " Draft" to the end of the existing title.

for tag in `cortex scorecards list | jq -r ".scorecards[].tag"`
do
   cortex scorecards descriptor -t ${tag} | yq '.draft = true | .tag += "-draft" | .name += " Draft"' | cortex scorecards create -f-
done

Replace scorecards with draft versions and delete the draft versions

This recipe is a companion to the above recipe. This recipe will replace the versions from which the drafts were created and delete the drafts.

for tag in `cortex scorecards list -s | jq -r ".scorecards[].tag" | grep "\-draft$"`
do
   cortex scorecards descriptor -t ${tag} | yq '.draft = false | .tag |= sub("-draft","") | .name |= sub(" Draft", "")' | cortex scorecards create -f- && cortex scorecards delete -t ${tag}
done

Get draft scorecards, change draft to false and save on disk

This recipe is similar to the one above, but it does not create a new scorecard in Cortex. Rather, it makes the changes and saves to a file.

for tag in `cortex scorecards list -s | jq -r ".scorecards[].tag" | grep "\-draft$"`
do
   cortex scorecards descriptor -t ${tag} | yq '.draft = false | .tag |= sub("-draft","") | .name |= sub(" Draft", "")' > ${tag}.yaml
done

Delete all draft scorecards

WARNING: This recipe will delete all draft scorecards.

for tag in `cortex scorecards list -s | jq -r ".scorecards[].tag"`
do
   cortex scorecards delete -t ${tag}
done

If you only want to delete some drafts, for example if you followed a recipe that creates draft versions of all existing scorecards, you will likely want to run this instead:

for tag in `cortex scorecards list -s | jq -r ".scorecards[].tag" | grep "\-draft$"`
do
   cortex scorecards delete -t ${tag}
done

Compare scorecard scores and levels for two scorecards

This could be helpful for changing CQL rules (for example for CQL v1 -> CQL v2) and ensuring that scorecards produce the same results.

The following command get all scores for a scorecard, pipes the JSON output to jq and filters it to create a CSV file of the form:

service,score,ladderLevel
cortex scorecards scores -t myScorecard | jq -r '.serviceScores[] | [ .service.tag, .score.ladderLevels[].level.name // "noLevel", .score.summary.score|tostring] | join(",")' | sort > /tmp/scorecard-output.csv

Run this command for two different scorecards and diff the csv files to compare results

export SCORECARD=scorecard1
cortex scorecards scores -t ${SCORECARD} | jq -r '.serviceScores[] | [ .service.tag, .score.ladderLevels[].level.name // "noLevel", .score.summary.score|tostring] | join(",")' | sort > /tmp/${SCORECARD}.csv

export SCORECARD=scorecard2
cortex scorecards scores -t ${SCORECARD} | jq -r '.serviceScores[] | [ .service.tag, .score.ladderLevels[].level.name // "noLevel", .score.summary.score|tostring] | join(",")' | sort > /tmp/${SCORECARD}.csv

sdiff -s /tmp/scorecard1.csv /tmp/scorecard2.csv

Delete all Workday teams

This recipe is helpful if you want to remove all Workday teams and import from scratch.

for team in `cortex teams list | jq -r '.teams[] | select (.type == "IDP") | select (.idpGroup.provider == "WORKDAY") | .teamTag'`
do
    cortex team delete -t ${team}
done

cortex-cli's People

Contributors

jeff-schnitter avatar shawnburke avatar rich-jay avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.