podnix 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,239 @@
1
+ # Copyright:: Copyright (c) 2012, 2013 Megam Systems
2
+ # License:: Apache License, Version 2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ module Podnix
17
+ class AppRequest
18
+ # Each notify entry is a resource/action pair, modeled as an
19
+ # Struct with a #resource and #action member
20
+ =begin
21
+ def self.hash_tree
22
+ Hash.new do |hash, key|
23
+ hash[key] = hash_tree
24
+ end
25
+ end
26
+ =end
27
+
28
+ def initialize
29
+ @id = nil
30
+ @req_type = nil
31
+ @appdefns_id = nil
32
+ @node_name = nil
33
+ @lc_apply = nil
34
+ @lc_additional = nil
35
+ @lc_when = nil
36
+ @created_at = nil
37
+ @some_msg = {}
38
+ end
39
+ def appreq
40
+ self
41
+ end
42
+
43
+ def podnix_rest
44
+ options = { :email => Megam::Config[:email], :api_key => Megam::Config[:api_key]}
45
+ Podnix::API.new(options)
46
+ end
47
+
48
+ def id(arg=nil)
49
+ if arg != nil
50
+ @id = arg
51
+ else
52
+ @id
53
+ end
54
+ end
55
+
56
+ def req_type(arg=nil)
57
+ if arg != nil
58
+ @req_type = arg
59
+ else
60
+ @req_type
61
+ end
62
+ end
63
+
64
+ def appdefns_id(arg=nil)
65
+ if arg != nil
66
+ @appdefns_id = arg
67
+ else
68
+ @appdefns_id
69
+ end
70
+ end
71
+
72
+ def node_name(arg=nil)
73
+ if arg != nil
74
+ @node_name = arg
75
+ else
76
+ @node_name
77
+ end
78
+ end
79
+
80
+ def lc_apply(arg=nil)
81
+ if arg != nil
82
+ @lc_apply = arg
83
+ else
84
+ @lc_apply
85
+ end
86
+ end
87
+
88
+ def lc_additional(arg=nil)
89
+ if arg != nil
90
+ @lc_additional = arg
91
+ else
92
+ @lc_additional
93
+ end
94
+ end
95
+
96
+ def lc_when(arg=nil)
97
+ if arg != nil
98
+ @lc_when = arg
99
+ else
100
+ @lc_when
101
+ end
102
+ end
103
+
104
+ def created_at(arg=nil)
105
+ if arg != nil
106
+ @created_at = arg
107
+ else
108
+ @created_at
109
+ end
110
+ end
111
+ def some_msg(arg=nil)
112
+ if arg != nil
113
+ @some_msg = arg
114
+ else
115
+ @some_msg
116
+ end
117
+ end
118
+
119
+ def error?
120
+ crocked = true if (some_msg.has_key?(:msg_type) && some_msg[:msg_type] == "error")
121
+ end
122
+
123
+ # Transform the ruby obj -> to a Hash
124
+ def to_hash
125
+ index_hash = Hash.new
126
+ index_hash["json_claz"] = self.class.name
127
+ index_hash["id"] = id
128
+ index_hash["req_type"] = req_type
129
+ index_hash["appdefns_id"] = appdefns_id
130
+ index_hash["node_name"] = node_name
131
+ index_hash["lc_apply"] = lc_apply
132
+ index_hash["lc_additional"] = lc_additional
133
+ index_hash["lc_when"] = lc_when
134
+ index_hash["created_at"] = created_at
135
+ index_hash["some_msg"] = some_msg
136
+ index_hash
137
+ end
138
+
139
+ # Serialize this object as a hash: called from JsonCompat.
140
+ # Verify if this called from JsonCompat during testing.
141
+ def to_json(*a)
142
+ for_json.to_json(*a)
143
+ end
144
+
145
+ def for_json
146
+ result = {
147
+ "id" => id,
148
+ "req_type" => req_type,
149
+ "appdefns_id" => appdefns_id,
150
+ "node_name" => node_name,
151
+ "lc_apply" => lc_apply,
152
+ "lc_additional" => lc_additional,
153
+ "lc_when" => lc_when,
154
+ "created_at" => created_at
155
+ }
156
+ result
157
+ end
158
+
159
+
160
+ # Create a Megam::Node from NodeResult-JSON
161
+ #
162
+ #[{
163
+ #"id":"NOD362212018897289216",
164
+ #"accounts_id":"ACT362211962353876992",
165
+ #"json_claz":"Megam::Node",
166
+ #"request":{
167
+ #"req_id":"NOD362212018897289216",
168
+ #"command":"commands"
169
+ #},
170
+ #"predefs":{
171
+ #"name":"",
172
+ #"scm":"",
173
+ #"war":"",
174
+ #"db":"",
175
+ #"queue":""
176
+ #}
177
+ #}]
178
+ #
179
+ def self.json_create(o)
180
+ appreq = new
181
+ appreq.id(o["id"]) if o.has_key?("id")
182
+ appreq.req_type(o["req_type"]) if o.has_key?("req_type")
183
+ appreq.appdefns_id(o["appdefns_id"]) if o.has_key?("appdefns_id")
184
+ appreq.node_name(o["node_name"]) if o.has_key?("node_name")
185
+ appreq.lc_apply(o["lc_apply"]) if o.has_key?("lc_apply")
186
+ appreq.lc_additional(o["lc_additional"]) if o.has_key?("lc_additional")
187
+ appreq.lc_when(o["lc_when"]) if o.has_key?("lc_when")
188
+ appreq.created_at(o["created_at"]) if o.has_key?("created_at")
189
+
190
+ appreq.some_msg[:code] = o["code"] if o.has_key?("code")
191
+ appreq.some_msg[:msg_type] = o["msg_type"] if o.has_key?("msg_type")
192
+ appreq.some_msg[:msg]= o["msg"] if o.has_key?("msg")
193
+ appreq.some_msg[:links] = o["links"] if o.has_key?("links")
194
+
195
+ appreq
196
+ end
197
+
198
+ def self.from_hash(o)
199
+ appreq = self.new()
200
+ appreq.from_hash(o)
201
+ appreq
202
+ end
203
+
204
+ def from_hash(o)
205
+ @id = o["id"] if o.has_key?("id")
206
+ @req_type = o["req_type"] if o.has_key?("req_type")
207
+ @appdefns_id = o["appdefns_id"] if o.has_key?("appdefns_id")
208
+ @node_name = o["node_name"] if o.has_key?("node_name")
209
+ @lc_apply = o["lc_apply"] if o.has_key?("lc_apply")
210
+ @lc_additional = o["lc_additional"] if o.has_key?("lc_additional")
211
+ @lc_when = o["lc_when"] if o.has_key?("lc_when")
212
+ @created_at = o["created_at"] if o.has_key?("created_at")
213
+ self
214
+ end
215
+
216
+ def self.create(o)
217
+ acct = from_hash(o)
218
+ acct.create
219
+ end
220
+
221
+ # Create the node via the REST API
222
+ def create
223
+ podnix_rest.post_appreq(to_hash)
224
+ end
225
+
226
+ # Load a account by email_p
227
+ def self.list(node_name)
228
+ appreq = self.new()
229
+ appreq.podnix_rest.get_appreq(node_name)
230
+ #self
231
+ end
232
+
233
+ def to_s
234
+ Podnix::Stuff.styled_hash(to_hash)
235
+ #"---> Megam::Account:[error=#{error?}]\n"+
236
+ end
237
+
238
+ end
239
+ end
@@ -0,0 +1,148 @@
1
+ # Copyright:: Copyright (c) 2012, 2013 Megam Systems
2
+ # License:: Apache License, Version 2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ module Podnix
17
+ class ImagesCollection
18
+ include Enumerable
19
+
20
+
21
+ attr_reader :iterator
22
+ def initialize
23
+ @appreqs = Array.new
24
+ @appreqs_by_name = Hash.new
25
+ @insert_after_idx = nil
26
+ end
27
+
28
+ def all_appreqs
29
+ @appreqs
30
+ end
31
+
32
+ def [](index)
33
+ @appreqs[index]
34
+ end
35
+
36
+ def []=(index, arg)
37
+ is_megam_appreq(arg)
38
+ @appreqs[index] = arg
39
+ @appreqs_by_name[arg.id] = index
40
+ end
41
+
42
+ def <<(*args)
43
+ args.flatten.each do |a|
44
+ is_megam_appreq(a)
45
+ @appreqs << a
46
+ @appreqs_by_name[a.id] = @appreqs.length - 1
47
+ end
48
+ self
49
+ end
50
+
51
+ # 'push' is an alias method to <<
52
+ alias_method :push, :<<
53
+
54
+ def insert(appreq)
55
+ is_megam_appreq(appreq)
56
+ if @insert_after_idx
57
+ # in the middle of executing a run, so any Appreqss inserted now should
58
+ # be placed after the most recent addition done by the currently executing
59
+ # appreqs
60
+ @appreqs.insert(@insert_after_idx + 1, appreq)
61
+ # update name -> location mappings and register new appreqs
62
+ @appreqs_by_name.each_key do |key|
63
+ @appreqs_by_name[key] += 1 if @appreqs_by_name[key] > @insert_after_idx
64
+ end
65
+ @appreqs_by_name[appreq.id] = @insert_after_idx + 1
66
+ @insert_after_idx += 1
67
+ else
68
+ @appreqs << appreq
69
+ @appreqs_by_name[appreq.id] = @appreqs.length - 1
70
+ end
71
+ end
72
+
73
+ def each
74
+ @appreqs.each do |appreq|
75
+ yield appreq
76
+ end
77
+ end
78
+
79
+ def each_index
80
+ @appreqs.each_index do |i|
81
+ yield i
82
+ end
83
+ end
84
+
85
+ def empty?
86
+ @appreqs.empty?
87
+ end
88
+
89
+ def lookup(appreq)
90
+ lookup_by = nil
91
+ if appreq.kind_of?(Megam::AppRequest)
92
+ lookup_by = appreq.id
93
+ elsif appreq.kind_of?(String)
94
+ lookup_by = appreq
95
+ else
96
+ raise ArgumentError, "Must pass a Megam::Appreqs or String to lookup"
97
+ end
98
+ res = @appreqs_by_name[lookup_by]
99
+ unless res
100
+ raise ArgumentError, "Cannot find a appreq matching #{lookup_by} (did you define it first?)"
101
+ end
102
+ @appreqs[res]
103
+ end
104
+
105
+ # Transform the ruby obj -> to a Hash
106
+ def to_hash
107
+ index_hash = Hash.new
108
+ self.each do |appreq|
109
+ index_hash[appreq.id] = appreq.to_s
110
+ end
111
+ index_hash
112
+ end
113
+
114
+ # Serialize this object as a hash: called from JsonCompat.
115
+ # Verify if this called from JsonCompat during testing.
116
+ def to_json(*a)
117
+ for_json.to_json(*a)
118
+ end
119
+
120
+
121
+ def self.json_create(o)
122
+ collection = self.new()
123
+ o["results"].each do |appreqs_list|
124
+ appreqs_array = appreqs_list.kind_of?(Array) ? appreqs_list : [ appreqs_list ]
125
+ appreqs_array.each do |appreq|
126
+ collection.insert(appreq)
127
+ end
128
+ end
129
+ collection
130
+ end
131
+
132
+ private
133
+
134
+
135
+
136
+ def is_megam_appreq(arg)
137
+ unless arg.kind_of?(Megam::AppRequest)
138
+ raise ArgumentError, "Members must be Megam::Appreq's"
139
+ end
140
+ true
141
+ end
142
+
143
+ def to_s
144
+ Podnix::Stuff.styled_hash(to_hash)
145
+ end
146
+
147
+ end
148
+ end
@@ -0,0 +1,162 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+
14
+ # Wrapper class for interacting with JSON.
15
+
16
+ require 'yajl/json_gem'
17
+ require 'yajl'
18
+
19
+ module Podnix
20
+ class JSONCompat
21
+ JSON_MAX_NESTING = 1000
22
+
23
+ JSON_CLAZ = "json_claz".freeze
24
+
25
+ PODNIX_ERROR = "Podnix::Error".freeze
26
+ PODNIX_IMAGES = "Podnix::Image".freeze
27
+ PODNIX_IMAGESCOLLECTION = "Podnix::NodeCollection".freeze
28
+ PODNIX_SERVERS = "Megam::Predef".freeze
29
+ PODNIX_SERVERSCOLLECTION = "Megam::PredefCollection".freeze
30
+
31
+ class <<self
32
+ # Increase the max nesting for JSON, which defaults
33
+ # to 19, and isn't enough for some (for example, a Node within a Node)
34
+ # structures.
35
+ def opts_add_max_nesting(opts)
36
+ if opts.nil? || !opts.has_key?(:max_nesting)
37
+ opts = opts.nil? ? Hash.new : opts.clone
38
+ opts[:max_nesting] = JSON_MAX_NESTING
39
+ end
40
+ opts
41
+ end
42
+
43
+ # Just call the JSON gem's parse method with a modified :max_nesting field
44
+ def from_json(source, opts = {})
45
+ obj = ::Yajl::Parser.parse(source)
46
+ # JSON gem requires top level object to be a Hash or Array (otherwise
47
+ # you get the "must contain two octets" error). Yajl doesn't impose the
48
+ # same limitation. For compatibility, we re-impose this condition.
49
+ unless obj.kind_of?(Hash) or obj.kind_of?(Array)
50
+ raise JSON::ParserError, "Top level JSON object must be a Hash or Array. (actual: #{obj.class})"
51
+ end
52
+
53
+ # The old default in the json gem (which we are mimicing because we
54
+ # sadly rely on this misfeature) is to "create additions" i.e., convert
55
+ # JSON objects into ruby objects. Explicit :create_additions => false
56
+ # is required to turn it off.
57
+ if opts[:create_additions].nil? || opts[:create_additions]
58
+ map_to_rb_obj(obj)
59
+ else
60
+ obj
61
+ end
62
+ end
63
+
64
+ # Look at an object that's a basic type (from json parse) and convert it
65
+ # to an instance of Megam classes if desired.
66
+ def map_to_rb_obj(json_obj)
67
+ case json_obj
68
+ when Hash
69
+ mapped_hash = map_hash_to_rb_obj(json_obj)
70
+ if json_obj.has_key?(JSON_CLAZ) && (class_to_inflate = class_for_json_class(json_obj[JSON_CLAZ]))
71
+ class_to_inflate.json_create(mapped_hash)
72
+ else
73
+ mapped_hash
74
+ end
75
+ when Array
76
+ json_obj.map {|e| map_to_rb_obj(e) }
77
+ else
78
+ json_obj
79
+ end
80
+ end
81
+
82
+ def map_hash_to_rb_obj(json_hash)
83
+ json_hash.each do |key, value|
84
+ json_hash[key] = map_to_rb_obj(value)
85
+ end
86
+ json_hash
87
+ end
88
+
89
+ def to_json(obj, opts = nil)
90
+ obj.to_json(opts_add_max_nesting(opts))
91
+ end
92
+
93
+ def to_json_pretty(obj, opts = nil)
94
+ ::JSON.pretty_generate(obj, opts_add_max_nesting(opts))
95
+ end
96
+
97
+ # Map +JSON_CLAZ+ to a Class object. We use a +case+ instead of a Hash
98
+ # assigned to a constant because otherwise this file could not be loaded
99
+ # until all the constants were defined, which means you'd have to load
100
+ # the world to get json.
101
+ def class_for_json_class(json_class)
102
+ case json_class
103
+ when MEGAM_ERROR
104
+ Megam::Error
105
+ when MEGAM_AUTH
106
+ Megam::Auth
107
+ when MEGAM_ACCOUNT
108
+ Megam::Account
109
+ when MEGAM_NODE
110
+ Megam::Node
111
+ when MEGAM_APPDEFNS
112
+ Megam::Appdefns
113
+ when MEGAM_APPREQUEST
114
+ Megam::AppRequest
115
+ when MEGAM_BOLTREQUEST
116
+ Megam::BoltRequest
117
+ when MEGAM_BOLTDEFNS
118
+ Megam::Boltdefns
119
+ when MEGAM_NODECOLLECTION
120
+ Megam::NodeCollection
121
+ when MEGAM_APPDEFNSCOLLECTION
122
+ Megam::AppdefnsCollection
123
+ when MEGAM_APPREQUESTCOLLECTION
124
+ Megam::AppRequestCollection
125
+ when MEGAM_BOLTREQUESTCOLLECTION
126
+ Megam::BoltRequestCollection
127
+ when MEGAM_BOLTDEFNSCOLLECTION
128
+ Megam::BoltdefnsCollection
129
+ when MEGAM_REQUEST
130
+ Megam::Request
131
+ when MEGAM_REQUESTCOLLECTION
132
+ Megam::RequestCollection
133
+ when MEGAM_PREDEF
134
+ Megam::Predef
135
+ when MEGAM_PREDEFCOLLECTION
136
+ Megam::PredefCollection
137
+ when MEGAM_PREDEFCLOUD
138
+ Megam::PredefCloud
139
+ when MEGAM_PREDEFCLOUDCOLLECTION
140
+ Megam::PredefCloudCollection
141
+ when MEGAM_CLOUDTOOL
142
+ Megam::CloudTool
143
+ when MEGAM_CLOUDTOOLCOLLECTION
144
+ Megam::CloudToolCollection
145
+ when MEGAM_CLOUDTEMPLATE
146
+ Megam::CloudTemplate
147
+ when MEGAM_CLOUDTEMPLATECOLLECTION
148
+ Megam::CloudTemplateCollection
149
+ when MEGAM_CLOUDINSTRUCTION
150
+ Megam::CloudInstruction
151
+ when MEGAM_CLOUDINSTRUCTIONGROUP
152
+ Megam::CloudInstructionGroup
153
+ when MEGAM_CLOUDINSTRUCTIONCOLLECTION
154
+ Megam::CloudInstructionCollection
155
+ else
156
+ raise JSON::ParserError, "Unsupported `json_class` type '#{json_class}'"
157
+ end
158
+ end
159
+
160
+ end
161
+ end
162
+ end