fhcap-cli 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +23 -0
  4. data/fhcap-cli.gemspec +1 -0
  5. data/lib/cookbooks/provision/recipes/aws_cluster_create.rb +5 -6
  6. data/lib/cookbooks/provision/recipes/aws_cluster_create_elb.rb +2 -2
  7. data/lib/cookbooks/provision/recipes/openstack_cluster_create.rb +6 -1
  8. data/lib/fhcap/chef-dk/chef_runner.rb +4 -1
  9. data/lib/fhcap/cli.rb +5 -0
  10. data/lib/fhcap/cluster.rb +2 -2
  11. data/lib/fhcap/component.rb +75 -0
  12. data/lib/fhcap/config.rb +5 -0
  13. data/lib/fhcap/misc/fh_config.rb +120 -0
  14. data/lib/fhcap/misc/java_config.rb +36 -0
  15. data/lib/fhcap/misc/json_config.rb +59 -0
  16. data/lib/fhcap/repo.rb +1 -1
  17. data/lib/fhcap/tasks/chef/cookbook/list_artifacts.rb +53 -0
  18. data/lib/fhcap/tasks/chef/cookbook/update_artifact.rb +39 -0
  19. data/lib/fhcap/tasks/chef/cookbook/update_config.rb +78 -0
  20. data/lib/fhcap/tasks/chef/provisioning/chef_provisioning_task_base.rb +3 -1
  21. data/lib/fhcap/tasks/cluster/create.rb +3 -3
  22. data/lib/fhcap/tasks/repo/checkout.rb +25 -1
  23. data/lib/fhcap/tasks/setup.rb +5 -0
  24. data/lib/fhcap/version.rb +1 -1
  25. data/spec/fhcap/tasks/chef/cookbook/list_artifacts_spec.rb +51 -0
  26. data/spec/fhcap/tasks/chef/cookbook/update_artifact_spec.rb +34 -0
  27. data/spec/fhcap/tasks/chef/cookbook/update_config_spec.rb +77 -0
  28. data/templates/cluster/aws/common.json.erb +10 -0
  29. data/templates/cluster/aws/core-3node.json.erb +3 -3
  30. data/templates/cluster/aws/core-small-9node.json.erb +3 -3
  31. data/templates/cluster/aws/mbaas-3node.json.erb +3 -3
  32. data/templates/cluster/aws/nginx-test.json.erb +2 -2
  33. data/templates/cluster/aws/single.json.erb +18 -4
  34. metadata +29 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65e3070c4f135cab4d5b55260bb771dc576defbc
4
- data.tar.gz: 81209d137087b8cdb2053a5b9ec51812666fed32
3
+ metadata.gz: 3334d314b15975b679b1566f0c11b514c3704f3f
4
+ data.tar.gz: 2429d1156af144524e6ff176d71127708978298e
5
5
  SHA512:
6
- metadata.gz: 0590064eade7da691bb7142e5e982009b6fe2e0e425db345f4395e869eba1220e4b719a798ee7f42bcb921be14413e6dcd7cd03045e0ad843827a75adc573ac6
7
- data.tar.gz: c881d8f06f8b4d8819bec8b9a4a3bb62ce819dd49631c2528e2ad746209e858371b38cc05e8c66d83038c2c7400bd221a1f7e7bbb4e131170bb7421c0ff9f43a
6
+ metadata.gz: 3ae8067f89a66214a2df62e822a91685b5d96c7d6e3ac052d62dc2d1c1f732f5db8f5db06053df2af94577d9e495f2cbc35fcde37ef0125f7aa929fccc3b9cde
7
+ data.tar.gz: b5c3573113861387ac44d4f6963c163b1765be989d15d3ff89c1ecde1ef507fea9160162465695e106f9b7802a33daff6740346ea8b51c201b7517401103d726
data/CHANGELOG.md CHANGED
@@ -1,4 +1,12 @@
1
1
 
2
+ ## 0.4.0
3
+
4
+ * [RHMAP-2732] - Ensure directory exists when finding remote during git checkout of repo
5
+ * [RHMAP-1715] - Add component update tasks.
6
+ * [RHMAP-2535] - Save generated cluster key pairs in the key pairs directory of the new clusters fhcap repo i.e. fhcap-dev/organisations/key_pairs.
7
+ * [RHMAP-2282] - Add support-dmz security group with brno cidrs
8
+ * [RHMAP-2647] - Dynamically configure remote during repo checkout based on configured repos url.
9
+
2
10
  ## 0.3.0
3
11
 
4
12
  * Implemented cluster create using chef provisioning, supports aws and openstack
@@ -12,4 +20,4 @@
12
20
 
13
21
  ## 0.1.0
14
22
  * Initial release
15
- * Initial work on setup task
23
+ * Initial work on setup task
data/README.md CHANGED
@@ -18,6 +18,10 @@ Or install it yourself as:
18
18
 
19
19
  $ gem install fhcap-cli
20
20
 
21
+ The gem itself has quite a few dependencies, to help speed up installation you could skip the docs:
22
+
23
+ $ gem install fhcap-cli --no-ri --no-doc
24
+
21
25
  ### Setup
22
26
 
23
27
  ```
@@ -40,6 +44,9 @@ This creates a new fhcap config, clones required repos and sets up knife based o
40
44
  | `-- fhcap.json
41
45
  ```
42
46
 
47
+
48
+ ##### repos-dir
49
+
43
50
  If you want to specify a different repos directory, you can do this by passing it in as an option:
44
51
 
45
52
  ```
@@ -53,6 +60,22 @@ fhcap setup -i
53
60
  Local directory where repos will be checked out (/Users/mnairn/src) /Users/mnairn/some_other_repo_dir
54
61
  ```
55
62
 
63
+ ##### fh-src-dir
64
+
65
+ The default 'fh-src-dir' is set to ~/fhcap/repos, if you already have fh component src checked out or want to use a different directory, you can pass it as an option:
66
+
67
+ ```
68
+ fhcap setup --fh-src-dir /Users/mnairn/src/fheng
69
+ ```
70
+
71
+ or, run setup in interactive mode and change it when prompted:
72
+
73
+ ```
74
+ bundle exec fhcap setup -i
75
+ Local directory where FH component src repos are checked out (/Users/mnairn/src/fheng)
76
+ ```
77
+
78
+
56
79
  #### knife setup (chef server)
57
80
 
58
81
  After the initial setup, you will need to copy your own chef server credentials into the correct knife directories in order to gain proper access to a chef server.
data/fhcap-cli.gemspec CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency 'knife-block', '~> 0.2.1'
27
27
  spec.add_dependency 'knife-cookbook-readme', '~> 0.2.1'
28
28
  spec.add_dependency 'ruby-progressbar', '~> 1.7.5'
29
+ spec.add_dependency 'java_properties', '~> 0.0.4'
29
30
  spec.add_dependency 'aws-sdk', '~> 2.1.23'
30
31
  spec.add_dependency 'chef', '~> 12.4.3'
31
32
  spec.add_dependency 'chef-provisioning', '~> 1.4.0'
@@ -4,14 +4,13 @@ include_recipe "provision::aws"
4
4
  cluster_config = cluster_config_for(node)
5
5
  org_name = cluster_config[:id]
6
6
 
7
+ local_key_pairs_dir = File.join(node[:local_repo_path], node[:local_repo_clusters_dir], 'key_pairs')
7
8
  key_pair_name = key_pair_name_for(org_name)
8
- aws_key_pair key_pair_name
9
9
 
10
- #aws_key_pair 'my-aws-key' do
11
- # private_key_path "~boiardi/.ssh/my-aws-key.pem"
12
- # public_key_path "~boiardi/.ssh/my-aws-key.pub"
13
- # allow_overwrite false # Set to true if you want to regenerate this each chef run
14
- #end
10
+ aws_key_pair key_pair_name do
11
+ private_key_path File.join(local_key_pairs_dir, "#{key_pair_name}.pem")
12
+ public_key_path File.join(local_key_pairs_dir, "#{key_pair_name}.pub")
13
+ end
15
14
 
16
15
  #Create VPC
17
16
  vpc_name = vpc_name_for(org_name)
@@ -20,8 +20,8 @@ cluster_config[:environments].each do |env, env_config|
20
20
  lb_certs = {}
21
21
  lb_config[:listeners].each_with_index do |listener, index|
22
22
  if listener[:server_certificate]
23
- certificate_file = File.join(node[:local_repo_path], 'clusters', 'ssl_certs', "#{listener[:server_certificate]}-certificate.pem")
24
- private_key_file = File.join(node[:local_repo_path], 'clusters', 'ssl_certs', "#{listener[:server_certificate]}-private-key.pem")
23
+ certificate_file = File.join(node[:local_repo_path], node[:local_repo_clusters_dir], 'ssl_certs', "#{listener[:server_certificate]}-certificate.pem")
24
+ private_key_file = File.join(node[:local_repo_path], node[:local_repo_clusters_dir], 'ssl_certs', "#{listener[:server_certificate]}-private-key.pem")
25
25
 
26
26
  if File.exists?(certificate_file) && File.exists?(private_key_file)
27
27
  certificate_body = File.open(certificate_file, "rb").read
@@ -5,7 +5,12 @@ include_recipe "provision::openstack"
5
5
  cluster_config = cluster_config_for(node)
6
6
  org_name = cluster_config[:id]
7
7
 
8
+ local_key_pairs_dir = File.join(node[:local_repo_path], node[:local_repo_clusters_dir], 'key_pairs')
8
9
  key_pair_name = key_pair_name_for(org_name)
9
- fog_key_pair key_pair_name
10
+
11
+ fog_key_pair key_pair_name do
12
+ private_key_path File.join(local_key_pairs_dir, "#{key_pair_name}.pem")
13
+ public_key_path File.join(local_key_pairs_dir, "#{key_pair_name}.pub")
14
+ end
10
15
 
11
16
  include_recipe "provision::cluster_provision_instances"
@@ -16,11 +16,13 @@ module Fhcap
16
16
 
17
17
  attr_reader :cookbook_path
18
18
  attr_reader :run_list
19
+ attr_reader :private_key_paths
19
20
  attr_reader :node_attrs
20
21
 
21
- def initialize(cookbook_path, run_list, node_attrs={})
22
+ def initialize(cookbook_path, run_list, node_attrs={}, private_key_paths=[])
22
23
  @cookbook_path = File.expand_path(cookbook_path)
23
24
  @run_list = run_list
25
+ @private_key_paths = private_key_paths
24
26
  @node_attrs = node_attrs
25
27
  @formatter = nil
26
28
  @ohai = nil
@@ -64,6 +66,7 @@ module Fhcap
64
66
  Chef::Config.log_level = :error
65
67
  Chef::Config.ssl_verify_mode = :verify_none
66
68
  Chef::Config.cookbook_path = cookbook_path
69
+ Chef::Config.private_key_paths = (Chef::Config.private_key_paths + private_key_paths).compact.uniq
67
70
  Chef::Config.color = true
68
71
  Chef::Config.diff_disabled = true
69
72
 
data/lib/fhcap/cli.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'fhcap/thor_base'
2
2
  require 'fhcap/cluster'
3
+ require 'fhcap/component'
3
4
  require 'fhcap/cookbook'
4
5
  require 'fhcap/repo'
5
6
  require 'fhcap/knife'
@@ -17,6 +18,7 @@ module Fhcap
17
18
  add_shared_option :interactive, :aliases => "-i", :desc => "Interactive mode (Stops for input)", :type => :boolean, :required => false, :default => false
18
19
 
19
20
  method_option 'repos-dir', :type => :string, :desc => "Local directory where configured repos will be checked out"
21
+ method_option 'fh-src-dir', :type => :string, :desc => "Local directory where FH component src repos are checked out"
20
22
 
21
23
  desc "setup", "Setup the FHCAP CLI"
22
24
 
@@ -46,6 +48,9 @@ module Fhcap
46
48
  desc "cluster COMMANDS", "Cluster commands"
47
49
  subcommand "cluster", Fhcap::CLI::Cluster
48
50
 
51
+ desc "component COMMANDS", "Component commands"
52
+ subcommand "component", Fhcap::CLI::Component
53
+
49
54
  desc "cookbook COMMANDS", "Cookbook commands"
50
55
  subcommand "cookbook", Fhcap::CLI::Cookbook
51
56
 
data/lib/fhcap/cluster.rb CHANGED
@@ -15,7 +15,7 @@ module Fhcap
15
15
 
16
16
  method_option 'template', :type => :string, :desc => "Cluster template i.e. [1, 3 , 5 node cluster setup, core or mbaas]", :enum => cluster_template_names
17
17
  method_option 'git-ref', :type => :string, :desc => "fhcap git ref, can be a branch, tag or commit hash"
18
- method_option 'git-remote', :type => :string, :desc => "git remote to use, default is origin"
18
+ method_option 'git-remote', :type => :string, :desc => "git remote to use, default is the remote for the configured repos url"
19
19
  method_option 'domain', :type => :string, :desc => "host names to register with DNS / base host name"
20
20
  method_option 'ssl-cert', :type => :string, :desc => "ssl cert to use"
21
21
  method_option 'dns-provider-id', :type => :string, :desc => "DNS Provider Id"
@@ -37,7 +37,7 @@ module Fhcap
37
37
 
38
38
  shared_options :verbose, :name
39
39
  method_option 'git-ref', :type => :string, :desc => "fhcap git ref, can be a branch, tag or commit hash"
40
- method_option 'git-remote', :type => :string, :desc => "git remote to use, default is origin"
40
+ method_option 'git-remote', :type => :string, :desc => "git remote to use, default is the remote for the configured repos url"
41
41
  method_option 'nodes', :type => :string, :desc => "Query to pass to name"
42
42
  method_option 'roles', :type => :string, :desc => "Query to pass to roles"
43
43
  method_option 'series', :type => :boolean, :default => false, :desc => "Run provision in series"
@@ -0,0 +1,75 @@
1
+ require 'thor'
2
+ require 'fhcap/thor_base'
3
+
4
+ module Fhcap
5
+ module CLI
6
+ class Component < Fhcap::ThorBase
7
+
8
+ add_shared_option :verbose, :aliases => "-v", :desc => "Verbose output", :type => :boolean, :required => false, :default => false
9
+ add_shared_option :interactive, :aliases => "-i", :desc => "Interactive mode (Stops for input)", :type => :boolean, :required => false, :default => false
10
+
11
+ desc "update COMPONENT VERSION BUILD", "Update a single component"
12
+
13
+ shared_options :interactive, :verbose
14
+ method_option 'force', :type => :boolean, :aliases => "-f", :desc => "Will force the component version update even if the artifact cant be found"
15
+ method_option 'wip', :type => :boolean, :desc => "Work in progress. Limits the meta that is changed during the update. i.e. no readme etc.."
16
+ method_option 'tag', :type => :string, :desc => "Adds a tag to a components changelog entry"
17
+
18
+ def update(component, version, build)
19
+
20
+ #1. Update artifact version
21
+ Fhcap::CLI::Component.new.invoke(:update_artifact, [component, version, build], {interactive: options[:interactive]})
22
+
23
+ #2. Update config
24
+ Fhcap::CLI::Component.new.invoke(:update_artifact, [component], {force: options[:force]})
25
+
26
+ #3. Update cookbook
27
+ clog_entry = "Updated #{component} component version #{version}-#{build}"
28
+ clog_entry += " (#{options[:tag]})" if options[:tag]
29
+ Fhcap::CLI::Cookbook.new.invoke(:update, [], {cookbooks: [component], :"changelog-entries" => [clog_entry], wip: options['wip']})
30
+
31
+ end
32
+
33
+ desc "update_artifact COMPONENT VERSION BUILD", "Update a single component artifact"
34
+
35
+ shared_options :interactive
36
+
37
+ def update_artifact(component, version, build)
38
+ require "fhcap/tasks/chef/cookbook/update_artifact"
39
+ Tasks::Chef::Cookbook::UpdateConfig.new(task_options(options.dup.merge({cookbook: component, version: version, build: build}))).run
40
+ end
41
+
42
+ desc "update_config COMPONENT", "Generates a chef attributes file from the given config file (json or java properties)"
43
+ long_desc <<-LONGDESC
44
+ Updates a chef attribute file e.g. site-cookbooks/fh-ngui/attributes/conf.json form a config file stored within the
45
+ components own git repository e.g. <FH_SRC_DIR>/fh-ngui/config.dev.json. It can take both json config files
46
+ (all node components) and java properties files (milliore) as input.
47
+
48
+ With -f option, the entire contents of the attribute file will be re-generated from the given config file. You probably don't really want to do this!
49
+
50
+ With -o <attribute1 attribute2> option, the given array of attributes will be updated from the input config file.
51
+ e.g To force an update of only the 'logger' attribute, thor config:generate fh-ngui -o logger. For nested attributes,
52
+ use . notation for attribute names e.g thor config:generate fh-ngui -n -o fhngui.port
53
+
54
+ LONGDESC
55
+ method_option 'overrides', :type => :array, :aliases => "-o", :desc => "Override the given list of values from the config"
56
+ method_option 'force', :type => :boolean, :aliases => "-f", :default => false, :desc => "Force all attribute values to be overwritten from config file (Re-writes the entire attribute file contents)"
57
+ method_option 'sort', :type => :boolean, :aliases => "-s", :default => true, :desc => "Sort attribute file attributes alphabetically"
58
+
59
+ def update_config(component)
60
+ require "fhcap/tasks/chef/cookbook/update_config"
61
+ Tasks::Chef::Cookbook::UpdateConfig.new(task_options(options.dup.merge({cookbook: component}))).run
62
+ end
63
+
64
+ desc "list", "List components and show artifact versions"
65
+
66
+ method_option 'format', :type => :string, :default => 'table', :desc => "Format to output data in", :enum => %w{table json}
67
+
68
+ def list
69
+ require "fhcap/tasks/chef/cookbook/list_artifacts"
70
+ Tasks::Chef::Cookbook::ListArtifacts.new(task_options(options.dup)).run
71
+ end
72
+
73
+ end
74
+ end
75
+ end
data/lib/fhcap/config.rb CHANGED
@@ -59,6 +59,10 @@ module Fhcap
59
59
  File.join(default_dir, 'tmp')
60
60
  end
61
61
 
62
+ def fh_src_dir
63
+ data[:fh_src_dir] || File.join(default_dir, 'repos')
64
+ end
65
+
62
66
  def fhcap_cookbook_archive_url
63
67
  'https://s3-eu-west-1.amazonaws.com/fhcap/fhcap-cookbooks-0fa68747b476f7ee555a94483877969a30133e76.tgz'
64
68
  end
@@ -67,6 +71,7 @@ module Fhcap
67
71
  def fhcap_config
68
72
  @fhcap_config ||= {
69
73
  :repos_dir => File.join(default_dir, 'repos'),
74
+ :fh_src_dir => File.join(default_dir, 'repos'),
70
75
  :repos => {
71
76
  :fhcap => {
72
77
  :url => 'git@github.com:fheng/fhcap.git',
@@ -0,0 +1,120 @@
1
+ require 'fhcap/dummy_node'
2
+
3
+ module Fhcap
4
+ class FHConfig
5
+
6
+ attr_accessor :file, :config, :node
7
+
8
+ def initialize
9
+ #ToDO Should really get rid of this extra config object and just use @node to store everything
10
+ @config = {}
11
+ @node = Fhcap::DummyNode.new
12
+ end
13
+
14
+ def add(key, value, force=false, overrides=[])
15
+ if force || !@config.has_key?(key) || (overrides.include? key.join('.'))
16
+ @config[key] = parse_value(value)
17
+ end
18
+ end
19
+
20
+ #Traverse the key and check it isn't overridden at any point further up the chain
21
+ def has_upper_recipe_override(key)
22
+ key.pop
23
+ return true if @config.has_key?(key) && @config[key] =~ /RECIPE_OVERRIDE/
24
+ has_upper_recipe_override(key) unless key.empty?
25
+ false
26
+ end
27
+
28
+ def to_chef_attributes(sort=false)
29
+ attrs = {}
30
+ if sort
31
+ conf = {}
32
+ @config.keys.sort.each do |key|
33
+ conf[key] = @config[key]
34
+ end
35
+ else
36
+ conf = @config
37
+ end
38
+ conf.each do |key, value|
39
+ #Skip any keys that are being overridden further up the chain
40
+ unless has_upper_recipe_override(key.clone)
41
+ #Since we converted all node['blah'] to strings, we need to convert them back
42
+ #Ahh. this is horrible, must be a better way to do this
43
+ val = value.to_s
44
+ val.gsub!(/node(\[['a-zA-Z0-9_-]*\])+/, '#{\&}')
45
+ if val =~ /^"#\{node(\[['a-zA-Z0-9_-]*\])+\}"$/
46
+ val.gsub!(/^"#\{|\}"$/, '')
47
+ end
48
+
49
+ val.gsub!(/node.chef_environment/, '#{\&}')
50
+ if val =~ /^"#\{node.chef_environment\}"$/
51
+ val.gsub!(/^"#\{|\}"$/, '')
52
+ end
53
+
54
+ if val =~ /^"\{\}"$/
55
+ val.gsub!(/"/, '')
56
+ end
57
+
58
+ attrs[key.collect { |part| "['#{part}']" }.join()] = val
59
+ end
60
+ end
61
+ attrs
62
+ end
63
+
64
+ def parse_key(key)
65
+ key
66
+ end
67
+
68
+ def parse_value(value)
69
+ if value =~ /^[0-9]+$/
70
+ # Got a number
71
+ elsif value =~ /^true$|^false$/
72
+ #Take any quotes off around true/false
73
+ return value.gsub("'", "")
74
+ elsif value.is_a? String
75
+ if is_json?(value)
76
+ return JSON.parse(value).to_json.inspect
77
+ elsif value.empty?
78
+ return "\"\""
79
+ else
80
+ value.gsub!(/^"|"$|^'|'$/, "")
81
+ #value.gsub!(/\\/, "")
82
+ return "\"#{value}\""
83
+ end
84
+ end
85
+ value
86
+ end
87
+
88
+ def is_json?(value)
89
+ begin
90
+ !!JSON.parse(value)
91
+ rescue
92
+ false
93
+ end
94
+ end
95
+
96
+ def from_file(filename)
97
+ end
98
+
99
+ def from_attributes_file(component, filename, force=false)
100
+ @node.from_file(filename)
101
+ conf = Fhcap::JsonConfig.new
102
+ conf.from_json(@node.default_attrs[component][:conf].to_json)
103
+ conf.config.each() do |k, v|
104
+ add(k, v, force)
105
+ end
106
+ end
107
+
108
+ def attribute_file_content(component, sort)
109
+ content = "# Default conf.rb attributes file, generated by fhcap, do not edit\n\n"
110
+ @node.included_recipe_attributes.each do |recipe|
111
+ content += "include_attribute '#{recipe}'\n"
112
+ end
113
+ self.to_chef_attributes(sort).collect do |key, value|
114
+ content += "default['#{component}']['conf']#{key} = #{value}\n"
115
+ end
116
+ content
117
+ end
118
+
119
+ end
120
+ end
@@ -0,0 +1,36 @@
1
+ require 'fhcap/misc/fh_config'
2
+ require 'java_properties'
3
+
4
+ module Fhcap
5
+ class JavaConfig < Fhcap::FHConfig
6
+
7
+ def initialize
8
+ super
9
+ end
10
+
11
+ def from_file(filename, force=false, overrides=[])
12
+ if File.exists?(filename) && File.readable?(filename)
13
+ props = JavaProperties::Properties.new(filename)
14
+ props.each do |key, value|
15
+ key = key.to_s
16
+ add(parse_key(key).split("."), value, force, overrides)
17
+ end
18
+ else
19
+ raise IOError, "Cannot open or read #{filename}!"
20
+ end
21
+ end
22
+
23
+ def parse_key(key)
24
+ case key
25
+ when 'feedhenry.domainsuffix'
26
+ return 'feedhenry.domainsuffix.external'
27
+ when 'digger.polling'
28
+ return 'digger.polling.enabled'
29
+ when 'fh.autosetup'
30
+ return 'fh.autosetup.enabled'
31
+ else
32
+ return key
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,59 @@
1
+ require 'fhcap/misc/fh_config'
2
+ require 'json'
3
+ require 'pp'
4
+
5
+ module Fhcap
6
+ class JsonConfig < Fhcap::FHConfig
7
+
8
+ def initialize
9
+ super
10
+ end
11
+
12
+ def from_file(filename, force=false, overrides=[])
13
+ if File.exists?(filename) && File.readable?(filename)
14
+ json = JSON.parse(IO.read(filename))
15
+ from_json(json, force, overrides)
16
+ else
17
+ raise IOError, "Cannot open or read #{filename}!"
18
+ end
19
+ end
20
+
21
+ def from_json(json, force=false, overrides=[])
22
+ keys = get_keys(json)
23
+ keys.each do |tuple|
24
+ current = tuple[0]
25
+ value = tuple[1]
26
+ add(current, value, force, overrides)
27
+ end
28
+ end
29
+
30
+ def get_keys(s, c=nil, keys=nil)
31
+ if s.is_a? String
32
+ s = JSON.parse(s)
33
+ end
34
+ keys ||= []
35
+ c ||= []
36
+ s.each_pair do |key, value|
37
+ c.push(key)
38
+ if value.class == Hash
39
+ get_keys(value, c, keys)
40
+ if value == {}
41
+ keys.push([c.clone, parse_value(value.to_json)])
42
+ end
43
+ elsif value.class == Array
44
+ # value.each_with_index do |val, ind|
45
+ # c.push(ind.to_s)
46
+ # get_keys(val, c, keys)
47
+ # c.pop
48
+ # end
49
+ keys.push([c.clone, JSON.parse(value.to_json)])
50
+ else
51
+ keys.push([c.clone, parse_value(value.to_json)])
52
+ end
53
+ c.pop
54
+ end
55
+ keys
56
+ end
57
+
58
+ end
59
+ end
data/lib/fhcap/repo.rb CHANGED
@@ -33,7 +33,7 @@ module Fhcap
33
33
 
34
34
  shared_options :verbose, :name
35
35
  method_option 'git-ref', :type => :string, :desc => "fhcap git ref, can be a branch, tag or commit hash"
36
- method_option 'remote', :type => :string, :default => 'origin', :desc => "Git remote to pull from"
36
+ method_option 'remote', :type => :string, :desc => "git remote to use, default is the remote for the configured repos url"
37
37
 
38
38
  def checkout
39
39
  require 'fhcap/tasks/repo/checkout'
@@ -0,0 +1,53 @@
1
+ require 'fhcap/tasks/chef/chef_task_base'
2
+
3
+ module Fhcap
4
+ module Tasks
5
+ module Chef
6
+ module Cookbook
7
+ class ListArtifacts < ChefTaskBase
8
+
9
+ def initialize(options)
10
+ super(options)
11
+ @format = options[:format] || 'table'
12
+ end
13
+
14
+ def run
15
+ thor.say "Chef::Cookbook::Component::List", :yellow
16
+ cookbooks = get_cookbooks(options, nil, repo_cookbook_paths('site-cookbooks'))
17
+
18
+ results = print_table? ? [table_header("Component", "Version", "Build")] : []
19
+
20
+ cookbooks.each do |name|
21
+ cookbook = cookbook_loader.cookbooks_by_name[name]
22
+ artifact_attribute_filepath = cookbook.attribute_filenames.find { |e| /artifact.rb/ =~ e }
23
+ if artifact_attribute_filepath
24
+ node = ::Chef::Node.new
25
+ node.from_file(artifact_attribute_filepath)
26
+ artifact_version = node.default[name]['version']
27
+ artifact_build = node.default[name]['build']
28
+ if print_table?
29
+ results << table_row(name, artifact_version, artifact_build)
30
+ else
31
+ results << {component: name, version: artifact_version, build: artifact_build}
32
+ end
33
+ end
34
+ end
35
+ thor.print_table results if print_table?
36
+ thor.say JSON.pretty_generate(results) if print_json?
37
+ end
38
+
39
+ private
40
+
41
+ def print_table?
42
+ @format == 'table'
43
+ end
44
+
45
+ def print_json?
46
+ @format == 'json'
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,39 @@
1
+ require 'fhcap/tasks/chef/chef_task_base'
2
+
3
+ module Fhcap
4
+ module Tasks
5
+ module Chef
6
+ module Cookbook
7
+ class UpdateArtifact < ChefTaskBase
8
+
9
+ attr_reader :name, :version, :build
10
+
11
+ def initialize(options)
12
+ super
13
+ @name = options[:cookbook]
14
+ @version = options[:version]
15
+ @build = options[:build]
16
+ end
17
+
18
+ def run
19
+ thor.say "Chef::Cookbook::UpdateArtifact cookbook = #{name}, version = #{version}, build = #{build}", :yellow
20
+ cookbook = cookbook_loader.cookbooks_by_name[name]
21
+
22
+ artifact_attribute_filepath = cookbook.attribute_filenames.find { |e| /artifact.rb/ =~ e }
23
+
24
+ if artifact_attribute_filepath
25
+ text = File.read(artifact_attribute_filepath)
26
+ replace = text.gsub(/default\['#{name}'\]\['version'\] = .+$/, "default['#{name}']['version'] = '#{version}'")
27
+ replace = replace.gsub(/default\['#{name}'\]\['build'\] = .+$/, "default['#{name}']['build'] = '#{build}'")
28
+ thor.create_file(artifact_attribute_filepath, replace, {force: !options[:interactive]})
29
+ else
30
+ thor.say_status("error", "No artifact file found for #{name}", :red)
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,78 @@
1
+ require 'fhcap/tasks/chef/chef_task_base'
2
+ require 'fhcap/misc/java_config'
3
+ require 'fhcap/misc/json_config'
4
+
5
+ module Fhcap
6
+ module Tasks
7
+ module Chef
8
+ module Cookbook
9
+ class UpdateConfig < ChefTaskBase
10
+
11
+ COMP_CFG_MAP = {
12
+ "fh-aaa" => "fh-aaa/config/dev.json",
13
+ "millicore" => "millicore/src/main/resources/config/cluster-config.properties",
14
+ "fh-reaper" => "millicore/src/main/resources/config/reaper.properties",
15
+ "fh-supercore" => "fh-supercore/config/dev.json",
16
+ "fh-docs" => ["fh-docs/config/development.json", "fh-docs/config/config.json"],
17
+ "fh-doxy" => "fh-doxy/config/dev.json",
18
+ "fh-messaging" => "fh-messaging/fh-messaging/config/conf.json",
19
+ "fh-metrics" => "fh-messaging/fh-metrics/config/conf.json",
20
+ "fh-ditch" => "fh-ditch/config/dev.json",
21
+ "fh-scm" => "fh-scm/config/dev.json",
22
+ "fh-stats" => "fh-stats/fh-statsd/config/dev.json",
23
+ "fh-dynoman" => "fh-dynoman/config/dev.json",
24
+ "fh-proxy" => "fh-proxy/config/dev.json",
25
+ "fh-ngui" => "fh-ngui/config/dev.json",
26
+ "fh-appstore" => "fh-appstore/config/dev.json",
27
+ "fh-digger" => "fh-digger/config/dev.json",
28
+ "fh-mbaas" => "fh-mbaas/config/dev.json",
29
+ }
30
+
31
+ attr_reader :name, :overrides, :sort, :force
32
+
33
+ def initialize(options)
34
+ super
35
+ @name = options[:cookbook]
36
+ @overrides = options[:overrides] || []
37
+ @sort = options[:sort] || true
38
+ @force = options[:force] || false
39
+ end
40
+
41
+ def run
42
+ thor.say "Chef::Cookbook::UpdateConfig cookbook = #{name}", :yellow
43
+ cookbook = cookbook_loader.cookbooks_by_name[name]
44
+
45
+ conf_attr_file = cookbook.attribute_filenames.find { |e| /conf.rb/ =~ e }
46
+ exit_with_error("No cookbook conf.rb attribute file found for #{name}") unless conf_attr_file
47
+
48
+ conf_src_files = cfg_lookup(name)
49
+ exit_with_error("No local src config file found for #{name}") if conf_src_files.empty?
50
+
51
+ thor.say "conf_attr_file = #{conf_attr_file}"
52
+ thor.say "conf_src_files = #{conf_src_files}"
53
+
54
+ conf_src_files.each() do |file|
55
+ if File.extname(file) =~ /.properties/
56
+ cfg = Fhcap::JavaConfig.new
57
+ else
58
+ cfg = Fhcap::JsonConfig.new
59
+ end
60
+ cfg.from_attributes_file(name, conf_attr_file)
61
+ cfg.from_file(file, force, overrides)
62
+ thor.create_file(conf_attr_file, cfg.attribute_file_content(name, sort))
63
+ end
64
+
65
+ end
66
+
67
+ private
68
+
69
+ def cfg_lookup(component)
70
+ cfg_paths = [COMP_CFG_MAP[component]].flatten.compact
71
+ cfg_paths.map! { |path| File.join(config.fh_src_dir, path) }
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -17,6 +17,7 @@ module Fhcap
17
17
  @cluster_config = JSON.parse(IO.read(@cluster_filepath), {:symbolize_names => true})
18
18
  @cluster_config.merge!({
19
19
  local_repo_path: repo_dir(@cluster_config[:repo]),
20
+ local_repo_clusters_dir: repo_clusters_dir(@cluster_config[:repo]),
20
21
  chef_server_config: chef_server_config_hash_for(@cluster_config[:chef_server]),
21
22
  provider_credentials: provider_credentials(@cluster_config[:provider_id])
22
23
  })
@@ -28,7 +29,8 @@ module Fhcap
28
29
 
29
30
  def do_chef_run(run_list)
30
31
  cookbook_path = File.join(Fhcap.source_root, 'lib', 'cookbooks')
31
- Fhcap::ChefRunner.new(cookbook_path, run_list, @cluster_config).converge
32
+ private_key_paths = [File.join(cluster_config[:local_repo_path], cluster_config[:local_repo_clusters_dir], 'key_pairs')]
33
+ Fhcap::ChefRunner.new(cookbook_path, run_list, cluster_config, private_key_paths).converge
32
34
  end
33
35
 
34
36
  end
@@ -110,7 +110,7 @@ module Fhcap
110
110
  ask_config(required_config, cluster_config)
111
111
  cluster_config[:driver] = provider_type(cluster_config[:provider_id])
112
112
  send(:"generate_cluster_config_#{cluster_config[:driver]}")
113
- driver_template_file = File.join('templates', 'cluster', cluster_config[:driver], "common.json.erb")
113
+ driver_template_file = File.join(Fhcap.source_root, 'templates', 'cluster', cluster_config[:driver], "common.json.erb")
114
114
  driver_template_config = template_as_object(driver_template_file, cluster_config)
115
115
  cluster_config.merge!(driver_template_config)
116
116
  end
@@ -131,11 +131,11 @@ module Fhcap
131
131
  end
132
132
 
133
133
  def create_cluster_environments
134
- env_template_file = File.join('templates', 'cluster', "#{cluster_config[:template]}.json.erb")
134
+ env_template_file = File.join(Fhcap.source_root, 'templates', 'cluster', "#{cluster_config[:template]}.json.erb")
135
135
  template_config = template_as_object(env_template_file, cluster_config)
136
136
 
137
137
  template_config[:environments].each do |env|
138
- env_template_file = File.join('templates', 'cluster', cluster_config[:driver], "#{env[:template]}.json.erb")
138
+ env_template_file = File.join(Fhcap.source_root, 'templates', 'cluster', cluster_config[:driver], "#{env[:template]}.json.erb")
139
139
  template_config = template_as_object(env_template_file, cluster_config)
140
140
 
141
141
  env_domain = [env[:'domain-prefix'], cluster_config[:domain]].compact.join('.')
@@ -14,7 +14,7 @@ module Fhcap
14
14
  @gitref = options[:"git-ref"]
15
15
  @repo = options[:repo] || options[:name]
16
16
  @fallback_gitref = options[:'fallback-git-ref']
17
- @remote = options[:remote] || options[:'git-remote'] || 'origin'
17
+ @remote = options[:remote] || options[:'git-remote'] || find_remote(@repo)
18
18
  end
19
19
 
20
20
  def run
@@ -41,6 +41,30 @@ module Fhcap
41
41
 
42
42
  private
43
43
 
44
+ def find_remote(repo)
45
+ remote = 'origin'
46
+ dir = repo_dir(repo)
47
+ if Dir.exists? dir
48
+ Dir.chdir repo_dir(repo) do
49
+ remotes = `git remote`.split
50
+ if remotes.length > 1
51
+ url = repo_cfg(repo)[:url]
52
+ remotes.each do |r|
53
+ remote_url = `git config --get remote.#{r}.url`.strip
54
+ if remote_url == url
55
+ remote = r
56
+ break
57
+ end
58
+ end
59
+ remote
60
+ else
61
+ remotes.first
62
+ end
63
+ end
64
+ end
65
+ remote
66
+ end
67
+
44
68
  def git_clone(repo)
45
69
  Dir.exists?(repo_dir(repo)) ? true : do_clone_cmd(repo)
46
70
  end
@@ -12,6 +12,7 @@ module Fhcap
12
12
 
13
13
  opts = {
14
14
  repos_dir: options[:'repos-dir'],
15
+ fh_src_dir: options[:'fh-src-dir'],
15
16
  }.delete_if { |k, v| v.nil? || v.empty? }
16
17
 
17
18
  @fhcap_config.merge!(opts)
@@ -31,6 +32,10 @@ module Fhcap
31
32
  repos_dir: {
32
33
  msg: "Local directory where repos will be checked out",
33
34
  options: {:path => true}
35
+ },
36
+ fh_src_dir: {
37
+ msg: "Local directory where FH component src repos are checked out",
38
+ options: {:path => true}
34
39
  }
35
40
  }
36
41
  end
data/lib/fhcap/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fhcap
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require "fhcap/tasks/chef/cookbook/list_artifacts"
3
+
4
+ describe Fhcap::Tasks::Chef::Cookbook::ListArtifacts do
5
+
6
+ subject {
7
+ Fhcap::Tasks::Chef::Cookbook::ListArtifacts.new(options)
8
+ }
9
+
10
+ let(:thor) do
11
+ DummyThor.new
12
+ end
13
+
14
+ let(:config) do
15
+ {}
16
+ end
17
+
18
+ context "table" do
19
+
20
+ let(:options) do
21
+ {
22
+ :config => config,
23
+ :thor => thor,
24
+ :format => 'table'
25
+ }
26
+ end
27
+
28
+ describe "#initialize" do
29
+ specify { expect(subject.instance_variable_get(:@format)).to eq('table') }
30
+ end
31
+
32
+ end
33
+
34
+ context "json" do
35
+
36
+ let(:options) do
37
+ {
38
+ :config => config,
39
+ :thor => thor,
40
+ :format => 'json'
41
+ }
42
+ end
43
+
44
+ describe "#initialize" do
45
+ specify { expect(subject.instance_variable_get(:@format)).to eq('json') }
46
+ end
47
+
48
+ end
49
+
50
+
51
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require "fhcap/tasks/chef/cookbook/update_artifact"
3
+
4
+ describe Fhcap::Tasks::Chef::Cookbook::UpdateArtifact do
5
+
6
+ subject {
7
+ Fhcap::Tasks::Chef::Cookbook::UpdateArtifact.new(options)
8
+ }
9
+
10
+ let(:thor) do
11
+ DummyThor.new
12
+ end
13
+
14
+ let(:config) do
15
+ {}
16
+ end
17
+
18
+ let(:options) do
19
+ {
20
+ :config => config,
21
+ :thor => thor,
22
+ :cookbook => 'testname',
23
+ :version => '9.9.9',
24
+ :build => '999'
25
+ }
26
+ end
27
+
28
+ describe "#initialize" do
29
+ specify { expect(subject.name).to eq('testname') }
30
+ specify { expect(subject.version).to eq('9.9.9') }
31
+ specify { expect(subject.build).to eq('999') }
32
+ end
33
+
34
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+ require "fhcap/tasks/chef/cookbook/update_config"
3
+
4
+ describe Fhcap::Tasks::Chef::Cookbook::UpdateConfig do
5
+
6
+ subject {
7
+ Fhcap::Tasks::Chef::Cookbook::UpdateConfig.new(options)
8
+ }
9
+
10
+ let(:thor) do
11
+ DummyThor.new
12
+ end
13
+
14
+ let(:config) do
15
+ {}
16
+ end
17
+
18
+ context 'default' do
19
+
20
+ let(:options) do
21
+ {
22
+ :config => config,
23
+ :thor => thor,
24
+ :cookbook => 'testname'
25
+ }
26
+ end
27
+
28
+ describe "#initialize" do
29
+ specify { expect(subject.name).to eq('testname') }
30
+ specify { expect(subject.overrides).to eq([]) }
31
+ specify { expect(subject.sort).to eq(true) }
32
+ specify { expect(subject.force).to eq(false) }
33
+ end
34
+
35
+ end
36
+
37
+ context 'force' do
38
+
39
+ let(:options) do
40
+ {
41
+ :config => config,
42
+ :thor => thor,
43
+ :cookbook => 'testname',
44
+ :force => true
45
+ }
46
+ end
47
+
48
+ describe "#initialize" do
49
+ specify { expect(subject.name).to eq('testname') }
50
+ specify { expect(subject.overrides).to eq([]) }
51
+ specify { expect(subject.sort).to eq(true) }
52
+ specify { expect(subject.force).to eq(true) }
53
+ end
54
+
55
+ end
56
+
57
+ context 'overrides' do
58
+
59
+ let(:options) do
60
+ {
61
+ :config => config,
62
+ :thor => thor,
63
+ :cookbook => 'testname',
64
+ :overrides => ['some.override']
65
+ }
66
+ end
67
+
68
+ describe "#initialize" do
69
+ specify { expect(subject.name).to eq('testname') }
70
+ specify { expect(subject.overrides).to eq(['some.override']) }
71
+ specify { expect(subject.sort).to eq(true) }
72
+ specify { expect(subject.force).to eq(false) }
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -38,6 +38,16 @@
38
38
  "sources": ["83.147.149.210/32", "46.38.161.225/32", "54.229.76.48/32", "79.125.117.182/32"]
39
39
  }
40
40
  ]
41
+ },
42
+ "support-dmz": {
43
+ "authorize_ingress": [
44
+ {
45
+ "protocols": ["tcp"],
46
+ "start": 8811,
47
+ "end": 8811,
48
+ "sources": ["213.175.37.8/29", "149.11.118.8/29"]
49
+ }
50
+ ]
41
51
  }
42
52
  }
43
53
  }
@@ -2,15 +2,15 @@
2
2
  "domain": "<%= config[:domain] %>",
3
3
  "subnets": {
4
4
  "1a": {
5
- "cidr": "64/26",
5
+ "cidr": "0/26",
6
6
  "availability_zone": "1a"
7
7
  },
8
8
  "1b": {
9
- "cidr": "128/26",
9
+ "cidr": "64/26",
10
10
  "availability_zone": "1b"
11
11
  },
12
12
  "1c": {
13
- "cidr": "192/26",
13
+ "cidr": "128/26",
14
14
  "availability_zone": "1c"
15
15
  }
16
16
  },
@@ -2,15 +2,15 @@
2
2
  "domain": "<%= config[:domain] %>",
3
3
  "subnets": {
4
4
  "1a": {
5
- "cidr": "64/26",
5
+ "cidr": "0/26",
6
6
  "availability_zone": "1a"
7
7
  },
8
8
  "1b": {
9
- "cidr": "128/26",
9
+ "cidr": "64/26",
10
10
  "availability_zone": "1b"
11
11
  },
12
12
  "1c": {
13
- "cidr": "192/26",
13
+ "cidr": "128/26",
14
14
  "availability_zone": "1c"
15
15
  }
16
16
  },
@@ -2,15 +2,15 @@
2
2
  "domain": "<%= config[:domain] %>",
3
3
  "subnets": {
4
4
  "1a": {
5
- "cidr": "64/26",
5
+ "cidr": "0/26",
6
6
  "availability_zone": "1a"
7
7
  },
8
8
  "1b": {
9
- "cidr": "128/26",
9
+ "cidr": "64/26",
10
10
  "availability_zone": "1b"
11
11
  },
12
12
  "1c": {
13
- "cidr": "192/26",
13
+ "cidr": "128/26",
14
14
  "availability_zone": "1c"
15
15
  }
16
16
  },
@@ -2,11 +2,11 @@
2
2
  "domain": "<%= config[:domain] %>",
3
3
  "subnets": {
4
4
  "1a": {
5
- "cidr": "64/26",
5
+ "cidr": "0/26",
6
6
  "availability_zone": "1a"
7
7
  },
8
8
  "1b": {
9
- "cidr": "128/26",
9
+ "cidr": "64/26",
10
10
  "availability_zone": "1b"
11
11
  }
12
12
  },
@@ -2,15 +2,15 @@
2
2
  "domain": "<%= config[:domain] %>",
3
3
  "subnets": {
4
4
  "1a": {
5
- "cidr": "64/26",
5
+ "cidr": "0/26",
6
6
  "availability_zone": "1a"
7
7
  },
8
8
  "1b": {
9
- "cidr": "128/26",
9
+ "cidr": "64/26",
10
10
  "availability_zone": "1b"
11
11
  },
12
12
  "1c": {
13
- "cidr": "192/26",
13
+ "cidr": "128/26",
14
14
  "availability_zone": "1c"
15
15
  }
16
16
  },
@@ -82,7 +82,21 @@
82
82
  "subnet": "1a"
83
83
  },
84
84
  "load_balancers": ["studio"],
85
- "run_list": ["role[fhcap]"]
85
+ "run_list": [
86
+ "role[mysql_server]",
87
+ "role[mongo_server]",
88
+ "role[platform_mongo_server]",
89
+ "role[gitlab-shell_server]",
90
+ "role[rabbitmq_server]",
91
+ "role[app_server]",
92
+ "role[pooled_server]",
93
+ "role[dyno_server]",
94
+ "role[fh-reaper]",
95
+ "role[fh-stats]",
96
+ "role[management_server]",
97
+ "recipe[tmuxinator]",
98
+ "recipe[feedhenry_common::fhctl]"
99
+ ]
86
100
  }
87
101
  }
88
102
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fhcap-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Nairn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-20 00:00:00.000000000 Z
11
+ date: 2015-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ~>
123
123
  - !ruby/object:Gem::Version
124
124
  version: 1.7.5
125
+ - !ruby/object:Gem::Dependency
126
+ name: java_properties
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: 0.0.4
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ~>
137
+ - !ruby/object:Gem::Version
138
+ version: 0.0.4
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: aws-sdk
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -363,6 +377,7 @@ files:
363
377
  - lib/fhcap/chef-dk/chef_runner.rb
364
378
  - lib/fhcap/cli.rb
365
379
  - lib/fhcap/cluster.rb
380
+ - lib/fhcap/component.rb
366
381
  - lib/fhcap/config.rb
367
382
  - lib/fhcap/cookbook.rb
368
383
  - lib/fhcap/dummy_node.rb
@@ -371,13 +386,19 @@ files:
371
386
  - lib/fhcap/knife.rb
372
387
  - lib/fhcap/knife_helper.rb
373
388
  - lib/fhcap/misc.rb
389
+ - lib/fhcap/misc/fh_config.rb
390
+ - lib/fhcap/misc/java_config.rb
391
+ - lib/fhcap/misc/json_config.rb
374
392
  - lib/fhcap/provider.rb
375
393
  - lib/fhcap/providers_helper.rb
376
394
  - lib/fhcap/repo.rb
377
395
  - lib/fhcap/repos_helper.rb
378
396
  - lib/fhcap/tasks/chef/chef_task_base.rb
379
397
  - lib/fhcap/tasks/chef/cookbook/list.rb
398
+ - lib/fhcap/tasks/chef/cookbook/list_artifacts.rb
399
+ - lib/fhcap/tasks/chef/cookbook/update_artifact.rb
380
400
  - lib/fhcap/tasks/chef/cookbook/update_changelog.rb
401
+ - lib/fhcap/tasks/chef/cookbook/update_config.rb
381
402
  - lib/fhcap/tasks/chef/cookbook/update_metadata.rb
382
403
  - lib/fhcap/tasks/chef/cookbook/update_readme.rb
383
404
  - lib/fhcap/tasks/chef/cookbook/update_version.rb
@@ -421,6 +442,9 @@ files:
421
442
  - lib/fhcap/thor_base.rb
422
443
  - lib/fhcap/version.rb
423
444
  - spec/fhcap/cli_spec.rb
445
+ - spec/fhcap/tasks/chef/cookbook/list_artifacts_spec.rb
446
+ - spec/fhcap/tasks/chef/cookbook/update_artifact_spec.rb
447
+ - spec/fhcap/tasks/chef/cookbook/update_config_spec.rb
424
448
  - spec/fhcap/tasks/cluster/create_spec.rb
425
449
  - spec/fhcap/tasks/knife/add_spec.rb
426
450
  - spec/fhcap/tasks/knife/remove_spec.rb
@@ -492,6 +516,9 @@ specification_version: 4
492
516
  summary: FHCAP Command Line Tool
493
517
  test_files:
494
518
  - spec/fhcap/cli_spec.rb
519
+ - spec/fhcap/tasks/chef/cookbook/list_artifacts_spec.rb
520
+ - spec/fhcap/tasks/chef/cookbook/update_artifact_spec.rb
521
+ - spec/fhcap/tasks/chef/cookbook/update_config_spec.rb
495
522
  - spec/fhcap/tasks/cluster/create_spec.rb
496
523
  - spec/fhcap/tasks/knife/add_spec.rb
497
524
  - spec/fhcap/tasks/knife/remove_spec.rb