#
# Copyright 2017, whitestar
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

name 'devops-suite-with-ssl-on-docker'
description 'DevOps Suite with SSL on Docker'

host_cn = nil
ca_name = nil
#ca_name = 'grid_ca'
import_ca = false
# chef-solo or chef-client local mode
if $0.split.include?('chef-solo') || ($0.split.include?('chef-client') && ARGV.include?('-z'))
  require 'ohai'
  node = Ohai::System.new
  node.all_plugins

  host_cn = node['fqdn'] if host_cn.nil?
end
host_cn = 'devops.io.example.com' if host_cn.nil?
aptly_cn = host_cn        # e.g. 'aptly.io.example.com'
athenz_cn = host_cn       # e.g. 'athenz.io.example.com'
concourse_cn = host_cn    # e.g. 'concourse.io.example.com'
concourse_port      = '8443'
docker_reg_cn = host_cn   # e.g. 'registry.docker.example.com'
docker_reg_port     = '5000'
docker_reg_data_vol = '/opt/docker-compose/app/registry/data'
gitlab_cn = host_cn       # e.g. 'gitlab.io.example.com'
gitlab_https_port   =  '443'
gitlab_reg_port     = '5050'
jenkins_cn = host_cn      # e.g. 'jenkins.io.example.com'
jenkins_port        = '9083'
nexus_cn = host_cn        # e.g. 'nexus.io.example.com'
screwdriver_cn = host_cn  # e.g. 'screwdriver.io.example.com'
screwdriver_ui_port = '9000'  # default: 9000
vault_cn = host_cn        # e.g. 'vault.io.example.com'
dockerd_extra_opts = [
  '-H fd://',
  '--bip=192.168.100.1/24 --fixed-cidr=192.168.100.0/24',
  #"--registry-mirror=https://#{docker_reg_cn}:#{docker_reg_port}",
].join(' ')

# for debug
with_ssl = true

common_names = [
  host_cn,
  aptly_cn,
  athenz_cn,
  concourse_cn,
  docker_reg_cn,
  gitlab_cn,
  jenkins_cn,
  nexus_cn,
  screwdriver_cn,
  vault_cn,
].compact.uniq

# for GitLab
ldap_servers = <<-'EOS'
main: # 'main' is the GitLab 'provider ID' of this LDAP server
  label: 'LDAP'
  host: 'ldap.grid.example.com'
  port: 389
  uid: 'uid'  # 'sAMAccountName'
  method: 'tls' # "tls" or "ssl" or "plain"
  #bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
  #password: '_the_password_of_the_bind_user'
  active_directory: false
  allow_username_or_email_login: false
  block_auto_created_users: false
  base: 'ou=Users,dc=grid,dc=example,dc=com'
  #user_filter: ''
  attributes:
    username: ['uid', 'userid', 'sAMAccountName']
    email:    ['mail', 'email', 'userPrincipalName']
    name:       'cn'
    first_name: 'givenName'
    last_name:  'sn'
  ## EE only
  #group_base: ''
  #admin_group: ''
  #sync_ssh_keys: false
#
#secondary: # 'secondary' is the GitLab 'provider ID' of second LDAP server
#  label: 'LDAP'
#  host: '_your_ldap_server'
#  port: 389
#  uid: 'sAMAccountName'
#  method: 'plain' # "tls" or "ssl" or "plain"
#  bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
#  password: '_the_password_of_the_bind_user'
#  active_directory: true
#  allow_username_or_email_login: false
#  block_auto_created_users: false
#  base: ''
#  user_filter: ''
#  attributes:
#    username: ['uid', 'userid', 'sAMAccountName']
#    email:    ['mail', 'email', 'userPrincipalName']
#    name:       'cn'
#    first_name: 'givenName'
#    last_name:  'sn'
#  ## EE only
#  group_base: ''
#  admin_group: ''
#  sync_ssh_keys: false
EOS

run_list(
  'role[devops-suite-on-docker]',
  'recipe[docker-grid::registry]',
)

#env_run_lists()

#default_attributes()

override_attributes(
  'ssl_cert' => {
    'ca_names' => [
      ca_name,
    ],
    'common_names' => common_names,
  },
  'docker-grid' => {
    'engine' => {
      'skip_setup' => false,
      'daemon_extra_options' => dockerd_extra_opts,
    },
    'compose' => {
      'skip_setup' => false,
    },
    'registry' => {
      'with_ssl_cert_cookbook' => with_ssl,
      'ssl_cert' => {
        'common_name' => docker_reg_cn,
      },
      'docker-compose' => {
        'host_data_volume' => docker_reg_data_vol,
        'config' => {
          'registry' => {
            'ports' => [
              "#{docker_reg_port}:5000",
            ],
            'environment' => {
              #'REGISTRY_AUTH' =>                'htpasswd',
              #'REGISTRY_AUTH_HTPASSWD_PATH' =>  '/auth/.htpasswd',
              #'REGISTRY_AUTH_HTPASSWD_REALM' => 'Registry Realm',
              # proxy cache only.
              'REGISTRY_PROXY_REMOTEURL' => 'https://registry-1.docker.io',
            },
            #'volumes' => [
            #],
          },
        },
      },
    },
  },
  'apt_utils' => {
    'aptly' => {
      'with_ssl_cert_cookbook' => with_ssl,
      'ssl_cert' => {
        'common_name' => aptly_cn,
      },
      'docker-compose' => {
        'config' => {
          'services' => {
            'reverseproxy' => {
              #'ports' => [
              #],
            },
            'aptly' => {
            },
          },
        },
      },
    },
  },
  'concourse-ci' => {
    'with_ssl_cert_cookbook' => with_ssl,
    'ssl_cert' => {
      'ca_names' => [
        ca_name,
      ],
      'common_name' => concourse_cn,
    },
    'docker-compose' => {
      'import_ca' => import_ca,
      # 'web_encryption_key_vault_item' => {
      #   'vault' => 'concourse',
      #   'name' => 'web_encryption_key',
      #   'env_context' => false,
      #   'key' => 'ekey',  # real hash path: "/ekey"
      # },
      # 'web_oauth_client_id_vault_item' => {
      #   'vault' => 'concourse',
      #   'name' => 'web_oauth_client_id',
      #   'env_context' => false,
      #   'key' => 'cid',  # real hash path: "/cid"
      # },
      # 'web_oauth_client_secret_vault_item' => {
      #   'vault' => 'concourse',
      #   'name' => 'web_oauth_client_secret',
      #   'env_context' => false,
      #   'key' => 'secret',  # real hash path: "/secret"
      # },
      'config' => {
        # Version 1 docker-compose format
        'concourse-db' => {
        },
        'concourse-web' => {
          'ports' => [
            "#{concourse_port}:8443",
          ],
          'environment' => {
            'CONCOURSE_TLS_BIND_PORT' => '8443',
            'CONCOURSE_EXTERNAL_URL' => "https://#{concourse_cn}:#{concourse_port}",
            # OAuth for the default `main`` team
            #'CONCOURSE_GENERIC_OAUTH_DISPLAY_NAME' => 'GitLab',
            #'CONCOURSE_GENERIC_OAUTH_AUTH_URL' => "https://#{gitlab_cn}/oauth/authorize",
            #'CONCOURSE_GENERIC_OAUTH_TOKEN_URL' => "https://#{gitlab_cn}/oauth/token",
          },
        },
        'concourse-worker' => {
          'environment' => {
          },
        },
      },
    },
  },
  'gitlab-grid' => {
    'with_ssl_cert_cookbook' => with_ssl,
    'ssl_cert' => {
      'ca_name' => ca_name,
      'common_name' => gitlab_cn,
      'registry' => {
        'reuse_gitlab_common_name' => true,
        # or
        #'reuse_gitlab_common_name' => false,
        #'common_name' => registry_gitlab_cn,
      },
    },
    'gitlab.rb' => {
      'external_url' => "https://#{gitlab_cn}:#{gitlab_https_port}",
      'registry_external_url' => "https://#{gitlab_cn}:#{gitlab_reg_port}",  # not 5000 if same domain (common name)
      'gitlab_rails' => {
        #'ldap_enabled' => true,
        #'ldap_servers' => YAML.load(ldap_servers),
      },
      'nginx' => {
        'redirect_http_to_https' => true,
      },
      'registry_nginx' => {
        'redirect_http_to_https' => true,
      },
    },
    'docker-compose' => {
      'config' => {
        'services' => {
          'gitlab' => {
            'hostname' => gitlab_cn,
            'ports' => [
              "#{gitlab_https_port}:#{gitlab_https_port}",
              "#{gitlab_reg_port}:#{gitlab_reg_port}",
            ],
          },
        },
      },
    },
    'runner-docker-compose' => {
      'import_ca' => import_ca,
    },
  },
  'jenkins-grid' => {
    'with_ssl_cert_cookbook' => with_ssl,
    'ssl_cert' => {
      'common_name' => jenkins_cn,
    },
    'docker-compose' => {
      'config' => {
        'services' => {
          'jenkins' => {
            'ports' => [
              "#{jenkins_port}:8083",
            ],
            'environment' => {
              'JENKINS_OPTS' => [
                '--httpPort=-1 --httpsPort=8083',
                # These options will be set by the jenkins-grid::docker-compose recipe automatically.
                #'--httpsCertificate=/var/lib/jenkins/server.crt',
                #'--httpsPrivateKey=/var/lib/jenkins/server.key',
              ].join(' '),
            },
          },
        },
      },
    },
  },
  'nexus-grid' => {
    'with_ssl_cert_cookbook' => with_ssl,
    'ssl_cert' => {
      'common_name' => nexus_cn,
    },
    'docker-compose' => {
      'config' => {
        'services' => {
          'reverseproxy' => {
            #'ports' => [
            #],
          },
          'nexus' => {
          },
        },
      },
    },
  },
  'screwdriver' => {
    'with_ssl_cert_cookbook' => with_ssl,
    'ssl_cert' => {
      'common_name' => screwdriver_cn,
    },
    'docker-compose' => {
      'config' => {
        'services' => {
          'reverseproxy' => {
            'ports' => [
              "#{screwdriver_ui_port}:9000"
            ],
            'environment' => {
            },
          },
          'api' => {
            #'ports' => [
            #],
            'environment' => {
            },
          },
          'ui' => {
            #'ports' => [
            #],
            'environment' => {
            },
          },
          'store' => {
            #'ports' => [
            #],
            'environment' => {
            },
          },
        },
      },
    },
  },
  'hc-vault' => {
    'with_ssl_cert_cookbook' => with_ssl,
    'ssl_cert' => {
      'common_name' => vault_cn,
    },
    'config' => {
    },
    'docker-compose' => {
      'config' => {
        'services' => {
          'vault' => {
            #'ports' => [
            #],
            'environment' => {
              #'VAULT_LOCAL_CONFIG' => '',  # expanded to /vault/config/local.json
            },
          },
        },
      },
    },
  },
)
