evoke Get started

Examples · 03 of 06

Operate services in your team's words.

Scale a service, mute an alert, roll back a release. Your service names map to the arguments kubectl needs. A write runs when the bar is met, and a rollback asks every time. A pattern for your app: the tooling, the credentials and the cluster access stay yours.

The request and the result

01

Scale, silence, roll back.

Three reflexes for one channel. A write runs when the bar is met. A rollback always asks. Every line is what the terminal printed.

~/ops
$ evoke "silence db-3 for 2 hours" silence host="db-3" duration="2 hours" 0.99 db-3 silenced until 01:12 AM
  1. 1kubectl, no code. The scale reflex is a manifest and nothing else: a program with its arguments, filled from the sentence.
  2. 2Your names, from a vocabulary. «checkout» is a word whose value is checkout-api. The program gets the value. The classifier sees the word.
  3. 3The rollback is destructive. Sure at 0.99, and it still asked. A release moved only after the yes.

The operations

02

The same reflexes as files, as code, and in the app.

A manifest around kubectl, the team's names in a file, and the eight-line app that runs a sentence. In code, the same text, and with hands the names over.

scale/reflex.tomlthe author's
reflex = 1

description = """
Scale a service to a number of replicas.
One deployment in one environment; the number is set, never added to."""
not_for = [
  "restarting or rolling back a service",
  "resizing a database or a disk",
  "autoscaling rules",
]
tags    = ["ops"]
effect  = "write"
confirm = "Scale {service} in {env} to {replicas}?"
run     = [
  "kubectl", "-n", "{env}", "scale", "deployment", "{service}",
  "--replicas", "{replicas}",
]

[args.service]
ask   = "Which service?"
vocab = "services"

[args.env]
ask   = "Which environment?"
vocab = "envs"

[args.replicas]
ask   = "How many replicas?"
pick  = "number"
range = [1, 20]

[examples]
"scale checkout to 6 in staging"   = { replicas = "6" }
"run 3 replicas of search in prod" = { replicas = "3" }
"take payments down to 1 replica"  = { replicas = "1" }

[tests]
"bring checkout up to 12 in prod" = { replicas = "12" }
"scale checkout"                  = { replicas = false }
"restart checkout"                = false
vocab/services.tomlyours
checkout = { what = "The checkout API.", value = "checkout-api" }
search   = { what = "The search API.", value = "search-api" }
payments = { what = "Payments; also 'the gateway'.", value = "payments-svc" }
  1. 1An argv body needs no runtime. Each placeholder is a whole element, filled with the word's value or the number's text. Never through a shell.
  2. 2silence and rollback follow the same shape. A duration read from the sentence, a host from your words, and a destructive effect on the rollback.
  3. 3The app is two handlers. A confirm is a question. An ask is a numbered menu. Twenty lines, shared by every example here.

One boundary

03

A missing environment is asked for, from your own list.

The sentence named the service and the number, not where. evoke offered the environments you defined, and decided again with the answer.

evoke
$ evoke "take payments down to 1 replica"
  Which environment?  [1] staging  [2] prod  [+] add one  > 2
  scale service="payments" env="prod" replicas="1"  0.95
deployment.apps/payments-svc scaled

The choice came from vocab/envs.toml, never from the classifier. Piped from a file with no terminal, this line would exit 3 instead, and name the command to run yourself.

Before you run it

04

What this pattern needs.

The files above are the whole example. Copy them from this page.