class CfDeployer::ConfigValidation

Constants

CommonInputs
ComponentOptions
EnvironmentOptions

Public Instance Methods

validate(config, validate_inputs = true) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 11
def validate config, validate_inputs = true
  @config = config
  @errors = []
  @warnings = []
  check_application_name
  check_components validate_inputs
  check_environments
  @warnings.each { |message| puts "WARNNING:#{message}" }
  raise ValidationError.new(@errors.join("\n")) if @errors.length > 0
end

Private Instance Methods

check_application_name() click to toggle source
# File lib/cf_deployer/config_validation.rb, line 37
def check_application_name
  @config[:application] = "" unless @config[:application]
  return @errors << "Application name is missing in config" unless @config[:application].length > 0
  @errors << "Application name cannot be longer than 100 and can only contain letters, numbers, '-' and '.'" unless @config[:application] =~ /^[a-zA-Z0-9\.-]{1,100}$/
end
check_asg_name_output(component) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 24
def check_asg_name_output(component)
  component[:settings][:'auto-scaling-group-name-output'] ||= []
  outputs = component[:settings][:'auto-scaling-group-name-output'].map { |name| name.to_sym }
  missing_output_keys = (outputs - component[:defined_outputs].keys)
   @errors << "'#{missing_output_keys.map(&:to_s)}' is not a CF stack output" unless missing_output_keys.empty?
end
check_cname_swap_options(component) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 31
def check_cname_swap_options(component)
  @errors << "dns-fqdn is required when using cname-swap deployment-strategy" unless component[:settings][:'dns-fqdn']
  @errors << "dns-zone is required when using cname-swap deployment-strategy" unless component[:settings][:'dns-zone']
  @errors << "'#{component[:settings][:'elb-name-output']}' is not a CF stack output, which is required by cname-swap deployment" unless component[:defined_outputs].keys.include?(component[:settings][:'elb-name-output'].to_sym)
end
check_component_options(name, component) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 63
def check_component_options(name, component)
  component.keys.each do |option|
    @errors << "The option '#{option}' of the component '#{name}' is not valid" unless ComponentOptions.include?(option)
  end
end
check_components(validate_inputs) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 43
def check_components validate_inputs
  @config[:components] ||= {}
  return @errors << "At least one component must be defined in config" unless @config[:components].length > 0
  deployable_components = @config[:targets] || []
  component_targets = @config[:components].select { |key, value| deployable_components.include?(key.to_s) }
  invalid_names = deployable_components - component_targets.keys.map(&:to_s)
  @errors <<  "Found invalid deployment components #{invalid_names}" if invalid_names.size > 0
  component_targets.each do |component_name, component|
    component[:settings] ||= {}
    component[:inputs] ||= {}
    component[:defined_outputs] ||= {}
    @errors << "Component name cannot be longer than 100 and can only contain letters, numbers, '-' and '.': #{component_name}" unless component_name =~ /^[A-Za-z0-9\.-]{1,100}$/
    check_parameters component_name, component if validate_inputs
    check_cname_swap_options(component) if component[:'deployment-strategy'] == 'cname-swap'
    check_asg_name_output(component)
    check_hooks(component)
    check_component_options(component_name, component)
  end
end
check_environment_options(name, environment) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 93
def check_environment_options(name, environment)
  environment.keys.each do |option|
    @errors << "The option '#{option}' of the environment '#{name}' is not valid" unless EnvironmentOptions.include?(option)
    end
end
check_environments() click to toggle source
# File lib/cf_deployer/config_validation.rb, line 85
def check_environments
  @config[:environments] ||= {}
  @config[:environments].each do | name, environment |
    @errors << "Environment name cannot be longer than 12 and can only contain letters, numbers, '-' and '.': #{name}" unless name =~ /^[a-zA-Z0-9\.-]{1,12}$/
    check_environment_options(name, environment)
  end
end
check_hook_file(component, hook_name) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 78
def check_hook_file(component, hook_name)
  file_name = component[hook_name][:file]
  return unless file_name
  path = File.join(component[:config_dir], file_name)
  @errors << "File '#{path}' does not exist, which is required by hook '#{hook_name}'" unless File.exists?(path)
end
check_hooks(component) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 69
def check_hooks(component)
  hook_names = [:'before-destroy', :'after-create', :'after-swap']
  hook_names.each do |hook_name|
    next unless component[hook_name] && component[hook_name].is_a?(Hash)
    @errors << "Invalid hook '#{hook_name}'" unless component[hook_name][:file] || component[hook_name][:code]
    check_hook_file(component, hook_name)
  end
end
check_output_reference(setting_name, component_name) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 127
def check_output_reference(setting_name, component_name)
  setting = @config[:components][component_name][:inputs][setting_name]
  return unless setting.is_a?(Hash)
  ref_component_name = setting[:component].to_sym
  ref_component = @config[:components][ref_component_name]
  if ref_component
    output_key = setting[:'output-key'].to_sym
    @errors << "No output '#{output_key}' found in CF template of component #{ref_component_name}, which is referenced by input setting '#{setting_name}' in component #{component_name}" unless ref_component[:defined_outputs].keys.include?(output_key)
  else
    @errors << "No component '#{ref_component_name}' found in CF template, which is referenced by input setting '#{setting_name}' in component #{component_name}"
  end
end
check_parameters(component_name, component) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 100
def check_parameters(component_name, component)
  component[:defined_parameters] ||= {}
  component[:defined_outputs] ||= {}
  component[:defined_parameters].each do | parameter_name, parameter |
    if component[:inputs].keys.include?(parameter_name) || parameter[:Default]
      check_output_reference(parameter_name, component_name)
    else
      @errors << "No input setting '#{parameter_name}' found for CF template parameter in component #{component_name}"
    end
  end
  check_un_used_inputs(component_name, component)
end
check_un_used_inputs(component_name, component) click to toggle source
# File lib/cf_deployer/config_validation.rb, line 113
def check_un_used_inputs(component_name, component)
  component[:inputs].keys.each do |input|
    unless component[:defined_parameters].keys.include?(input) || CommonInputs.include?(input)
      message = "The input '#{input}' defined in the component '#{component_name}' is not used in the json template as a parameter"
      if component[:settings][:'raise-error-for-unused-inputs']
        @errors << message
      else
        @warnings << message
      end
    end
  end
end