class Tpt::Rails::KubernetesGenerator

Constants

ODE_KUBE_CONTEXT
VALID_APP_NAME

Public Instance Methods

setup_kubernetes() click to toggle source
# File lib/generators/tpt/rails/kubernetes/kubernetes_generator.rb, line 9
  def setup_kubernetes
    if !valid_app_name?
      say("ERROR: App name #{Tpt::Rails.app_name.inspect} will not be valid for DNS usage.")
      abort
    end

    check_dependencies

    secrets_name = "#{Tpt::Rails.app_name}-secrets"
    secrets_key = "secret-key-base"
    secrets_value = SecureRandom.alphanumeric(32).downcase

    team_name = ask("What's your GitHub team name? Something like `core-services`").strip
    app_type = "internal"

    tpt_config = get_tpt_config
    tpt_user_alias = tpt_config.fetch('user.alias')

    template 'Dockerfile'
    template 'entrypoint.sh'
    template '.dockerignore'

    directory(
      'kubernetes',
      team_name: team_name,
      secrets_name: secrets_name,
      secrets_key: secrets_key,
      app_type: app_type,
    )

    inside('kubernetes/helm') do
      run('helm dependency update', abort_on_failure: true)
    end

    add_kube_secret(secrets_name, secrets_key, secrets_value)

    # TODO: move the below instruction to a wiki page
    say(<<~MESSAGE)

      ********************************************************************************
      * Success!  Your project has been configured for Kubernetes!
      ********************************************************************************

      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      ! Follow-up actions required:
      !
      ! 1. Review and commit these changes
      ! 2. Push your changes up to a Github repository
      ! 3. Follow the docker instructions on
      !     https://teacherspayteachers.atlassian.net/wiki/spaces/SER/pages/1521090593/Getting+started+Create+a+new+serverless+service#Build-and-push-your-project-to-DockerHub
      ! 4. Deploy to an ODE with `tpt project push`
      ! 5. Monitor the status of your ODE deploy with:
      !      kubectl get pods --namespace #{tpt_user_alias} | grep #{Tpt::Rails.app_name}
      ! 6. When your ODE is ready you can visit it here:
      !      http://#{Tpt::Rails.app_name}--#{tpt_user_alias}.ode.tptpm.info/#{Tpt::Rails::Engine.instance.routes.url_helpers.health_check_path}
      !
      ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    MESSAGE
  end

Private Instance Methods

add_kube_secret(secrets_name, secrets_key, secrets_value) click to toggle source
# File lib/generators/tpt/rails/kubernetes/kubernetes_generator.rb, line 109
def add_kube_secret(secrets_name, secrets_key, secrets_value)
  key_exists = run("kubectl get secret #{secrets_name} --context='#{ODE_KUBE_CONTEXT}' >/dev/null 2>&1", abort_on_failure: false)

  if !key_exists
    say "Kube secret #{secrets_name} not found. Creating it…"
    run(
      "kubectl create secret generic #{secrets_name} --from-literal='#{secrets_key}=#{secrets_value}' --context='#{ODE_KUBE_CONTEXT}'",
      abort_on_failure: true,
    )
  end
end
check_dependencies() click to toggle source
# File lib/generators/tpt/rails/kubernetes/kubernetes_generator.rb, line 72
def check_dependencies
  say('Checking dependencies…')
  check_dependency('config/master.key', 'test -f config/master.key')
  check_dependency('jq', 'which jq')
  check_dependency('tpt network', 'nc -G1 -w1 chartmuseum.tptpm.info 443')
  check_dependency('tpt-cli', 'tpt version')
  check_dependency('tpt config', 'tpt config get') # fails if tpt config has not been initialized
  check_dependency('docker', 'docker version') # fails if docker isn't running
  check_dependency('kubectl', 'kubectl version') # fails if kubectl isn't set up
  check_dependency('kubeval', 'which kubeval') # needed for `tpt project push`. See https://kubeval.instrumenta.dev/installation/
  check_dependency('helm', 'helm search justtesting') # fails if helm isn't installed + initialized (~/.helm directory created)
  check_dependency('helm tpt repo', "helm repo list | egrep '^tpt '") # fails if tpt helm repo isn't added
end
check_dependency(name, command) click to toggle source
# File lib/generators/tpt/rails/kubernetes/kubernetes_generator.rb, line 86
def check_dependency(name, command)
  say("Checking for dependency: #{name}")
  run(command, abort_on_failure: true, capture: true) # capture: true makes the output nicer
rescue Exception => e
  say "Error! #{name} does not seem to be available. `#{command}` returned: #{e.inspect}"
  abort
end
get_tpt_config() click to toggle source
# File lib/generators/tpt/rails/kubernetes/kubernetes_generator.rb, line 101
def get_tpt_config
  conf = run('tpt config get', capture: true, abort_on_failure: true)
  YAML.load(conf)
rescue
  say("Failed to get tpt config")
  raise
end
valid_app_name?() click to toggle source

Dasherize the app name for kube usage, and verify that it will be valid for DNS usage. Note: Rails itself also verifies that the name does not start with a number so that it is a valid

Ruby identifier.
# File lib/generators/tpt/rails/kubernetes/kubernetes_generator.rb, line 97
def valid_app_name?
  Tpt::Rails.app_name =~ VALID_APP_NAME
end