collins_client 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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