nginx.rb 6.25 KB
#
# Author:: Earth U (<sysadmin@chromedia.com>)
# Cookbook Name:: cfe-nginx-php-fpm
# Recipe:: nginx
#
# Copyright 2016, Chromedia Far East, Inc.
#
# 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.
#

# Set derived attribute defaults inside recipe

node.default['cfe-nginx-php-fpm']['nginx']['inc_dir'] =
  "#{node['nginx']['dir']}/sites-available/include" unless
  node['cfe-nginx-php-fpm']['nginx']['inc_dir']
node.default['cfe-nginx-php-fpm']['nginx']['priv_dir'] =
  "#{node['nginx']['dir']}/private" unless
  node['cfe-nginx-php-fpm']['nginx']['priv_dir']

# Begin server configuration

include_recipe 'nginx'

attribs  = node['cfe-nginx-php-fpm']['nginx']
inc_dir  = attribs['inc_dir']
priv_dir = attribs['priv_dir']

[ inc_dir, priv_dir ].each do |ndir|
  directory ndir do
    recursive true
  end
end

# The restrictions.conf file containing default rules for virtual servers.
path_rest = "#{inc_dir}/restrictions.conf"
template path_rest do
  action :create_if_missing
  mode   0644
  variables(
    :log_robots   => attribs['restriction_file']['log_robots'],
    :log_hidden   => attribs['restriction_file']['log_hidden'],
    :log_static   => attribs['restriction_file']['log_static'],
    :static_types => attribs['restriction_file']['static_types']
  )
end

# Some basic "include" files for PHP
path_bpf = "#{inc_dir}/inc_basic_php_fastcgi"
template path_bpf do
  action :create_if_missing
  mode 0644
  variables(
    :socket => node['cfe-nginx-php-fpm']['php_fastcgi_socket']
  )
  only_if { node['cfe-nginx-php-fpm']['php_fastcgi_socket'] }
end

catch_all_def_false = attribs['sites'].length > 1

attribs['sites'].each do |site|

  if site.is_a?(Array)
    site_sname = site[0]
    site = site[1]
  else
    site_sname = site[:server_name]
  end

  site_index    = site[:index] || 'index.php'
  site_aliases  = site[:aliases] || []
  site_doc_root = site[:doc_root] || ''
  site_index    = site[:index] || 'index.html'
  site_ssl      = site[:ssl] || false
  site_auth     = site[:auth] || false
  site_alo      = site[:access_log_options] || false
  site_cs       = site[:custom_statements] || []

  site_types = ( site[:types] || [] ).uniq { |e| e[:type] }

  temp_catch_all = site.has_key?(:catch_all) ? site[:catch_all] : true
  site_catch_all = catch_all_def_false ? false : temp_catch_all

  path_crt     = "#{priv_dir}/#{site_sname}.crt"
  path_key     = "#{priv_dir}/#{site_sname}.key"
  path_pass    = "#{priv_dir}/#{site_sname}.htpasswd"
  path_dhparam = "#{priv_dir}/#{site_sname}.dhparam"

  # If TLS/SSL is enabled, create necessary files
  if site_ssl
    if site_ssl[:cert].nil?
      Chef::Log.error('Missing SSL certificate')
      raise 'Missing SSL certificate'
    end

    if site_ssl[:key].nil?
      Chef::Log.error('Missing SSL key file')
      raise 'Missing SSL key file'
    end

    file path_crt do
      mode      0644
      content   site_ssl[:cert]
      sensitive true
      action    :create_if_missing
    end

    file path_key do
      mode      0644
      content   site_ssl[:key]
      sensitive true
      action    :create_if_missing
    end

    dh_modulus = site_ssl[:dh_modulus] || 2048
    execute "openssl dhparam -out #{path_dhparam} #{dh_modulus}" do
      not_if { ::File.exist?(path_dhparam) }
    end
  end

  # If basic auth is enabled, create htaccess file
  if site_auth
    site_auth[:users].each do |auser, apass|
      execute "Generate #{path_pass}" do
        command   "printf \"#{auser}:"\
                  "$( openssl passwd -apr1 '#{apass}' )"\
                  "\\n\" >> #{path_pass}"
        action    :run
        sensitive true
        not_if    { ::File.exist?(path_pass) }
      end
    end
  end

  site_includes = []

  # Create necessary include files for each type of this site
  site_types.each do |stype|
    stype_subpath = stype[:subpath] || ''

    case stype[:type]
    # BASIC PHP SITE
    when 'basic'
      template "#{inc_dir}/inc_type_basic_#{site_sname}" do
        source 'inc_type_basic.erb'
        mode   0644
        action :create_if_missing
        variables(
          :index             => site_index,
          :subpath           => stype_subpath,
          :basic_php_fastcgi => path_bpf
        )
      end
      site_includes.push("#{inc_dir}/inc_type_basic_#{site_sname}")

    # STANDARD WORDPRESS SITE
    when 'wordpress'
      template "#{inc_dir}/inc_type_wordpress_#{site_sname}" do
        source 'inc_type_wordpress.erb'
        mode   0644
        action :create_if_missing
        variables(
          :index                    => site_index,
          :subpath                  => stype_subpath,
          :basic_php_fastcgi        => path_bpf,
          :loginpage_statements     => stype[:loginpage_statements] || [],
          :fastcgi_intercept_errors => stype[:fastcgi_intercept_errors] || false
        )
      end
      site_includes.push("#{inc_dir}/inc_type_wordpress_#{site_sname}")

    else
      Chef::Log.error("Unknown site type: #{stype[:type]}")
      raise 'Missing SSL key file'
    end
  end

  # Create the main config file for this site
  template "#{node['nginx']['dir']}/sites-available/#{site_sname}" do
    source   'nginx_site.conf.erb'
    action   :create_if_missing
    mode     0644
    notifies :restart, 'service[nginx]'
    variables(
      :server_name => site_sname,
      :aliases     => site_aliases,
      :doc_root    => site_doc_root,
      :index       => site_index,
      :ssl         => site_ssl,
      :auth        => site_auth,

      :access_log_options => site_alo,
      :catch_all          => site_catch_all,

      :path_crt     => path_crt,
      :path_key     => path_key,
      :path_pass    => path_pass,
      :path_dhparam => path_dhparam,
      :path_rest    => path_rest,

      :includes          => site_includes,
      :custom_statements => site_cs
    )
  end

  nginx_site site_sname do
    enable true
  end
end