collins_client 0.2.7

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,19 @@
1
+ require 'uri'
2
+
3
+ module Collins; module Api
4
+
5
+ module Admin
6
+
7
+ def repopulate_solr! wait_for_completion = true
8
+ parameters = {
9
+ :waitForCompletion => wait_for_completion
10
+ }
11
+ http_get("/api/admin/solr", parameters) do |response|
12
+ parse_response response, :expects => 200
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end; end
19
+
@@ -0,0 +1,184 @@
1
+ require 'uri'
2
+
3
+ module Collins; module Api
4
+
5
+ module Asset
6
+
7
+ def create! asset_or_tag, options = {}
8
+ asset = get_asset_or_tag asset_or_tag
9
+ parameters = {
10
+ :generate_ipmi => get_option(:generate_ipmi, options, false),
11
+ :status => get_option(:status, options, asset.status),
12
+ :type => get_option(:type, options, asset.type)
13
+ }
14
+ parameters = select_non_empty_parameters parameters
15
+ logger.debug("Creating asset #{asset.tag} with parameters #{parameters.inspect}")
16
+ http_put("/api/asset/#{asset.tag}", parameters) do |response|
17
+ parse_response response, :expects => 201, :as => :asset
18
+ end
19
+ end
20
+
21
+ def delete! asset_or_tag, options = {}
22
+ asset = get_asset_or_tag asset_or_tag
23
+ parameters = {
24
+ :reason => get_option(:reason, options, nil)
25
+ }
26
+ parameters = select_non_empty_parameters parameters
27
+ logger.debug("Deleting asset #{asset.tag} with parameters #{parameters.inspect}")
28
+ http_delete("/api/asset/#{asset.tag}", parameters, asset.location) do |response|
29
+ parse_response response, :expects => 200, :as => :status, :raise => strict?, :default => false
30
+ end
31
+ end
32
+
33
+ def exists? asset_or_tag, status = nil
34
+ begin
35
+ asset = get(asset_or_tag)
36
+ if asset && status && asset.status.downcase == status.downcase then
37
+ true
38
+ elsif asset && status.nil? then
39
+ true
40
+ else
41
+ false
42
+ end
43
+ rescue Collins::RequestError => e
44
+ if e.code.to_i == 404 then
45
+ false
46
+ else
47
+ # if strict? is true, should still return a boolean for exists?
48
+ logger.info("Exception getting asset: #{e.class} #{e}")
49
+ false
50
+ end
51
+ rescue Exception => e
52
+ if e.class.to_s == "WebMock::NetConnectNotAllowedError" then
53
+ raise e
54
+ end
55
+ # if strict? is true, should still return a boolean for exists?
56
+ logger.info("Exception getting asset: #{e.class} - #{e}")
57
+ false
58
+ end
59
+ end
60
+
61
+ def get asset_or_tag, options = {}
62
+ asset = get_asset_or_tag asset_or_tag
63
+ parameters = {
64
+ :location => get_option(:location, options, nil)
65
+ }
66
+ parameters = select_non_empty_parameters parameters
67
+ logger.debug("Getting asset #{asset.tag} with params #{parameters.inspect}")
68
+ http_get("/api/asset/#{asset.tag}", parameters, asset.location) do |response|
69
+ parse_response response, :as => :asset, :expects => 200, :raise => strict?, :default => false
70
+ end
71
+ end
72
+
73
+ # Find assets matching the specified criteria
74
+ #
75
+ # In general the options hash corresponds to asset key/value pairs. Reserved keys in the selector
76
+ # are treated with care. These keys are in {Collins::Asset::Find::DATE\_PARAMS} and in
77
+ # {Collins::Asset::Find::GENERAL\_PARAMS}. All other keys are assumed to be asset attributes.
78
+ # @param [Hash] options Query options
79
+ # @return [Array<Collins::Asset>] An array of assets matching the query
80
+ # @raise [UnexpectedResponseError] If the HTTP response code is not a 200
81
+ def find options = {}
82
+ solrquery = options.delete(:query)
83
+ if solrquery != nil then
84
+ return search solrquery, options[:size], options.sort
85
+ end
86
+ use_api_version "1.1"
87
+ query = asset_hash_to_find_query options
88
+ params = query.to_a.map do |param|
89
+ key, val = param
90
+ if val.is_a?(Array) then
91
+ val.map{|v| "#{key}=#{asset_escape_attribute(v)}"}.join("&")
92
+ else
93
+ "#{key}=#{asset_escape_attribute(val)}"
94
+ end
95
+ end.reject{|s| s.empty?}
96
+ logger.debug("Finding assets using params #{params.inspect}")
97
+ http_get("/api/assets", params) do |response|
98
+ parse_response response, :expects => 200, :as => :paginated do |json|
99
+ json.map { |j| Collins::Asset.from_json(j) }
100
+ end
101
+ end
102
+ end
103
+
104
+ def search query, size = 50, sort = "ASC", sort_field = "tag"
105
+ use_api_version "1.2"
106
+ if query.start_with? "\"" and query.end_with? "\"" then
107
+ query = query[1..-2]
108
+ end
109
+ params = {
110
+ :query => query,
111
+ :size => size,
112
+ :sort => sort,
113
+ :sort_field => sort_field
114
+ }
115
+ logger.debug("perform asset search using query #{query}")
116
+ http_get("/api/assets",params) do |response|
117
+ parse_response response, :expects => 200, :as => :paginated do |json|
118
+ json.map { |j| Collins::Asset.from_json(j) }
119
+ end
120
+ end
121
+ end
122
+
123
+ def find_similar asset_or_tag, size = 50, sort = "ASC", sort_type = "distance", only_unallocated = true
124
+ asset = get_asset_or_tag asset_or_tag
125
+ params = {
126
+ :size => size,
127
+ :sort => sort,
128
+ :sortType => sort_type,
129
+ :onlyUnallocated => only_unallocated
130
+ }
131
+ logger.debug("Finding similar assets for #{asset.tag}")
132
+ http_get("/api/asset/#{asset.tag}/similar", params) do |response|
133
+ parse_response response, :expects => 200, :as => :paginated do |json|
134
+ json.map { |j| Collins::Asset.from_json(j) }
135
+ end
136
+ end
137
+ end
138
+
139
+ private
140
+ def asset_escape_attribute value
141
+ URI.escape(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
142
+ end
143
+
144
+ def asset_hash_to_find_query opts = {}
145
+ options = opts.clone
146
+ hash = {:attribute => []}
147
+ okeys = options.keys
148
+ Collins::Asset::Find::DATE_PARAMS.each do |query_key|
149
+ okeys.each do |user_key|
150
+ if query_key.to_s.downcase == user_key.to_s.downcase then
151
+ hash[query_key.to_sym] = Collins::Asset.format_date_string(options.delete(user_key))
152
+ end
153
+ end
154
+ end
155
+ Collins::Asset::Find::GENERAL_PARAMS.each do |query_key|
156
+ okeys.each do |user_key|
157
+ if query_key.to_s.downcase == user_key.to_s.downcase then
158
+ hash[query_key.to_sym] = options.delete(user_key)
159
+ end
160
+ end
161
+ end
162
+ options.each do |k,v|
163
+ hash[:attribute] << "#{k};#{regex_to_string(v)}"
164
+ end
165
+ hash
166
+ end
167
+
168
+ def regex_to_string value
169
+ if is_regex? value then
170
+ rewrite_regex value
171
+ else
172
+ value
173
+ end
174
+ end
175
+ def is_regex? value
176
+ value.is_a?(Regexp)
177
+ end
178
+ def rewrite_regex value
179
+ value.inspect[1..-2] # turn /lkasd/ into lkasd
180
+ end
181
+
182
+ end
183
+
184
+ end; end
@@ -0,0 +1,85 @@
1
+ module Collins; module Api
2
+
3
+ module AssetState
4
+ def state_test; @state_test end
5
+ def state_test= v; @state_test = v end
6
+ module_function :state_test, :state_test=
7
+
8
+ def state_create! name, label, description, status = nil
9
+ name = validate_state_name name
10
+ parameters = {
11
+ :label => label,
12
+ :description => description,
13
+ :status => status
14
+ }
15
+ if not ::Collins::Api::AssetState.state_test then
16
+ parameters = select_non_empty_parameters parameters
17
+ end
18
+ logger.debug("Creating state with name #{name}")
19
+ http_put("/api/state/#{name}", parameters) do |r|
20
+ parse_response r, :expects => 201, :as => :status, :raise => strict?, :default => false
21
+ end
22
+ end
23
+ def state_delete! name
24
+ name = validate_state_name name
25
+ logger.debug("Deleting state with name #{name}")
26
+ http_delete("/api/state/#{name}") do |r|
27
+ parse_response r, :expects => 202, :as => :data, :raise => strict?, :default => 0 do |js|
28
+ js["DELETED"].to_s.to_i
29
+ end
30
+ end
31
+ end
32
+ def state_update! name, options = {}
33
+ name = validate_state_name name
34
+ parameters = {
35
+ :label => options[:label],
36
+ :description => options[:description],
37
+ :name => options[:name],
38
+ :status => options[:status]
39
+ }
40
+ if not ::Collins::Api::AssetState.state_test then
41
+ parameters = select_non_empty_parameters parameters
42
+ end
43
+ logger.debug("Updating state with name #{name} params #{parameters}")
44
+ http_post("/api/state/#{name}", parameters) do |r|
45
+ parse_response r, :expects => 200, :as => :status, :raise => strict?, :default => false
46
+ end
47
+ end
48
+ def state_get name
49
+ name = validate_state_name name
50
+ logger.debug("Fetching state with name #{name}")
51
+ http_get("/api/state/#{name}") do |r|
52
+ empty = ::Collins::AssetState.new({})
53
+ parse_response r, :expects => 200, :as => :data, :default => empty, :raise => false do |js|
54
+ ::Collins::AssetState.from_json(js)
55
+ end
56
+ end
57
+ end
58
+ def state_get_all
59
+ http_get("/api/states") do |r|
60
+ parse_response r, :expects => 200, :as => :data, :default => [], :raise => false do |js|
61
+ js.map do |state|
62
+ ::Collins::AssetState.from_json(state)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ private
69
+ def validate_state_name name
70
+ if ::Collins::Api::AssetState.state_test then
71
+ return name
72
+ end
73
+ name_opt = ::Collins::Option(name).map {|x| x.to_s.strip}.filter_not {|x| x.empty?}.filter {|x|
74
+ x.size > 1 && x.size <= 32
75
+ }
76
+ if name_opt.empty? then
77
+ raise ::Collins::ExpectationFailedError.new("name must be between 2 and 32 characters")
78
+ else
79
+ name_opt.get
80
+ end
81
+ end
82
+
83
+ end # end module AssetState
84
+
85
+ end; end
@@ -0,0 +1,76 @@
1
+ module Collins; module Api
2
+
3
+ module Attributes
4
+ def delete_attribute! asset_or_tag, attribute, group_id = nil
5
+ asset = get_asset_or_tag asset_or_tag
6
+ parameters = {
7
+ :groupId => group_id
8
+ }
9
+ parameters = select_non_empty_parameters parameters
10
+ logger.debug("Deleting attribute #{attribute} on #{asset.tag} with params #{parameters.inspect}")
11
+ http_delete("/api/asset/#{asset.tag}/attribute/#{attribute}", parameters, asset.location) do |response|
12
+ parse_response response, :expects => 202, :as => :status, :raise => strict?, :default => false
13
+ end
14
+ end
15
+ def set_attribute! asset_or_tag, key, value, group_id = nil
16
+ asset = get_asset_or_tag asset_or_tag
17
+ parameters = {
18
+ :attribute => "#{key};#{value}",
19
+ :groupId => group_id
20
+ }
21
+ parameters = select_non_empty_parameters parameters
22
+ logger.debug("Setting attribute #{key} to #{value} on #{asset.tag}")
23
+ http_post("/api/asset/#{asset.tag}", parameters, asset.location) do |response|
24
+ parse_response response, :expects => 200, :as => :status, :raise => strict?, :default => false
25
+ end
26
+ end
27
+
28
+ # Set the status of an asset
29
+ # @overload set_status!(asset_or_tag, status, reason = 'Set via API', state = nil)
30
+ # Set the status, reason and optionally state of asset
31
+ # @param [String,Collins::Asset] asset_or_tag The asset or tag
32
+ # @param [String] status the status of the asset
33
+ # @param [String] reason the reason for the change
34
+ # @param [String] state the asset state
35
+ # @overload set_status!(asset_or_tag, hash)
36
+ # Set the status, reason, and optionally state of asset
37
+ # @param [String,Collins::Asset] asset_or_tag The asset or tag
38
+ # @param [Hash] hash the options to set
39
+ # @option hash [String] :status The asset status
40
+ # @option hash [String] :reason The reason for the change
41
+ # @option hash [String] :state The asset state
42
+ # @return Boolean
43
+ def set_status! asset_or_tag, *varargs
44
+ status = state = nil
45
+ reason = 'Set via ruby client'
46
+ asset = get_asset_or_tag asset_or_tag
47
+ if varargs.size == 0 then
48
+ raise ::Collins::ExpectationFailedError.new("set_status! requires a status")
49
+ elsif varargs.size == 1 and varargs[0].is_a?(Hash) then
50
+ hash = symbolize_hash(varargs[0], :downcase => true)
51
+ status = hash[:status]
52
+ reason = hash.fetch(:reason, reason)
53
+ state = hash[:state]
54
+ elsif varargs.size == 1 and (varargs[0].is_a?(String) or varargs[0].is_a?(Symbol)) then
55
+ status = varargs[0].to_s
56
+ elsif varargs.size > 1 then
57
+ status = varargs[0]
58
+ reason = varargs[1]
59
+ state = varargs[2] if varargs.size > 2
60
+ else
61
+ raise ::Collins::ExpectationFailedError.new("set_status! called with invalid parameters")
62
+ end
63
+ parameters = {
64
+ :status => status,
65
+ :reason => reason,
66
+ :state => state
67
+ }
68
+ parameters = select_non_empty_parameters parameters
69
+ logger.debug("Setting status to #{status} on #{asset.tag}")
70
+ http_post("/api/asset/#{asset.tag}/status", parameters, asset.location) do |response|
71
+ parse_response response, :expects => 200, :as => :status, :raise => strict?, :default => false
72
+ end
73
+ end
74
+ end # module Attributes
75
+
76
+ end; end
@@ -0,0 +1,87 @@
1
+ require 'collins/address'
2
+
3
+ module Collins; module Api
4
+
5
+ module IpAddress
6
+ def ipaddress_allocate! asset_or_tag, address_pool, count = 1
7
+ asset = get_asset_or_tag asset_or_tag
8
+ logger.debug("Allocating #{count} addresses for #{asset.tag} in pool #{address_pool}")
9
+ parameters = {
10
+ :count => count,
11
+ :pool => address_pool
12
+ }
13
+ http_put("/api/asset/#{asset.tag}/address", parameters, asset.location) do |response|
14
+ parse_response response, :expects => 201, :default => [] do |json|
15
+ Collins::Address.from_json(json["data"]["ADDRESSES"])
16
+ end
17
+ end
18
+ end
19
+
20
+ def ipaddress_update! asset_or_tag, old_address = nil, options = {}
21
+ asset = get_asset_or_tag asset_or_tag
22
+ logger.debug("Updating IP address for #{asset.tag}")
23
+ parameters = {
24
+ :old_address => old_address,
25
+ :address => get_option(:address, options, nil),
26
+ :gateway => get_option(:gateway, options, nil),
27
+ :netmask => get_option(:netmask, options, nil),
28
+ :pool => get_option(:pool, options, nil)
29
+ }
30
+ parameters = select_non_empty_parameters parameters
31
+ http_post("/api/asset/#{asset.tag}/address", parameters, asset.location) do |response|
32
+ parse_response response, :expects => [200,201], :default => false, :raise => strict?
33
+ end
34
+ end
35
+
36
+ def ipaddress_delete! asset_or_tag, pool = nil
37
+ asset = get_asset_or_tag asset_or_tag
38
+ logger.debug("Deleting addresses for asset #{asset.tag} in pool #{pool}")
39
+ parameters = {
40
+ :pool => pool
41
+ }
42
+ parameters = select_non_empty_parameters parameters
43
+ http_delete("/api/asset/#{asset.tag}/addresses", parameters, asset.location) do |response|
44
+ parse_response response, :expects => 200, :default => false, :raise => strict? do |json|
45
+ json["data"]["DELETED"].to_s.to_i
46
+ end
47
+ end
48
+ end
49
+
50
+ def ipaddress_pools show_all = true
51
+ logger.debug("Finding IP address pools")
52
+ http_get("/api/address/pools", {:all => show_all}) do |response|
53
+ parse_response response, :expects => 200, :default => [], :raise => strict? do |json|
54
+ json["data"]["POOLS"]
55
+ end
56
+ end
57
+ end
58
+
59
+ def addresses_for_asset asset_or_tag
60
+ asset = get_asset_or_tag asset_or_tag
61
+ logger.debug("Getting IP addresses for asset #{asset.tag}")
62
+ http_get("/api/asset/#{asset.tag}/addresses", {}, asset.location) do |response|
63
+ parse_response response, :expects => 200, :default => [], :raise => strict? do |json|
64
+ Collins::Address.from_json(json["data"]["ADDRESSES"])
65
+ end
66
+ end
67
+ end
68
+
69
+ def asset_at_address address
70
+ logger.debug("Finding asset at address #{address}")
71
+ http_get("/api/asset/with/address/#{address}") do |response|
72
+ parse_response response, :expects => 200, :default => nil, :raise => strict?, :as => :bare_asset
73
+ end
74
+ end
75
+
76
+ def assets_in_pool pool
77
+ logger.debug("Finding assets in pool #{pool}")
78
+ http_get("/api/assets/with/addresses/in/#{pool}") do |response|
79
+ parse_response response, :expects => 200, :default => [], :raise => strict? do |json|
80
+ json["data"]["ASSETS"].map{|j| Collins::Asset.from_json(j, true)}
81
+ end
82
+ end
83
+ end
84
+
85
+ end # module IpAddress
86
+
87
+ end; end