Menu

Knox Install

module.exports = header: 'Knox Install', handler: ({options}) ->

Register

  @registry.register 'hconfigure', 'ryba/lib/hconfigure'
  @registry.register 'hdp_select', 'ryba/lib/hdp_select'
  @registry.register ['file', 'jaas'], 'ryba/lib/file_jaas'

Identities

  @system.group header: 'Group', options.group
  @system.user header: 'User', options.user

IPTables

ServicePortProtoParameter
Gateway8443httpgateway.port

IPTables rules are only inserted if the parameter "iptables.action" is set to "start" (default value).

  @tools.iptables
    header: 'IPTables'
    if: options.iptables
    rules: [
      { chain: 'INPUT', jump: 'ACCEPT', dport: options.gateway_site['gateway.port'], protocol: 'tcp', state: 'NEW', comment: "Knox Gateway" }
    ]

Packages

  @call header: 'Packages', ->
    @service name: 'knox'
    @hdp_select name: 'knox-server'
    # Fix autogen of master secret
    @call
      if: ->@status -2
    , ->
      @each  [
        '/usr/hdp/current/knox-server/data/security/master'
        '/usr/hdp/current/knox-server/data/security/keystores'
        '/usr/hdp/current/knox-server/conf/topologies/admin.xml'
        '/usr/hdp/current/knox-server/conf/topologies/sandbox.xml'
      ] , ({options}) ->
          @system.remove  target: options.key
    # Fix for the bug with rpm/deb packages. During installation of the package, they re-apply permissions to the folder
    @system.mkdir
      target: "#{options.log_dir}"
      uid: options.user.name
      gid: options.group.name
      mode: 0o0755
    @service.init
      if_os: name: ['redhat','centos'], version: '6'
      header: 'Initd Script'
      target: '/etc/init.d/knox-server'
      source: "#{__dirname}/../resources/knox-server.j2"
      local: true
      context: options: options
      mode: 0o755
    @call
      if_os: name: ['redhat','centos'], version: '7'
    , ->
      @service.init
        header: 'Systemd Script'
        target: '/usr/lib/systemd/system/knox-server.service'
        source: "#{__dirname}/../resources/knox-server-systemd.j2"
        local: true
        context: options: options
        mode: 0o0644
      @system.tmpfs
        if_os: name: ['redhat','centos'], version: '7'
        mount: "#{options.pid_dir}"
        uid: options.user.name
        gid: options.group.name
        perm: '0755'

Configure

  @hconfigure
    header: 'Configure'
    target: "#{options.conf_dir}/gateway-site.xml"
    properties: options.gateway_site
    merge: true

  @file.render
    header: 'Knox Ldap Caching'
    target: "#{options.conf_dir}/ehcache.xml"
    source: "#{__dirname}/../resources/ehcache.j2"
    local: true
    context: options: options

Env

We do not edit knox-env.sh because environnement variables are directly set in the gateway.sh service script.

  @call header: 'Env', ->
    options.env.app_log_opts += " -D#{k}=#{v}" for k,v of options.log4jopts
    @file
      header: 'Env'
      target: "#{options.bin_dir}/gateway.sh"
      mode: 0o0755
      write: for k, v of options.env
        match: RegExp "^#{k.toUpperCase()}=.*$", 'img'
        replace: "#{k.toUpperCase()}=\"#{v}\""
        append: false

Kerberos

  @call header: 'Kerberos', ->
    @krb5.addprinc options.krb5.admin,
      principal: options.krb5_user.principal
      randkey: true
      keytab: options.krb5_user.keytab
      uid: options.user.name
      gid: options.group.name
    @file.jaas
      target: options.gateway_site['java.security.auth.login.config']
      content: 'com.sun.security.jgss.initiate':
        principal: options.krb5_user.principal
        keyTab: options.krb5_user.keytab
        renewTGT: true
        doNotPrompt: true
        isInitiator: true
        useTicketCache: true
        client: true
      no_entry_check: true
      uid: options.user.name
      gid: options.group.name
      mode: 0o600

Topologies

  @call header: 'Topologies', ->
    for nameservice, topology of options.topologies
      doc = builder.create 'topology', version: '1.0', encoding: 'UTF-8'
      gateway = doc.ele 'gateway' if topology.providers?
      for role, p of topology.providers
        provider = gateway.ele 'provider'
        provider.ele 'role', role
        provider.ele 'name', p.name
        provider.ele 'enabled', if p.enabled? then "#{p.enabled}" else 'true'
        if typeof p.config is 'object'
          for name in Object.keys(p.config).sort()
            if p.config[name]
              param = provider.ele 'param'
              param.ele 'name', name
              param.ele 'value', p.config[name]
      for role, url_params of topology.services
        unless url_params is false
          service = doc.ele 'service'
          service.ele 'role', role.toUpperCase()
          if Array.isArray url_params then for u in url_params
            service.ele 'url', u
          else if typeof url_params is 'object'
            service.ele 'url',url_params.url
            if url_params.params? then for param,value of url_params.params
              service.ele 'param', param
              service.ele 'value', value
          else if url_params not in [null, ''] then service.ele 'url', url_params
      @file
        target: "#{options.conf_dir}/topologies/#{nameservice}.xml"
        content: doc.end pretty: true
        backup: true
        eof: true
      @file.render
        header: "ehcache #{nameservice}"
        target: "#{options.conf_dir}/#{nameservice}-ehcache.xml"
        source: "#{__dirname}/../resources/ehcache.j2"
        local: true
        context: options:
          nameservice:nameservice

Master Key

  @call
    header: 'Create Keystore'
    unless_exists: '/usr/hdp/current/knox-server/data/security/master'
  , (_, callback) ->
    ssh = @ssh options.ssh
    ssh.shell (err, stream) =>
      stream.write "su -l #{options.user.name} -c '/usr/hdp/current/knox-server/bin/knoxcli.sh create-master'\n"
      stream.on 'data', (data, extended) ->
        if /Enter master secret/.test data then stream.write "#{options.ssl.keystore.password}\n"
        if /Master secret is already present on disk/.test data then callback null, false
        else if /Master secret has been persisted to disk/.test data then callback null, true
      stream.on 'exit', -> callback Error 'Exit before end'

  @call header: 'Store Password', ->
    # Create alias to store password used in topology
    for alias,password of options.realm_passwords then do (alias,password) =>
      nameservice=alias.split("-")[0]
      @system.execute
        cmd: "/usr/hdp/current/knox-server/bin/knoxcli.sh create-alias #{alias} --cluster #{nameservice} --value #{password}"

SSL

  @call header: 'SSL Server', ->
    
    # tmp_location = "/var/tmp/ryba/knox_ssl"
    # @file.download
    #   source: options.ssl.cacert
    #   target: "#{tmp_location}/cacert"
    #   mode: 0o0600
    #   shy: true
    # @file.download
    #   source: options.ssl.cert
    #   target: "#{tmp_location}/cert"
    #   mode: 0o0600
    #   shy: true
    # @file.download
    #   source: options.ssl.key
    #   target: "#{tmp_location}/key"
    #   mode: 0o0600
    #   shy: true
    # @java.keystore_add
    #   keystore: '/usr/hdp/current/knox-server/data/security/keystores/gateway.jks'
    #   storepass: options.ssl.storepass
    #   caname: "hadoop_root_ca"
    #   cacert: "#{tmp_location}/cacert"
    #   key: "#{tmp_location}/key"
    #   cert: "#{tmp_location}/cert"
    #   keypass: options.ssl.keypass
    #   name: 'gateway-identity'
    @java.keystore_add
      keystore: options.ssl.keystore.target
      storepass: options.ssl.keystore.password
      key: options.ssl.key.source
      cert: options.ssl.cert.source
      keypass: options.ssl.keystore.keypass
      name: options.ssl.key.name
      local:  options.ssl.key.local
    @java.keystore_add
      keystore: options.ssl.keystore.target
      storepass: options.ssl.keystore.password
      caname: options.ssl.truststore.caname
      cacert: options.ssl.cacert.source
      local: options.ssl.cacert.local
    @system.execute
      if: -> @status -1
      cmd: "/usr/hdp/current/knox-server/bin/knoxcli.sh create-alias gateway-identity-passphrase --value #{options.ssl.keystore.keypass}"

Knox use Shiro for LDAP authentication and Shiro cannot be configured for unsecure SSL. With LDAPS, the certificate must be imported into the JRE's keystore for the client to connect to openldap.

    @java.keystore_add
      keystore: "#{options.jre_home or options.java_home}/lib/security/cacerts"
      storepass: 'changeit'
      caname: options.ssl.truststore.caname
      cacert: options.ssl.cacert.source
      local: options.ssl.cacert.local
    # @system.remove
    #   target: "#{tmp_location}/cacert"
    #   shy: true
    # @system.remove
    #   target: "#{tmp_location}/cert"
    #   shy: true
    # @system.remove
    #   target: "#{tmp_location}/key"
    #   shy: true

Log4j

  @file
    header: 'Log4J Properties'
    target: "#{options.conf_dir}/gateway-log4j.properties"
    source: "#{__dirname}/../resources/gateway-log4j.properties"
    local: true
    write: for k, v of options.log4j
      match: RegExp "#{k}=.*", 'm'
      replace: "#{k}=#{v}"
      append: true

Dependencies

builder = require 'xmlbuilder'