bcrypt example in Golang

Tagged bcrypt, golang  Languages go
package main

import (
    "golang.org/x/crypto/bcrypt"
    "log"
    "os"
)

// NOTE: You need to escape the dollar signs in the hash with \
// HASH="xxx" PASSWORD=xxx go run main.go
func main() {
    hash, ok := os.LookupEnv("HASH")
    if !ok {
        log.Fatal("The HASH environment variable is not set")
    }
    password, ok := os.LookupEnv("PASSWORD")
    if !ok {
        log.Fatal("The PASSWORD environment variable is not set")
    }
    if isMatch(password, hash) {
        log.Printf("Match '%s' == '%s'", hash, password)
    } else {
        log.Printf("Mismatch '%s' != '%s'", hash, password)
    }
}

func isMatch(password string, hash string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
    return err == nil
}

For loop in Postgres

Tagged for, loop, postgres  Languages sql
DO
$$
DECLARE
    row record;
BEGIN
    FOR row IN SELECT tablename FROM pg_tables WHERE schemaname = 'public'
    LOOP
        EXECUTE 'ALTER TABLE public.' || quote_ident(row.tablename) || ' SET SCHEMA <new schema>;';
    END LOOP;
END;
$$;

How to read barcodes with ZXing and ZBar

Tagged barcode, code 39, data matrix, qr code, zbar, zxing  Languages bash

How to read barcodes

$ java -cp javase.jar:core.jar com.google.zxing.client.j2se.CommandLineRunner barcode.png --try_harder --format=DATA_MATRIX
$ zbarimg barcode.png

Note that cropping might improve detection accuracy. For example, crop image to show only the top-right corner using imagemagick’s convert (width 1500, height 500):

$ convert example.png -gravity northeast -crop 1500x500+0+0 cropped.png

NOTE

  • if you need data correction (reliability) use a Data Matrix (used on e.g. products), Aztec (used on e.g. tickets), or QR code. These allow up to 30% of the image to be unreadable.
  • do not use a barcode that uses code 39 or 128. There is no error correction in code 39 and 128.
  • SimpleCV can also be used to detect barcodes.

Log shipping with rsyslog

Tagged logging, logs, remote, rsyslog, shipping  Languages 

Server

/etc/rsyslog.conf

$ModLoad imtcp
 
#
# Disable rate-limiting
#
# "interval = 1 AND burst = 1000" means rsyslog starts dropping messages if more than 1000 messages are received within 1 seconds. 
$SystemLogRateLimitInterval 0
$SystemLogRateLimitBurst 0

/etc/rsyslog.d/35-remote-logs.conf

input(type="imtcp" port="514" ruleset="remote")
template(name="PerRemoteHostLogFileName" type="list") {
   constant(value="/var/log/hosts/")
   property(name="$year")
   constant(value="/")
   property(name="$month")
   constant(value="/")
   property(name="hostname" securepath="replace")
   constant(value="/")
   property(name="programname" securepath="replace")
   constant(value=".log")
}
ruleset(name="remote") {
   $FileCreateMode 0640
   $DirCreateMode 0755
   ?PerRemoteHostLogFileName
}

Client

/etc/rsyslog.conf

# Disable rate-limiting
$SystemLogRateLimitInterval 0
$SystemLogRateLimitBurst 0

#
# Send all logs to centralized log server over TCP
#
*.*       @@{{log_server_ip_addr}}

How to deploy an app on a specific node/server in a kubernetes cluster using labels

Tagged kubernetes, label, node  Languages yaml

This is an example of how to deploy an app on a specific node/server in a kubernetes cluster using labels:

# # Label one node in k8s cluster
#
# $ kubectl label nodes 48.234.16.45 country=finland name=node1
#
# # Deploy 1 nginx pod in k8s cluster on node1 in Finland
#
# $ kubectl apply -f nginx.yml
#
# # View deployment
#
# $ kubectl describe deployment nginx-app
#
# # View pods
#
# $ kubectl get pods -l app=nginx
#
# # Find port the service is listening on
#
# $ kubectl describe service nginx-app | grep NodePort
# > NodePort:                 http   31796/TCP
# > NodePort:                 https  31797/TCP
#
# # Find the node the pod is deployed to
#
# $ kubectl describe pods nginx-app | grep Node
# > Node:           48.234.16.45/10.0.0.2
#
# # Access deployment using node ip and port
#
# http://<node ip>:<node port>
#
# # Export service to YAML
#
# $ kubectl get service nginx-app -o yaml --export
#
# # Delete
#
# $ kubectl delete deployments,services -l country=finland
#
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
  labels:
    run: nginx-app
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1 # tells deployment to run 1 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.13.12
        ports:
        - containerPort: 80
        - containerPort: 443
      nodeSelector:
        country: finland
        server: node1
---
#
# Expose deployment on <node ip>:<node port>. Node and a random port is assigned by k8s.
#
apiVersion: v1
kind: Service
metadata:
  labels:
    run: nginx-app
  name: nginx-app
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
  selector:
    app: nginx
  type: NodePort

Kill OSX disk warning notification

Tagged kill, notification, osx  Languages bash

Kill OSX disk warning notification:

$ defaults write com.apple.diskspaced minFreeSpace 1

This prevents it from showing up every second, if free disk space is above 1 Gb.

How to SSH with Go

Tagged go, ssh  Languages go, bash

How to SSH with Go.

main.go:

package main

import (
    "bytes"
    "flag"
    "golang.org/x/crypto/ssh"
    "io/ioutil"
    "log"
    "os"
    "strings"
)

var host string
var port string
var user string
var command string
var keyPath string
var keyPass string

func init() {
    flag.StringVar(&host, "host", "", "SSH hostname or IP")
    flag.StringVar(&port, "port", "", "SSH port")
    flag.StringVar(&user, "user", "", "SSH user")
    flag.StringVar(&command, "command", "", "Command to execute on server")
    flag.StringVar(&keyPath, "key-path", "", "For example, ~/.ssh/id_rsa")
    flag.StringVar(&keyPass, "key-password", "", "Password for private key (optional)")
    flag.Parse()
    if host == "" || port == "" || command == "" || user == "" || keyPath == "" {
        flag.PrintDefaults()
        os.Exit(2)
    }
}

func readPubKey(file string) ssh.AuthMethod {
    var key ssh.Signer
    var err error
    var b []byte
    b, err = ioutil.ReadFile(file)
    mustExec(err, "failed to read public key")
    if !strings.Contains(string(b), "ENCRYPTED") {
        key, err = ssh.ParsePrivateKey(b)
        mustExec(err, "failed to parse private key")
    } else {
        key, err = ssh.ParsePrivateKeyWithPassphrase(b, []byte(keyPass))
        mustExec(err, "failed to parse password-protected private key")
    }
    return ssh.PublicKeys(key)
}

func main() {
    conf := &ssh.ClientConfig{
        User: user,
        Auth: []ssh.AuthMethod{
            readPubKey(keyPath),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(), // XXX: Security issue
    }
    client, err := ssh.Dial("tcp", strings.Join([]string{host, ":", port}, ""), conf)
    mustExec(err, "failed to dial SSH server")
    session, err := client.NewSession()
    mustExec(err, "failed to create SSH session")
    defer session.Close()
    var b bytes.Buffer
    session.Stdout = &b
    err = session.Run(command)
    mustExec(err, "failed to run command over SSH")
    log.Printf("%s: %s", command, b.String())
}

func mustExec(err error, msg string) {
    if err != nil {
        log.Fatalf("%s:\n  %s", msg, err)
    }
}

This command will run a command on a remote SSH server:

go run main.go -command whoami -host bush.com -key-path ~/.ssh/id_rsa -port 22 -user jeb

Also see:

Repeatable-read vs read-committed example in Rails / ActiveRecord

Tagged isolation, postgres, read-commited, repeatable-read, transaction, activerecord, rails  Languages ruby
ActiveRecord::Base.logger = Logger.new(STDOUT)

require "test/unit/assertions"
include Test::Unit::Assertions

class Cust1 < ActiveRecord::Base
  self.table_name = "customers"
end

class Cust2 < ActiveRecord::Base
  self.table_name = "customers"
end

# NOTE: Two separate connections
Cust1.establish_connection :development
Cust2.establish_connection :development

Cust1.find_by(username: 'z@localhost').try(:delete)

c = Cust1.create!(first_name: 'Putin', last_name: 'jebus', password_digest: 'abcdef12345', username: 'z@localhost')

case ENV['isolation']
when 'repeatable_read'
  #
  # NOTE: Repeatable-read isolation
  #
  # This level is different from Read Committed in that a query in a repeatable
  # read transaction sees a snapshot as of the start of the transaction, not as
  # of the start of the current query within the transaction. Thus, successive
  # SELECT commands within a single transaction see the same data, i.e., they do
  # not see changes made by other transactions that committed after their own
  # transaction started.
  #
  puts "Repeatable read"
  assert ActiveRecord::Base.connection.transaction_isolation_levels.include?(:repeatable_read)
  Cust1.transaction(isolation: :repeatable_read) do
    c.reload
    Cust2.find(c.id).update_attributes(first_name: 'Stalin')
    c.reload
    assert_equal 'Putin', c.first_name
  end
  c.reload
  assert_equal 'Stalin', c.first_name
else
  #
  # NOTE: Read-committed isolation
  #
   # Read Committed is the default isolation level in PostgreSQL. When a
  # transaction uses this isolation level, a SELECT query (without a FOR
  # UPDATE/SHARE clause) sees only data committed before the query began; it
  # never sees either uncommitted data or changes committed during query
  # execution by concurrent transactions. In effect, a SELECT query sees a
  # snapshot of the database as of the instant the query begins to run.
  # However, SELECT does see the effects of previous updates executed within
  # its own transaction, even though they are not yet committed. Also note that
  # two successive SELECT commands can see different data, even though they are
  # within a single transaction, if other transactions commit changes after the
  # first SELECT starts and before the second SELECT starts.
  #
  puts "Read committed"
  Cust1.transaction do
    c.reload
    Cust2.find(c.id).update_attributes(first_name: 'Stalin')
    c.reload
    assert_equal 'Stalin', c.first_name
  end
  c.reload
  assert_equal 'Stalin', c.first_name
end

See