• Using Rails ecnrypted credentials in Rails 5.2

    From Rails 5.2 onwards, there is no longer a config/secrets.yml file created whenever a rails app is created. The default mechanism is to use credentials to unify the management and storage of confidential information.

    Within a new rails 5.2 app, you will see a config/credentials.yml.enc file which is encrypted by default using the config/master.key. The master.key file is the master key which is used to encrypt/decrypt data stored within the credentials.yml.enc file and as such, it is added to .gitignore by default.

    To view the contents of the encrypted file, you need to run the following:

    EDITOR="vim" bin/rails credentials:show
    

    This will display what was the contents of a file such as config/secrets.yml.

    Mine contains the following out of the box:

    # aws:
    #   access_key_id: 123
    #   secret_access_key: 345
    
    # Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
    secret_key_base: e86bd7e58727da9b818f0f5a8851e8e2c99679bb9ab0728e6d87fbf31febc26ff8b649dda74e8b5632d16521afb30066254a2e4d6869e2fb57cb93f072b3e0ef
    

    To edit/add new entries to the file:

    EDITOR="vim" bin/rails credentials:edit
    

    This will allow you to edit/update the entries within config/credentials.yml.enc

    You can still use the old YAML syntax to declare variables. For example:

    EDITOR="vim" bin/rails credentials:edit
    
    # Add the following snippet below
    foo:
      bar: baz
    

    To access any of the data during runtime, we can use Rails.application.credentials, which returns a ActiveSupport::EncryptedConfiguration object

    For example, to access the default secret_key_base:

    Rails.application.credentials.secret_key_base
    

    To access nested values, we can use:

    Rails.application.credentials.foo[:bar] # => baz
    
    ruby rails encryption
  • Fixing dep update reference not a tree error

    When running dep ensure -update <dependency> -v to update a depedency, one might run into the following error:

    Unable to update checked out version: fatal: reference is not a tree:
    

    This is due to the cached version of the dependency in GOPATH/pkg/dep/sources/<depname> being in detached HEAD state.

    To fix this, cd into the dep cache folder and update it manually:

    cd GOPATH/pkg/dep/sources/<depname>
    
    git checkout master # or branch specified in Gopkg.toml
    
    git pull
    

    Run dep ensure -update <dependency> again and it should work again.

    This is an open issue on the golang dep repository:

    golang dep
  • Using journalctl to check hardware / bootup errors

    While trying to figure out a hardware issue during startup, I discovered that on systemd systems, the journald daemon collects logs from early in the boot process.

    One can use journalctl to view systemd logs for issues:

    sudo journalctl -b -p err
    

    One can then page through the errors list, if any, to resolve any issue.

    Resources

    Wikipedia

    DigitalOcean tutorial

    redhat linux
  • yum update Protected multilib versions

    During a recent yum update, it failed with multiple lines of

    Error: Protected multilib versions:
    
    iptables-1.4.21-24.el7.i686 != iptables-1.4.21-23.el7.x86_64
    
    ( more error lines like above )
    ....
    
    

    From above, what the above error means is that for that specific package, version “X” of an RPM is installed for architecture x86_64 while yum was also instructed to install version “Y” of that same rpm for architecture i686.

    Rather than resolving each depedency manually, I enabled the Workstation Optional RPMs repo to locate the missing rpms and the problem was resolved:

    sudo subscription-manager repos --enable=rhel-7-workstation-optional-rpms
    
    sudo yum clean-all
    
    sudo rm -rf /var/cache/clean
    
    sudo yum update
    

    Additional Resources

    RedHat support ticket

    Same Issue from HPE

    redhat linux
  • Using kube-proxy to access deployments

    When we create a service on k8 cluster, it is often initialized with type of ClusterIP.

    We can still access the service using kubectl proxy.

    kubectl proxy allows one to interact with the API without the need for a Bearer token.

    Assuming we have a service called guestbook, we can access it as below:

    kubectl proxy > /dev/null &
    
    KC_PROXY_PID = $!
    
    SERVICE_PREFIX=http://localhost:8001/api/v1/proxy
    
    GUESTBOOK_URL = $SERVICE_PREFIX/namespaces/default/services/guestbook
    
    kubernetes kubectl proxy
  • Resolving dep ensure conflicts

    Sometimes when collborating on a golang project, it is possible to get dependency conflicts after runningdep ensure.

    The following is an approach I take to resolve them:

    • Run dep ensure -v with verbose to debug the issue.

    • Delete the repo’s Gopkg.lock

    • Clear out the ~GOPATH/src/pkg directory

    • Re-run dep ensure -v

    golang dep
  • Using virtualenv in python

    When working with python, sometimes it is important to create isolated environments due to compatibility issues with the libs being used. Some examples that come to mind is the dependency of pyOpenSSL lib by certbot or setting up a deep learning environment.

    To install virtualenv:

    pip install virtualenv
    

    To create an isolated environment based on a specific python version:

    virtualenv -p /usr/bin/python2.7 <path to env>
    

    Without the -p option, virtualenv defaults to the current python version.

    To activate the virtualenv:

    source <path to env>/bin/activate
    

    You should see the name of the virtualenv in brackets to the left of the terminal. As an extra step, do python -v to check that the version is the one specified above.

    To exit the virtualenv and return to the terminal:

    deactivate
    

    Also install virtualenvwrapper as it provides some useful utility commands to list and create virtualenvs:

    pip install virtualenvwrapper
    

    To list all available virtualenvs, for example:

    lsvirtualenv
    

    Additional Resources

    virtualenv docs

    virtualenvwrapper docs

    python virtualenv
  • golang pointer receiver error

    Assuming we have an interface declaration in go as so:

    type Stringer interface {
      String() string
    }
    

    We can create a custom struct to implement the interface like so:

    type struct MyStruct{
      Value string
    }
    
    func (m *MyStruct) String() string {
      return m.Value
    }
    

    If we try to assign a type of MyStruct to the Stringer interface, we will receive an error of __ MyType does not implement Stringer (String method has pointer receiver)__

    mytype := MyStruct{Value: "test"}
    
    var s Stringer
    s = m // throws the error above
    

    This is because the interface is defined on pointer types of *MyType and not the types of MyType

    To fix the error we just need to use the pointer type:

    mytype := MyStruct{Value: "test"}
    
    var s Stringer
    s = &m // no errors
    
    go golang error
  • Vendoring private github repos using dep

    When using dep for vendoring dependencies in a go project, I came across the issue of pulling down a private github repo. dep ensure -v keeps reporting of an error with the repo.

    To overcome this, you can create a ~/.netrc with your credentials to access the private repo. For example, when using github, you first need to create an Personal Github Token within your Account Settings. Then create a ~/.netrc file with the following format:

    machine github.com
        login [GITHUB USERNAME]
        password [GITHUB TOKEN]
    

    This is also documented in the dep repo:

    Private git repos using github token

    go golang dep
  • Kubectl and KUBECONFIG

    While working on a kubernetes based project, I had to set the $KUBECONFIG env variable in order to access a private cluster.

    Later, I started minikube and ran kubectl config view. This resulted in all my kubectl calls to the private cluster failing.

    The reason is due to the way kubectl config behaves when it detects the $KUBECONFIG env variable. According to the docs:

    kubectl config -h
    
    Modify kubeconfig files using subcommands like "kubectl config set current-context my-context"
    
    The loading order follows these rules:
    
      1. If the --kubeconfig flag is set, then only that file is loaded.  The flag may only be set once
    and no merging takes place.
    
      2. If $KUBECONFIG environment variable is set, then it is used a list of paths (normal path
    delimitting rules for your system).  These paths are merged.  When a value is modified, it is
    modified in the file that defines the stanza.  When a value is created, it is created in the first
    file that exists.  If no files in the chain exist, then it creates the last file in the list.
    
      3. Otherwise, ${HOME}/.kube/config is used and no merging takes place.

    As stated in point 2 above, since my $KUEBCONFIG is still present, when I started minikube, it merges the minikube settings into file pointed to by $KUBECONFIG, updating it by merging the contents of minikube, and sets minikube as the current context. Which is why all the kubectl calls are going to the minikube cluster only.

    As a note to self, I need to remember to

    unset $KUBECONFIG
    kubernetes kubectl
  • Redhat Subscription Renewal

    Recently I had to update my Redhat subscription.

    Afterwards, the subscription-manager application kept showing as “No valid subscriptions found”. This was caused by a mismatch between the type of RHEL system I was running and the actual subscription type itself.

    To ensure that one renews to the right subscription type, simply use the following:

    cat /etc/redhat-release
    redhat linux
  • Checking for open ports in go lang

    I had to create a periodic status check for an open port on a specific host for a service I was creating recently. The status check has to work for both the localhost in development and also on the remote host.

    Using the [net][net pkg] package in Go I was able to come up with the following snippet for testing the localhost port:

    package main
    
    import (
      "fmt"
      "net"
    )
    
    func main() {
      l, err := net.Listen("tcp", ":" + port)
      defer l.Close()
    
      if err != nil {
        // Log or report the error here
        fmt.Printf("Error: %s\n", err)
      }
    }

    We use [Listen][net pkg Listen] above as it works for localhost only.

    For testing the remote port, we can use [DialTimeout][net pkg DialTimeout] as it accepts a custom timeout parameter, which we can use to check for timeout errors:

    package main
    
    import (
      "fmt"
      "net"
      "time"
    )
    
    func main() {
      // host -> the remote host
      // timeoutSecs -> the timeout value
      conn, err := net.DialTimeout("tcp", host, time.Duration(timeoutSecs)*time.Second)
      defer conn.Close()
    
      if err, ok := err.(*net.OpError); ok && err.TimeOut() {
        fmt.Printf("Timeout error: %s\n", err)
        return
      }
    
      if err != nil {
        // Log or report the error here
        fmt.Printf("Error: %s\n", err)
        return
      }
    }

    Resources

    net pkg

    net pkg Listen

    net pkg DialTimeout

    golang network

subscribe via RSS