Class: Bolt::Project

Inherits:
Object
  • Object
show all
Defined in:
lib/bolt/project.rb

Constant Summary collapse

BOLTDIR_NAME =
'Boltdir'
PROJECT_SETTINGS =
{
  "name"  => "The name of the project",
  "plans" => "An array of plan names to show, if they exist in the project."\
             "These plans are included in `bolt plan show` output",
  "tasks" => "An array of task names to show, if they exist in the project."\
             "These tasks are included in `bolt task show` output"
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(raw_data, path, type = 'option') ⇒ Project

Returns a new instance of Project.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/bolt/project.rb', line 52

def initialize(raw_data, path, type = 'option')
  @path = Pathname.new(path).expand_path
  @project_file = @path + 'bolt-project.yaml'

  @warnings = []
  if (@path + 'bolt.yaml').file? && project_file?
    msg = "Project-level configuration in bolt.yaml is deprecated if using bolt-project.yaml. "\
      "Transport config should be set in inventory.yaml, all other config should be set in "\
      "bolt-project.yaml."
    @warnings << { msg: msg }
  end

  @inventory_file = @path + 'inventory.yaml'
  @modulepath = [(@path + 'modules').to_s, (@path + 'site-modules').to_s, (@path + 'site').to_s]
  @hiera_config = @path + 'hiera.yaml'
  @puppetfile = @path + 'Puppetfile'
  @rerunfile = @path + '.rerun.json'
  @resource_types = @path + '.resource_types'
  @type = type

  tc = Bolt::Config::INVENTORY_OPTIONS.keys & raw_data.keys
  if tc.any?
    msg = "Transport configuration isn't supported in bolt-project.yaml. Ignoring keys #{tc}"
    @warnings << { msg: msg }
  end

  @data = raw_data.reject { |k, _| Bolt::Config::INVENTORY_OPTIONS.include?(k) }

  # Once bolt.yaml deprecation is removed, this attribute should be removed
  # and replaced with .project_file in lib/bolt/config.rb
  @config_file = if (Bolt::Config::BOLT_OPTIONS & @data.keys).any?
                   if (@path + 'bolt.yaml').file?
                     msg = "bolt-project.yaml contains valid config keys, bolt.yaml will be ignored"
                     @warnings << { msg: msg }
                   end
                   @project_file
                 else
                   @path + 'bolt.yaml'
                 end
  validate if project_file?
end

Instance Attribute Details

#config_fileObject (readonly)

Returns the value of attribute config_file.



18
19
20
# File 'lib/bolt/project.rb', line 18

def config_file
  @config_file
end

#dataObject (readonly)

Returns the value of attribute data.



18
19
20
# File 'lib/bolt/project.rb', line 18

def data
  @data
end

#hiera_configObject (readonly)

Returns the value of attribute hiera_config.



18
19
20
# File 'lib/bolt/project.rb', line 18

def hiera_config
  @hiera_config
end

#inventory_fileObject (readonly)

Returns the value of attribute inventory_file.



18
19
20
# File 'lib/bolt/project.rb', line 18

def inventory_file
  @inventory_file
end

#modulepathObject (readonly)

Returns the value of attribute modulepath.



18
19
20
# File 'lib/bolt/project.rb', line 18

def modulepath
  @modulepath
end

#pathObject (readonly)

Returns the value of attribute path.



18
19
20
# File 'lib/bolt/project.rb', line 18

def path
  @path
end

#project_fileObject (readonly)

Returns the value of attribute project_file.



18
19
20
# File 'lib/bolt/project.rb', line 18

def project_file
  @project_file
end

#puppetfileObject (readonly)

Returns the value of attribute puppetfile.



18
19
20
# File 'lib/bolt/project.rb', line 18

def puppetfile
  @puppetfile
end

#rerunfileObject (readonly)

Returns the value of attribute rerunfile.



18
19
20
# File 'lib/bolt/project.rb', line 18

def rerunfile
  @rerunfile
end

#resource_typesObject (readonly)

Returns the value of attribute resource_types.



18
19
20
# File 'lib/bolt/project.rb', line 18

def resource_types
  @resource_types
end

#typeObject (readonly)

Returns the value of attribute type.



18
19
20
# File 'lib/bolt/project.rb', line 18

def type
  @type
end

#warningsObject (readonly)

Returns the value of attribute warnings.



18
19
20
# File 'lib/bolt/project.rb', line 18

def warnings
  @warnings
end

Class Method Details

.create_project(path, type = 'option') ⇒ Object



45
46
47
48
49
50
# File 'lib/bolt/project.rb', line 45

def self.create_project(path, type = 'option')
  fullpath = Pathname.new(path).expand_path
  project_file = File.join(fullpath, 'bolt-project.yaml')
  data = Bolt::Util.read_optional_yaml_hash(File.expand_path(project_file), 'project')
  new(data, path, type)
end

.default_projectObject



21
22
23
24
25
26
# File 'lib/bolt/project.rb', line 21

def self.default_project
  create_project(File.expand_path(File.join('~', '.puppetlabs', 'bolt')), 'user')
# If homedir isn't defined use the system config path
rescue ArgumentError
  create_project(Bolt::Config.system_path, 'system')
end

.find_boltdir(dir) ⇒ Object

Search recursively up the directory hierarchy for the Project. Look for a directory called Boltdir or a file called bolt.yaml (for a control repo type Project). Otherwise, repeat the check on each directory up the hierarchy, falling back to the default if we reach the root.



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/bolt/project.rb', line 32

def self.find_boltdir(dir)
  dir = Pathname.new(dir)
  if (dir + BOLTDIR_NAME).directory?
    create_project(dir + BOLTDIR_NAME, 'embedded')
  elsif (dir + 'bolt.yaml').file? || (dir + 'bolt-project.yaml').file?
    create_project(dir, 'local')
  elsif dir.root?
    default_project
  else
    find_boltdir(dir.parent)
  end
end

Instance Method Details

#check_deprecated_fileObject



148
149
150
151
152
153
# File 'lib/bolt/project.rb', line 148

def check_deprecated_file
  if (@path + 'project.yaml').file?
    logger = Logging.logger[self]
    logger.warn "Project configuration file 'project.yaml' is deprecated; use 'bolt-project.yaml' instead."
  end
end

#eql?(other) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)


104
105
106
# File 'lib/bolt/project.rb', line 104

def eql?(other)
  path == other.path
end

#nameObject



113
114
115
# File 'lib/bolt/project.rb', line 113

def name
  @data['name']
end

#plansObject



121
122
123
# File 'lib/bolt/project.rb', line 121

def plans
  @data['plans']
end

#project_file?Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/bolt/project.rb', line 109

def project_file?
  @project_file.file?
end

#tasksObject



117
118
119
# File 'lib/bolt/project.rb', line 117

def tasks
  @data['tasks']
end

#to_hObject

This API is used to prepend the project as a module to Puppet’s internal module_references list. CHANGE AT YOUR OWN RISK



100
101
102
# File 'lib/bolt/project.rb', line 100

def to_h
  { path: @path, name: name }
end

#to_sObject



94
95
96
# File 'lib/bolt/project.rb', line 94

def to_s
  @path.to_s
end

#validateObject



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/bolt/project.rb', line 125

def validate
  if name
    name_regex = /^[a-z][a-z0-9_]*$/
    if name !~ name_regex
      raise Bolt::ValidationError, <<~ERROR_STRING
      Invalid project name '#{name}' in bolt-project.yaml; project name must match #{name_regex.inspect}
      ERROR_STRING
    elsif Dir.children(Bolt::PAL::BOLTLIB_PATH).include?(name)
      raise Bolt::ValidationError, "The project '#{name}' will not be loaded. The project name conflicts "\
        "with a built-in Bolt module of the same name."
    end
  else
    message = "No project name is specified in bolt-project.yaml. Project-level content will not be available."
    @warnings << { msg: message }
  end

  %w[tasks plans].each do |conf|
    unless @data.fetch(conf, []).is_a?(Array)
      raise Bolt::ValidationError, "'#{conf}' in bolt-project.yaml must be an array"
    end
  end
end