chapp 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6b7400e9bd5d239d51f9da4e50f7e59b750f0f4c
4
- data.tar.gz: a640f10a2332bc0611be364cb5a4ddd2e051e0f9
3
+ metadata.gz: a55bf03c52c00bafbe28fa2f50706f45b0bdf0f5
4
+ data.tar.gz: 5a386ad53a944249f1915531c3edd8eb53789a38
5
5
  SHA512:
6
- metadata.gz: fe6fedbfcd25cf6c73851ac1f623582ad9a2c6ab66127090dec2194b33f43ca02478aa57ec9baa27fdcb9f3c1804ecc66e94790cc7fb4c381d14c81a570c57af
7
- data.tar.gz: 798403528dd3f6d8e31d21ae258bb4fb29c8e5c91767ae22801bd251c1ca3b2bcc743a2a5756f14cb835065f63c08bfbfa764a7d498146377be7bf5e68189443
6
+ metadata.gz: 69b6a02ba6e2cd304007a3721ee56aa3cc9360e0b145010e0527a4b6fdb82413d0a616d2992afef06c9ab27077d60db664b3d78a5304ffe927d97fcd8d4bffdb
7
+ data.tar.gz: e74ced9f3850c76c3fc8b075dc3a88fc03935fa8971ff337500a8187d7a5de759d628dc7e3b0ae2b9753c7db57ed77711647f20b6e80fbd1ed6f3df8a73d8dc1
@@ -4,7 +4,7 @@ require 'chapp/app_config'
4
4
  require 'chapp/wiring'
5
5
  require 'chapp/database'
6
6
  require 'chapp/provisioner'
7
- require 'chapp/provisioner/property_provisioner'
7
+ require 'chapp/provisioner/ec2_provisioner'
8
8
 
9
9
  module Chapp
10
10
 
@@ -14,7 +14,7 @@ module Chapp
14
14
 
15
15
  def self.provisioner
16
16
  # TODO: Make configurable
17
- Chapp::PropertyProvisioner.new
17
+ Chapp::EC2Provisioner.new
18
18
  end
19
19
 
20
20
  end
@@ -3,55 +3,37 @@ require 'chef/node/attribute'
3
3
 
4
4
  module Chapp
5
5
  class App
6
-
7
- def initialize id, db, config=nil, attributes=nil
6
+
7
+ attr_reader :id, :attributes, :instances
8
+
9
+ def initialize id, attributes, instances, db
8
10
  @id = id
9
11
  @db = db
10
- @config = config
11
12
  @attributes = attributes
12
- @instances = nil
13
+ @instances = instances
14
+ @config = nil
13
15
  @connected_apps = nil
14
16
  end
15
-
16
- def id
17
- @id
18
- end
19
-
17
+
20
18
  def config
21
19
  unless @config
22
20
  @config = @db.app_config @id
23
21
  end
24
-
22
+
25
23
  @config
26
24
  end
27
-
28
- def instances
29
- unless @instances
30
- @instances = @db.app_instances @id
31
- end
32
-
33
- @instances
34
- end
35
-
36
- def attributes
37
- unless @attributes
38
- @attributes = @db.app_attributes @id
39
- end
40
-
41
- @attributes
42
- end
43
-
25
+
44
26
  def connected_apps
45
27
  unless @connected_apps
46
28
  @connected_apps = Array.new
47
-
29
+
48
30
  @db.connected_app_ids(@id).each do |app_id|
49
- @connected_apps << App.new(app_id, @db)
31
+ @connected_apps << @db.app(app_id)
50
32
  end
51
33
  end
52
-
34
+
53
35
  @connected_apps
54
36
  end
55
-
37
+
56
38
  end
57
- end
39
+ end
@@ -0,0 +1,45 @@
1
+ require 'chapp'
2
+
3
+ module Chapp
4
+ class NodeApp < Chapp::App
5
+
6
+ def initialize id, db, config, attributes, node_name, fqdn
7
+ @id = id
8
+ @db = db
9
+ @config = config
10
+ @fqdn = fqdn
11
+ @node_name = node_name
12
+ @attributes = attributes
13
+
14
+ @instances = nil
15
+ @connected_apps = nil
16
+ end
17
+
18
+ def instances
19
+ unless @instances
20
+ app = @db.app id
21
+ app_instances = app.instances
22
+ @instances = []
23
+
24
+ # If we can't find our own instance add it to the list
25
+ found_node = false
26
+ app_instances.each do |instance|
27
+ if instance.node_name == @node_name
28
+ found_node = true
29
+ @instances << Chapp::AppInstance.new(id, @node_name, @fqdn)
30
+ break
31
+ else
32
+ @instances << instance
33
+ end
34
+ end
35
+
36
+ unless found_node
37
+ @instances << Chapp::AppInstance.new(id, @node_name, @fqdn)
38
+ end
39
+ end
40
+
41
+ @instances
42
+ end
43
+
44
+ end
45
+ end
@@ -41,6 +41,8 @@ module Chapp
41
41
  end
42
42
  end
43
43
 
44
+ app.cloud app_hash["cloud"]
45
+
44
46
  app.node Chef::Node::Attribute.new({}, app_hash["node"], {}, {}).default
45
47
  app.environment app_hash["environment"]
46
48
 
@@ -63,6 +65,7 @@ module Chapp
63
65
  @group = nil
64
66
  @name = nil
65
67
  @used_apps = Hash.new
68
+ @cloud = Hash.new
66
69
  @dependencies = Hash.new
67
70
  @pre_run_list = Array.new
68
71
  @post_run_list = Array.new
@@ -139,6 +142,10 @@ module Chapp
139
142
  set_or_return :node, node
140
143
  end
141
144
 
145
+ def cloud cloud=nil
146
+ set_or_return :cloud, cloud
147
+ end
148
+
142
149
  def run_list run_list=nil
143
150
  set_or_return :run_list, run_list
144
151
  end
@@ -154,6 +161,8 @@ module Chapp
154
161
  hash.store "name", name
155
162
  hash.store "used_apps", used_apps
156
163
 
164
+ hash.store "cloud", cloud
165
+
157
166
  hash.store "pre_run_list", pre_run_list
158
167
  hash.store "post_run_list", post_run_list
159
168
 
@@ -7,167 +7,151 @@ require 'chef/search/query'
7
7
 
8
8
  module Chapp
9
9
  class Database
10
-
10
+
11
11
  APPS_CONFIG_DATA_BAG_NAME = "chapp_apps_config"
12
12
  APP_ATTRIBUTES_DATA_BAG_NAME = "chapp_app_attributes"
13
-
13
+
14
14
  def app_ids
15
15
  apps_config_databag.keys
16
16
  end
17
-
17
+
18
18
  def app_config app_id
19
-
19
+
20
20
  unless app_exists? app_id
21
21
  raise AppNotExistsException.new, "App [#{app_id}] does not exist"
22
22
  end
23
-
23
+
24
24
  AppConfig.from_hash apps_config_databag_item(app_id).raw_data["app"]
25
25
  end
26
-
26
+
27
27
  def app_exists? app_id
28
28
  apps_config_databag.has_key? app_id
29
29
  end
30
-
30
+
31
31
  def connected_app_ids app_id
32
32
  app_ids = Array.new
33
-
33
+
34
34
  query = Chef::Search::Query.new
35
35
  query.search APPS_CONFIG_DATA_BAG_NAME, "used_apps:#{app_id}" do |databag_item|
36
36
  app_config = AppConfig.from_hash databag_item.raw_data["app"]
37
37
  app_ids.push app_config.id
38
38
  end
39
-
39
+
40
40
  app_ids
41
41
  end
42
42
 
43
43
  def write_app_config app_config
44
-
44
+
45
45
  # TODO Verify used_apps exist
46
46
  # TODO Verify cookbooks exist
47
-
47
+
48
48
  app_role_name = app_config.role_name
49
-
49
+
50
50
  attributes = app_config.node
51
51
  attributes["chapp"]["app_id"] = app_config.id
52
-
52
+
53
53
  # Build/Save role
54
54
  role = Chef::Role.new
55
55
  role.name app_role_name
56
56
  role.description "Used to define the App [#{app_config.id}]"
57
57
  role.default_attributes attributes.to_hash
58
- role.run_list "recipe[chapp]", *app_config.pre_run_list, "recipe[#{app_config.cookbook}::#{app_config.recipe}]", *app_config.post_run_list, "recipe[chapp::publish_app_attributes]"
58
+ role.run_list "recipe[chapp]", *app_config.pre_run_list, "recipe[#{app_config.cookbook}::#{app_config.recipe}]", *app_config.post_run_list
59
59
  role.save
60
-
60
+
61
61
  # Set run_list of app to role
62
62
  app_config.run_list ["role[#{app_role_name}]"]
63
-
63
+
64
64
  environment_name = app_config.environment_name
65
-
65
+
66
66
  # Build/Save environment
67
67
  environment = Chef::Environment.new
68
68
  environment.name environment_name
69
69
  environment.description "Used to define the dependencies of App [#{app_config.id}]"
70
-
70
+
71
71
  app_config.dependencies.each do |cookbook, version|
72
72
  environment.cookbook cookbook, version
73
73
  end
74
-
74
+
75
75
  environment.save
76
-
77
- # Set environment of app
76
+
77
+ # Set environment of app
78
78
  app_config.environment environment_name
79
-
79
+
80
80
  # Update app databag item
81
81
  databag_item = apps_config_databag_item app_config.id
82
82
  databag_item.raw_data["app"] = app_config.to_hash
83
83
  databag_item.save
84
-
84
+
85
85
  end
86
-
86
+
87
87
  def delete_app app_name
88
88
  # TODO (not necessary for now)
89
89
  # Delete role/environment, app config databag item, app attribute databag item, app instances
90
90
  end
91
-
92
- def app_instances app_id
93
- app_instances = Array.new
94
-
91
+
92
+ def app app_id
93
+ app_instances = []
94
+ app_attributes = {}
95
+ latest_time = 0
96
+
95
97
  query = Chef::Search::Query.new
96
98
  # TODO Figure out how to get role name more appropriately
97
99
  query.search(:node, "role:chapp_#{app_id}") do |node|
98
100
  app_instances.push Chapp::AppInstance.new(app_id, node.name, node["fqdn"])
101
+
102
+ if node.has_key?("ohai_time") && node.has_key?("chapp") && node["chapp"].has_key?("app_attributes") && node["ohai_time"] > latest_time
103
+ latest_time = node["ohai_time"]
104
+ app_attributes = node["chapp"]["app_attributes"].to_hash
105
+ end
99
106
  end
100
-
101
- app_instances
107
+
108
+ Chapp::App.new app_id, app_attributes, app_instances, self
102
109
  end
103
-
110
+
104
111
  def write_app_instance app_instance
105
112
  # NOOP (uses Chef Search)
106
113
  end
107
-
114
+
108
115
  def delete_app_instance app_instance
109
116
  # TODO: Delete node/client (not necessary for now)
110
117
  end
111
-
118
+
112
119
  def app_attributes app_id
113
120
  databag = app_attributes_databag
114
-
121
+
115
122
  unless databag.has_key? app_id
116
123
  raise AppAttributesNotExistsException.new, "Attributes for app [#{app_id}] do not exist"
117
124
  end
118
-
125
+
119
126
  app_attributes_databag_item(app_id).raw_data["app_attributes"]
120
127
  end
121
-
122
- def write_app_attributes app_id, app_attributes
123
- databag_item = app_attributes_databag_item app_id
124
- databag_item.raw_data["app_attributes"] = app_attributes
125
- databag_item.save
126
- end
127
-
128
- def delete_app_attributes app_id
129
- databag = app_attributes_databag
130
-
131
- if databag.has_key? app_id
132
- app_attributes_databag_item(app_id).destroy
133
- end
134
-
135
- end
136
-
128
+
137
129
  class AppAttributesNotExistsException < StandardError; end
138
130
  class AppNotExistsException < StandardError; end
139
-
131
+
140
132
  private
141
-
133
+
142
134
  def apps_config_databag
143
135
  get_or_create_databag APPS_CONFIG_DATA_BAG_NAME
144
136
  end
145
-
137
+
146
138
  def apps_config_databag_item app_id
147
139
  load_or_build_databag_item apps_config_databag, APPS_CONFIG_DATA_BAG_NAME, app_id
148
140
  end
149
-
150
- def app_attributes_databag
151
- get_or_create_databag APP_ATTRIBUTES_DATA_BAG_NAME
152
- end
153
-
154
- def app_attributes_databag_item app_id
155
- load_or_build_databag_item app_attributes_databag, APP_ATTRIBUTES_DATA_BAG_NAME, app_id
156
- end
157
-
141
+
158
142
  def get_or_create_databag databag_name
159
143
  databags = Chef::DataBag.list
160
-
144
+
161
145
  unless databags.include? databag_name
162
146
  # Create databag if it does not exist
163
147
  databag = Chef::DataBag.new
164
148
  databag.name databag_name
165
149
  databag.save
166
150
  end
167
-
151
+
168
152
  Chef::DataBag.load databag_name
169
153
  end
170
-
154
+
171
155
  def load_or_build_databag_item databag, databag_name, databag_item_name
172
156
  if databag.keys.include? databag_item_name
173
157
  databag_item = Chef::DataBagItem.load databag_name, databag_item_name
@@ -176,10 +160,10 @@ module Chapp
176
160
  databag_item = Chef::DataBagItem.new
177
161
  databag_item.data_bag databag_name
178
162
  databag_item.raw_data["id"] = databag_item_name
179
-
163
+
180
164
  databag_item
181
165
  end
182
166
  end
183
-
167
+
184
168
  end
185
169
  end
@@ -0,0 +1,67 @@
1
+ require 'chapp'
2
+ require 'aws'
3
+
4
+ module Chapp
5
+ class EC2Provisioner < Chapp::Provisioner
6
+
7
+ # Knife config
8
+ ACCESS_KEY = "ec2_access_key_id"
9
+ SECRET_KEY = "ec2_secret_access_key"
10
+ KEY_PAIR = "ec2_key_pair"
11
+
12
+ # App config
13
+ IMAGE_ID = "image_id"
14
+ INSTANCE_TYPE = "instance_type"
15
+
16
+ def build_server app_config, properties
17
+
18
+ errors = []
19
+
20
+ access_key = Chef::Config[ACCESS_KEY]
21
+ secret_key = Chef::Config[SECRET_KEY]
22
+ key_pair = Chef::Config[KEY_PAIR]
23
+
24
+ if access_key.nil?
25
+ errors << "#{ACCESS_KEY} must be specified in your knife config"
26
+ end
27
+
28
+ if secret_key.nil?
29
+ errors << "#{SECRET_KEY} must be specified in your knife config"
30
+ end
31
+
32
+ if key_pair.nil?
33
+ errors << "#{KEY_PAIR} must be specified in your knife config"
34
+ end
35
+
36
+ unless app_config.cloud.has_key? IMAGE_ID
37
+ errors << "#{IMAGE_ID} must be specified in your app's cloud config"
38
+ end
39
+
40
+ unless app_config.cloud.has_key? INSTANCE_TYPE
41
+ errors << "#{INSTANCE_TYPE} must be specified in your app's cloud config"
42
+ end
43
+
44
+ image_id = app_config.cloud[IMAGE_ID]
45
+ instance_type = app_config.cloud[INSTANCE_TYPE]
46
+
47
+ ec2 = AWS::EC2.new(:access_key_id => access_key, :secret_access_key => secret_key)
48
+
49
+ instance = ec2.instances.create(
50
+ :image_id => image_id,
51
+ :instance_type => instance_type,
52
+ :key_pair => ec2.key_pairs[key_pair]
53
+ )
54
+
55
+ puts "Waiting for new instance with id #{instance.id} to become available..."
56
+ sleep 1 while instance.status == :pending
57
+
58
+ puts "#{instance.dns_name} is ready"
59
+
60
+ # TODO: Wait for SSH to become available
61
+ sleep 70
62
+
63
+ instance.dns_name
64
+ end
65
+
66
+ end
67
+ end
@@ -1,19 +1,19 @@
1
1
  require 'chapp'
2
+ require 'chapp/app/node_app'
2
3
 
3
4
  module Chapp
4
5
 
5
6
  class Wiring
6
7
 
7
- attr_reader :announcements
8
8
  attr_reader :node
9
9
 
10
10
  def initialize app_config, db, node
11
- @announcements = Hash.new
12
11
  @used_apps = Hash.new
13
12
 
14
13
  @db = db
15
14
  @node = node
16
- @app = App.new app_config.id, db, app_config, @announcements
15
+ @app = Chapp::NodeApp.new app_config.id, db, app_config, node.default["chapp"]["app_attributes"],
16
+ Chef::Config[:node_name], node["fqdn"]
17
17
 
18
18
  app_config.used_apps.each do |type, app_ids|
19
19
  unless @used_apps.has_key? type
@@ -21,7 +21,7 @@ module Chapp
21
21
  end
22
22
 
23
23
  app_ids.each do |app_id|
24
- @used_apps[type] << App.new(app_id, db)
24
+ @used_apps[type] << app_id
25
25
  end
26
26
  end
27
27
  end
@@ -38,7 +38,7 @@ module Chapp
38
38
  raise "App uses many apps of [#{type}]"
39
39
  end
40
40
 
41
- @used_apps[type].first
41
+ @db.app @used_apps[type].first
42
42
  end
43
43
  end
44
44
 
@@ -47,7 +47,7 @@ module Chapp
47
47
  raise "App does not use app of type [#{type}]"
48
48
  end
49
49
 
50
- @used_apps[type]
50
+ @db.app @used_apps[type]
51
51
  end
52
52
 
53
53
  end
@@ -40,12 +40,13 @@ class Chef
40
40
 
41
41
  app_config = db.app_config app_id
42
42
 
43
- # TODO: May need something better than Time
44
- node_name = "chapp_#{app_id}_#{Time.now.to_i}"
45
-
46
43
  # Provision the server and retrieve the host name
47
44
  host = provisioner.build_server app_config, properties
48
45
 
46
+ properties.each do |key, value|
47
+ @config[key.to_sym] = value
48
+ end
49
+
49
50
  # Tells bootstrap what environment to use
50
51
  Chef::Config[:environment] = app_config.environment_name
51
52
 
@@ -53,7 +54,7 @@ class Chef
53
54
  @config[:run_list] = "role[#{app_config.role_name}]"
54
55
 
55
56
  # Tells bootstrap what node name to use
56
- @config[:chef_node_name] = node_name
57
+ @config[:chef_node_name] = host
57
58
 
58
59
  # Tells bootstrap what ip/fqdn to use
59
60
  @name_args = host
@@ -63,7 +64,7 @@ class Chef
63
64
 
64
65
  # We have to save the node here since bootstrap wont actually assign the run_list
65
66
  node = Node.new
66
- node.name node_name
67
+ node.name host
67
68
  node.run_list = Chef::RunList.new "role[#{app_config.role_name}]"
68
69
  node.chef_environment = app_config.environment_name
69
70
  node.save
@@ -20,9 +20,9 @@ class Chef
20
20
 
21
21
  app_id = @name_args[0]
22
22
 
23
- db = Chapp.database
23
+ app = Chapp.database.app app_id
24
24
 
25
- app_config = db.app_config app_id
25
+ app_config = app.config
26
26
 
27
27
  puts "App :"
28
28
  puts " id : #{app_config.id}"
@@ -31,6 +31,7 @@ class Chef
31
31
  puts " type : #{app_config.type}"
32
32
  puts " cookbook : #{app_config.cookbook}"
33
33
  puts " recipe : #{app_config.recipe}"
34
+ puts " cloud : #{app_config.cloud}"
34
35
 
35
36
  puts " used_apps :"
36
37
  app_config.used_apps.each do |type, used_app_ids|
@@ -61,15 +62,10 @@ class Chef
61
62
  puts ""
62
63
 
63
64
  puts "App Attributes :"
64
- begin
65
- attributes = db.app_attributes app_id
66
- print_hash attributes, 2
67
- rescue Chapp::Database::AppAttributesNotExistsException => e
68
- puts " NONE"
69
- end
65
+ print_hash app.attributes, 2
70
66
 
71
67
  puts "App Instances :"
72
- db.app_instances(app_id).each do |app_instance|
68
+ app.instances.each do |app_instance|
73
69
  puts " #{app_instance.fqdn}"
74
70
  end
75
71
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chapp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Baugher
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-24 00:00:00.000000000 Z
11
+ date: 2014-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '11.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '2.10'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '2.10'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -45,19 +59,21 @@ executables: []
45
59
  extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
48
- - Gemfile
49
- - lib/chapp.rb
62
+ - lib/chapp/app/node_app.rb
50
63
  - lib/chapp/app.rb
51
64
  - lib/chapp/app_config.rb
52
65
  - lib/chapp/app_instance.rb
53
66
  - lib/chapp/database.rb
54
- - lib/chapp/provisioner.rb
67
+ - lib/chapp/provisioner/ec2_provisioner.rb
55
68
  - lib/chapp/provisioner/property_provisioner.rb
69
+ - lib/chapp/provisioner.rb
56
70
  - lib/chapp/wiring.rb
71
+ - lib/chapp.rb
57
72
  - lib/chef/knife/app_instance_create.rb
58
73
  - lib/chef/knife/app_list.rb
59
74
  - lib/chef/knife/app_show.rb
60
75
  - lib/chef/knife/app_upload.rb
76
+ - Gemfile
61
77
  homepage: http://github.com/bbaugher/chapp
62
78
  licenses:
63
79
  - The MIT License (MIT)
@@ -78,8 +94,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
94
  version: '0'
79
95
  requirements: []
80
96
  rubyforge_project: nowarning
81
- rubygems_version: 2.2.1
97
+ rubygems_version: 2.0.3
82
98
  signing_key:
83
99
  specification_version: 4
84
100
  summary: A Chef knife plugin for creating Chef Apps
85
101
  test_files: []
102
+ has_rdoc: