rundeck-ruby 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c0b2b8b341f0873b0ca2a5f5d38f75dc2ba99d4e
4
- data.tar.gz: c03843110188e81e43939b5fe4b737c17c98b095
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTI0YWU4MTIwODllNDgwN2ZkZDgxY2E1NDcwNDk4OWZlMWZmNmM0OQ==
5
+ data.tar.gz: !binary |-
6
+ NTJiOGRlMWRhNTNiM2JiNGExOGU2YTYwZTAzMDk3NzdmZTBhMTE0Yg==
5
7
  SHA512:
6
- metadata.gz: 92f5845c06eb9fde084af309ce89ca4a7aee5386c2f09848e86afa72df74e7ca7a26505c77a5651b9b3a107281bfe6bc9a91713e6da809fccd2fa758f39efaa9
7
- data.tar.gz: 789262397ce473570fca1f4821bbcfe581a83295d403771ec3bc432e9573a5bcdb2d00b69c7c0d6a8a3bec879f2962cbd98f16597998912a0a1dfdb900762a81
8
+ metadata.gz: !binary |-
9
+ OTUzNmUyY2ExYjlhMTI5ZmRkZWQzNTY3ZTY3NmRlYTdiMGNkOTYzMjExNzM0
10
+ MDAyZGIzODY2ZWE2NjFjYWI4M2Q2ZDAwZmFhMDYyMGY1MzkyMzIzMDA4MGVh
11
+ M2M4Yjg1YzQ5MDE5ZWMwNDcxNTAwNDA4YjcxZmJhYmMxNjcwNGQ=
12
+ data.tar.gz: !binary |-
13
+ MmI1MTRjZTM1ODQwMjZhZDIzYjczNWExZTc1ZWM2ZTZkYmE3Yjk3NTk5ODVk
14
+ NDY5N2IwMTI1Y2RhMDQ3MmI0OWEwNWUzMGI2MmIzNTFjOTQ5MTQ5MjE5NjYz
15
+ MGMyNmY4ZDk4OWQ2YzZkNzFhMzBhOGI4OTExZmMyNGVkMTc2YWQ=
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Gem Version](https://badge.fury.io/rb/rundeck-ruby.svg)](http://badge.fury.io/rb/rundeck-ruby)
2
+
1
3
  # Rundeck-ruby
2
4
 
3
5
  Like the name says, these are ruby bindings for the rundeck API
@@ -154,6 +156,8 @@ hostnames to log entries, which will be self-explanatory
154
156
 
155
157
  ## Contributing
156
158
 
159
+ [![Code Climate](https://codeclimate.com/github/jonp/rundeck-ruby.png)](https://codeclimate.com/github/jonp/rundeck-ruby)
160
+
157
161
  The usual boilerplate:
158
162
 
159
163
  1. Fork it
@@ -180,4 +184,6 @@ rundeck exec -tail ...the other parameters...
180
184
  ```
181
185
 
182
186
  * Running ad-hoc commands, both in irb and with the binstub
183
-
187
+ * Unit tests. While normally more of a TDDer than most, I find writing
188
+ tests for API wrappers tedious at best. It should probably be done,
189
+ though.
@@ -1,4 +1,22 @@
1
1
  module Rundeck
2
+ class ExecutionTimeout < StandardError
3
+ def initialize(execution)
4
+ super("Timed out while waiting for execution #{execution.url} to complete")
5
+ end
6
+ end
7
+
8
+ class ExecutionFailure < StandardError
9
+ def initialize(execution)
10
+ super("Execution #{execution.url} failed")
11
+ end
12
+ end
13
+
14
+ class APIFailure < StandardError
15
+ def initialize(call, status)
16
+ super("The call to #{call} failed with result #{result}")
17
+ end
18
+ end
19
+
2
20
  class Execution
3
21
  def self.from_hash(session, hash)
4
22
  job = Job.from_hash(session, hash['job'])
@@ -30,7 +48,7 @@ module Rundeck
30
48
  end
31
49
 
32
50
  def self.where(project)
33
- qb = QueryBuilder.new
51
+ qb = SearchQueryBuilder.new
34
52
  yield qb if block_given?
35
53
 
36
54
  endpoint = "api/5/executions?project=#{project.name}#{qb.query}"
@@ -41,9 +59,10 @@ module Rundeck
41
59
  end
42
60
 
43
61
  def output
44
- ret = session.get("api/9/execution/#{id}/output")
62
+ path = "api/9/execution/#{id}/output"
63
+ ret = session.get(path)
45
64
  result = ret['result']
46
- raise "API call not successful" unless result && result['success']=='true'
65
+ raise APIFailure.new(path, result) unless result && result['success']=='true'
47
66
 
48
67
  #sort the output by node
49
68
  ret = result['output'].slice(*%w(id completed hasFailedNodes))
@@ -51,17 +70,36 @@ module Rundeck
51
70
  ret
52
71
  end
53
72
 
54
- class QueryBuilder
73
+ def wait_for_complete(poll_interval, timeout)
74
+ Timeout.timeout(timeout) do
75
+ while (cur = self.class.find(session, id)).status != :succeeded
76
+ raise ExecutionFailure.new(self) if cur.status == :failed
77
+ sleep(poll_interval)
78
+ end
79
+ end
80
+ rescue Timeout::Error
81
+ raise ExecutionTimeout.new(self)
82
+ end
83
+
84
+ class SearchQueryBuilder
55
85
  attr_accessor :status, :max, :offset
56
86
 
87
+ class ValidationError < StandardError
88
+ def initialize(field, value, message=nil)
89
+ msg = "Invalid #{field}: #{value}"
90
+ msg += message unless message==nil
91
+ super(msg)
92
+ end
93
+ end
94
+
57
95
  def self.valid_statuses
58
96
  %w(succeeded failed aborted running) << nil
59
97
  end
60
98
 
61
99
  def validate
62
- raise "Invalid requested status: #{status}" unless status.nil? || elf.class.valid_statuses.include?(status.to_s)
63
- raise "Invalid offset: #{offset}" unless offset.nil? || offset.to_i >= 0
64
- raise "Invalid max: #{max}" unless max.nil? || max.to_i >= 0
100
+ raise ValidationError.new("requested status", status) unless status.nil? || self.class.valid_statuses.include?(status.to_s)
101
+ raise ValidationError.new("offset", offset) unless offset.nil? || offset.to_i >= 0
102
+ raise ValidationError.new("max", max) unless max.nil? || max.to_i >= 0
65
103
  end
66
104
 
67
105
  def query
@@ -46,10 +46,18 @@ module Rundeck
46
46
  Execution::QueryBuilder.valid_statuses
47
47
  end
48
48
 
49
+ class ValidationError < StandardError
50
+ def initialize(field, value, message=nil)
51
+ msg = "Invalid #{field}: #{value}"
52
+ msg += message unless message==nil
53
+ super(msg)
54
+ end
55
+ end
56
+
49
57
  def validate
50
- raise "Invalid requested status: #{status}" unless status.nil? || self.class.valid_statuses.include?(status.to_s)
51
- raise "Invalid offset" unless offset.nil? || offset.to_i >= 0
52
- raise "Invalid max" unless max.nil? || max.to_i >= 0
58
+ raise ValidationError.new("status", status) unless status.nil? || self.class.valid_statuses.include?(status.to_s)
59
+ raise ValidationError.new("offset", offset) unless offset.nil? || offset.to_i >= 0
60
+ raise ValidationError.new("max", max) unless max.nil? || max.to_i >= 0
53
61
  end
54
62
 
55
63
  def query
@@ -26,5 +26,55 @@ module Rundeck
26
26
  def job(id)
27
27
  jobs.first{|j| j.id == id}
28
28
  end
29
+
30
+ def resources
31
+ qb = ResourceQueryBuilder.new
32
+
33
+ yield qb if block_given?
34
+
35
+ endpoint = "api/3/resources?project=#{name}&#{qb.query}"
36
+ pp endpoint
37
+
38
+ session.get(endpoint, 'project', 'node')
39
+ end
40
+
41
+ def resource(resource_name)
42
+ session.get("api/1/resource/#{resource_name}?project=#{name}", 'project', 'node')
43
+ end
44
+
45
+ class ResourceQueryBuilder
46
+ def self.fields
47
+ [:name, :hostname, :tags, :os_arch, :os_family, :os_name, :os_version]
48
+ end
49
+
50
+ def self.exclude_name(f)
51
+ "exclude_#{f}".to_sym
52
+ end
53
+
54
+ attr_accessor :precedence
55
+
56
+ fields.each do |f|
57
+ attr_accessor f, exclude_name(f)
58
+ end
59
+
60
+ def clause(field)
61
+ val = send(field)
62
+ return nil unless val
63
+ name = field.to_s.gsub('_', '-')
64
+ "#{name}=#{val}"
65
+ end
66
+
67
+ def query
68
+ clauses = self.class.fields.map do |f|
69
+ [
70
+ clause(f),
71
+ clause(self.class.exclude_name(f))
72
+ ]
73
+ end
74
+
75
+ clauses << "exclude-precedence=#{precedence==:exclude ? true : false}" if precedence
76
+ clauses.flatten.compact.join('&')
77
+ end
78
+ end
29
79
  end
30
80
  end
@@ -1,3 +1,3 @@
1
1
  module Rundeck
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
 
28
28
  spec.add_development_dependency "bundler", "~> 1.3"
29
29
  spec.add_development_dependency "rake", "~> 10.0"
30
+ spec.add_development_dependency "pry"
30
31
  end
metadata CHANGED
@@ -1,113 +1,127 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rundeck-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Phillips
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2014-04-26 00:00:00.000000000 Z
11
+ date: 2015-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
15
- version_requirements: !ruby/object:Gem::Requirement
15
+ requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.6'
20
- requirement: !ruby/object:Gem::Requirement
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
21
23
  requirements:
22
24
  - - ~>
23
25
  - !ruby/object:Gem::Version
24
26
  version: '1.6'
25
- prerelease: false
26
- type: :runtime
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: json
29
- version_requirements: !ruby/object:Gem::Requirement
29
+ requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.8'
34
- requirement: !ruby/object:Gem::Requirement
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
35
37
  requirements:
36
38
  - - ~>
37
39
  - !ruby/object:Gem::Version
38
40
  version: '1.8'
39
- prerelease: false
40
- type: :runtime
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
- version_requirements: !ruby/object:Gem::Requirement
43
+ requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ~>
46
46
  - !ruby/object:Gem::Version
47
47
  version: '3.0'
48
- requirement: !ruby/object:Gem::Requirement
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
49
51
  requirements:
50
52
  - - ~>
51
53
  - !ruby/object:Gem::Version
52
54
  version: '3.0'
53
- prerelease: false
54
- type: :runtime
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: i18n
57
- version_requirements: !ruby/object:Gem::Requirement
57
+ requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0.6'
62
- requirement: !ruby/object:Gem::Requirement
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
63
65
  requirements:
64
66
  - - ~>
65
67
  - !ruby/object:Gem::Version
66
68
  version: '0.6'
67
- prerelease: false
68
- type: :runtime
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: naught
71
- version_requirements: !ruby/object:Gem::Requirement
71
+ requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ~>
74
74
  - !ruby/object:Gem::Version
75
75
  version: '1.0'
76
- requirement: !ruby/object:Gem::Requirement
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
77
79
  requirements:
78
80
  - - ~>
79
81
  - !ruby/object:Gem::Version
80
82
  version: '1.0'
81
- prerelease: false
82
- type: :runtime
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: bundler
85
- version_requirements: !ruby/object:Gem::Requirement
85
+ requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ~>
88
88
  - !ruby/object:Gem::Version
89
89
  version: '1.3'
90
- requirement: !ruby/object:Gem::Requirement
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
91
93
  requirements:
92
94
  - - ~>
93
95
  - !ruby/object:Gem::Version
94
96
  version: '1.3'
95
- prerelease: false
96
- type: :development
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rake
99
- version_requirements: !ruby/object:Gem::Requirement
99
+ requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ~>
102
102
  - !ruby/object:Gem::Version
103
103
  version: '10.0'
104
- requirement: !ruby/object:Gem::Requirement
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
105
107
  requirements:
106
108
  - - ~>
107
109
  - !ruby/object:Gem::Version
108
110
  version: '10.0'
109
- prerelease: false
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
110
118
  type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Ruby client for Rundeck API
112
126
  email:
113
127
  - jphillips@biaprotect.com
@@ -134,24 +148,24 @@ homepage: https://github.com/jonp/rundeck-ruby
134
148
  licenses:
135
149
  - MIT
136
150
  metadata: {}
137
- post_install_message:
151
+ post_install_message:
138
152
  rdoc_options: []
139
153
  require_paths:
140
154
  - lib
141
155
  required_ruby_version: !ruby/object:Gem::Requirement
142
156
  requirements:
143
- - - '>='
157
+ - - ! '>='
144
158
  - !ruby/object:Gem::Version
145
159
  version: '0'
146
160
  required_rubygems_version: !ruby/object:Gem::Requirement
147
161
  requirements:
148
- - - '>='
162
+ - - ! '>='
149
163
  - !ruby/object:Gem::Version
150
164
  version: '0'
151
165
  requirements: []
152
- rubyforge_project:
153
- rubygems_version: 2.2.2
154
- signing_key:
166
+ rubyforge_project:
167
+ rubygems_version: 2.4.2
168
+ signing_key:
155
169
  specification_version: 4
156
170
  summary: For talking to Rundeck
157
171
  test_files: []