INT 21h

Hi, I am Vladimir Smagin, SysAdmin and Kaptain. Telegram Email / GIT / RSS / GPG

Python скрипт для быстрого получения токена из Селектел

№ 11253 В разделах: Programming Sysadmin от March 21st, 2021,
В подшивках: , ,

Получает токен по логину и паролю и отдает в виде строки без переносов. Крайне удобно использовать в bash скриптах. Пример использования в моем наборе скриптов для получения сертификатов LetsEncrypt для хранилища Селектел

import argparse
import requests

parser = argparse.ArgumentParser("get_selectel_token")
parser.add_argument("account", help="Your master account or subaccount, i.e. 83522 or 43544_somename", type=str)
parser.add_argument("password", help="Password for this account", type=str)
args = parser.parse_args()

headers = {'X-Auth-User': str(args.account), 'X-Auth-Key': str(args.password)}
response = requests.get("", headers=headers)
if response.status_code == 204:
    print(response.headers['X-Auth-Token'], end="")
    print("Error:", response.status_code)

Нет комментариев »

Smooth LED blink on Arduino, ESP8266, etc

№ 11244 В разделах: Electronics ESP8266 Programming от March 8th, 2021,
В подшивках: ,

Human eye can’t see led switching because its too fast, same effect used in old TV and displays with CRT, most of 7-segment indicators and other things. Change timings between on and off state to change brightness and effect duration.

int sv_max=20;
int sv_min=0;

void setup() {

void loop() {
  int pause_on=sv_min;
  int pause_off=sv_max;
  // Smooth turn on
  while(pause_on < sv_max) {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(LED_BUILTIN, LOW);
  // Smooth turn off
  while(pause_on > sv_min) {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(LED_BUILTIN, LOW);

Нет комментариев »

Credentials and other secrets from Vault to your containers at startup

№ 11183 В разделах: Programming Sysadmin от January 2nd, 2021,
В подшивках: , , , ,

What if you stored your database credentials in Vault and want to make ENV variables with them for your application at container startup? You can do it for Kubernetes deployments or plain Docker containers with my small program vault-envs.

Add to your Dockerfile additional steps:

  • install my vault-envs programs that “converts” secret to ENV variables
  • create\modify entrypoint script where or call vault-envs and other pre-startup actions

Add to your Dockerfile steps:

# add Ubuntu\Debian repo and install vault-envs with fresh certificates
RUN curl | apt-key add - && \
    echo "deb bionic main" | tee /etc/apt/sources.list.d/21h.list && \
    apt update
RUN apt install -y ca-certificates vault-envs

# copy entrypoint script
RUN chmod +x /


Your entrypoint script will look like:



export eval `vault-envs -token "$VAULT_TOKEN" \
        -vault-url \
        -vault-path /prod/crm/connection_postgres -envs-prefix "PG_"`

export eval `vault-envs -token "$VAULT_TOKEN" \
        -vault-url \
        -vault-path /prod/crm/connection_mysql -envs-prefix "MYSQL_"`

export eval `vault-envs -token "$VAULT_TOKEN" \
        -vault-url \
        -vault-path /prod/crm/connection_api`


exec "$@"

If some vars names is identical they will be overwritten at next vault-envs call, so I used prefix.

Now build image and run

docker run --rm -e VAULT_TOKEN=s.QQmLlqnHnRAEO9eUeoggeK1n crm printenv

and see results at container console:


Wooh! You did it.

Нет комментариев »

Golang: marshal and unmarshal iota (yaml, json, toml)

№ 11025 В разделе "Programming" от June 16th, 2020,
В подшивках:

Tried to unmarshal enum value from app config file and failed?

  masterDB: "ips.sdb"
  clean: Full

Use strings instead of iota.

const (
	CleanRecreate  = "Recreate" // completely remove DB file and create again
	CleanFull      = "Full" // delete all and vacuum
	CleanLastDay   = "LastDay" // remove all before last day
	CleanLastWeek  = "LastWeek"
	CleanLastMonth = "LastMonth"
	CleanNever     = "Never" // do nothing

type CleanType string

type AppConfig struct {
	DB    struct {
		MasterDB string    `yaml:"masterDB"`        // master sqlite database
		Clean    CleanType `yaml:"clean,omitempty"` // cleanup at startup
	} `yaml:"DB"`

Now load config file:

func main() {
	if *configFilename == "" {
		log.Fatalln("Set configuration filename")

	// read settings from file
	log.Println("Loading config file", *configFilename)
	appConfig := AppConfig{}

	yamlFile, err := ioutil.ReadFile(*configFilename)
	if err != nil {
		log.Fatalf("Config read error: %v\n", err)
	err = yaml.Unmarshal(yamlFile, &appConfig)
	if err != nil {
		log.Fatalf("Config format error: %v\n", err)

	switch appConfig.DB.Clean {
	case CleanRecreate:
		log.Println("Recreate cleanup option set")
	case CleanFull:
		log.Println("Full cleanup option set")
	case CleanLastDay:
		log.Println("Save only last day cleanup option set")
	case CleanLastWeek:
		log.Println("Save only last week option set")
	case CleanLastMonth:
		log.Println("Save only last month option set")
	dbHandler := dbLoadFile(appConfig.DB.MasterDB)
	defer dbHandler.Close()

Here is another solution

Нет комментариев »

Простой способ подготовки библиотеки на golang к тестированию

№ 11006 В разделе "Programming" от May 26th, 2020,
В подшивках:

Чтобы без проблем тестировать программы, написанные с использованием вашей библиотеки ее необходимо подготовить для этого. Делаем интерфейс, который будет использоваться в тестах, где ваши реальные функции будут заменены функциями с тестовыми данными.

package main

import "fmt"

// library 

type FooAdapter interface {
	Read() string

type Foo struct {
	mvar    string

func NewFoo(v string) FooAdapter {
	return &Foo{mvar:v}

func (a *Foo) Read() string {
	return "orig: " + a.mvar

// test 

func NewFooStub(v string) FooAdapter {
	return &FooStub{mvar: v}

type FooStub struct {
	mvar string

func (s *FooStub) Read() string {
	return "stub: " + s.mvar

func main() {
	z := NewFoo("o")
	fmt.Println("Read", z.Read())
	m := NewFooStub("s")
	fmt.Println("Read", m.Read())

Нет комментариев »


Fortune cookie: There are three kinds of lies: lies, damned lies and statistics. -- Benjamin Disraeli