rally_api 0.9.17.pre → 0.9.18
Sign up to get free protection for your applications and to get access to all the features.
- data/{README.rdoc → README.md} +26 -17
- data/lib/rally_api/rally_json_connection.rb +1 -59
- data/lib/rally_api/rally_object.rb +7 -2
- data/lib/rally_api/rally_rest_json.rb +13 -20
- data/lib/rally_api/version.rb +1 -1
- metadata +14 -25
data/{README.rdoc → README.md}
RENAMED
@@ -1,16 +1,31 @@
|
|
1
|
-
|
1
|
+
## License
|
2
2
|
|
3
|
-
|
3
|
+
Copyright (c) Rally Software Development Corp. 2013 Distributed under the MIT License.
|
4
|
+
|
5
|
+
## Warranty
|
6
|
+
|
7
|
+
The Ruby Toolkit for Rally REST API is available on an as-is basis.
|
8
|
+
|
9
|
+
## Support
|
10
|
+
|
11
|
+
Rally Software does not actively maintain this toolkit. If you have a question or problem, we recommend posting it to Stack Overflow: http://stackoverflow.com/questions/ask?tags=rally
|
12
|
+
|
13
|
+
## Introduction
|
14
|
+
|
15
|
+
RallyAPI (rally_api) -- a wrapper for Rally's REST Web Services API
|
16
|
+
|
17
|
+
[![Stories in Ready](http://badge.waffle.io/RallyTools/RallyRestToolkitForRuby.png)](http://waffle.io/RallyTools/RallyRestToolkitForRuby)
|
4
18
|
|
5
19
|
RallyAPI is a wrapper of Rally's Web Service API Json endpoints using rest-client and native json parsing
|
6
20
|
Check the examples directory for more detailed samples.
|
7
21
|
|
8
|
-
|
9
|
-
|
22
|
+
### Installation
|
23
|
+
|
24
|
+
gem install rally_api
|
10
25
|
|
11
|
-
|
26
|
+
### Usage
|
12
27
|
|
13
|
-
|
28
|
+
Making a connection to Rally
|
14
29
|
require 'rally_api'
|
15
30
|
|
16
31
|
#Setting custom headers
|
@@ -32,7 +47,7 @@ Check the examples directory for more detailed samples.
|
|
32
47
|
@rally = RallyAPI::RallyRestJson.new(config)
|
33
48
|
|
34
49
|
|
35
|
-
|
50
|
+
### Querying Rally
|
36
51
|
|
37
52
|
#type names are stored in rally.rally_objects hash, you can inspect there for a list
|
38
53
|
#Look at the TypePath for all typedefs and this is the key to each hash.
|
@@ -69,7 +84,7 @@ Check the examples directory for more detailed samples.
|
|
69
84
|
end
|
70
85
|
|
71
86
|
|
72
|
-
|
87
|
+
### Reading an Artifact
|
73
88
|
defect = @rally.read("defect", 12345) #by ObjectID
|
74
89
|
#or
|
75
90
|
defect = @rally.read("defect", "FormattedID|DE42") #by FormattedID
|
@@ -89,13 +104,13 @@ Check the examples directory for more detailed samples.
|
|
89
104
|
# This is done for speed - lazy loading (going back to get a value from Rally) can be unneccessarily slow
|
90
105
|
# *Pick you fetch strings wisely* fetch everything you need and don't rely on read if you don't need it the speed is worth it.
|
91
106
|
|
92
|
-
|
107
|
+
### Creating an Artifact
|
93
108
|
obj = {}
|
94
109
|
obj["Name"] = "Test Defect created #{DateTime.now()}"
|
95
110
|
new_de = @rally.create("defect", obj)
|
96
111
|
puts new_de["FormattedID"]
|
97
112
|
|
98
|
-
|
113
|
+
### Updating an Artifact
|
99
114
|
fields = {}
|
100
115
|
fields["Severity"] = "Critical"
|
101
116
|
fields["Description"] = "Description for the issue"
|
@@ -107,7 +122,7 @@ Check the examples directory for more detailed samples.
|
|
107
122
|
field_updates = {"Description" => "Changed Description"}
|
108
123
|
defect.update(field_updates)
|
109
124
|
|
110
|
-
|
125
|
+
### Utils
|
111
126
|
#allowed values: pass the Artifact type string or downcased symbol and the Display Name of the field
|
112
127
|
@rally.allowed_values("Defect", "Severity")
|
113
128
|
@rally.allowed_values("story", "ScheduleState")
|
@@ -117,9 +132,3 @@ Check the examples directory for more detailed samples.
|
|
117
132
|
story1.rank_below(story2)
|
118
133
|
story1.rank_to_bottom
|
119
134
|
story1.rank_to_top
|
120
|
-
|
121
|
-
== License/Meta
|
122
|
-
Copyright (c) 2002-2013 Rally Software Development Corp. All Rights Reserved.
|
123
|
-
Your use of this Software is governed by the terms and conditions of the applicable Subscription Agreement
|
124
|
-
between your company and Rally Software Development Corp.
|
125
|
-
|
@@ -1,6 +1,5 @@
|
|
1
|
-
require
|
1
|
+
require "httpclient"
|
2
2
|
require 'json'
|
3
|
-
require 'nokogiri'
|
4
3
|
|
5
4
|
# :stopdoc:
|
6
5
|
#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved.
|
@@ -68,63 +67,6 @@ module RallyAPI
|
|
68
67
|
@security_token = keyval
|
69
68
|
end
|
70
69
|
|
71
|
-
#==========================================================================================================
|
72
|
-
#new sso auth method - experimental
|
73
|
-
def do_sso_auth(rally_sso_url, sso_user, sso_password)
|
74
|
-
step1res = @rally_http_client.request(:get, rally_sso_url, {:follow_redirect => true})
|
75
|
-
step1action = get_sso_form_info(step1res)
|
76
|
-
|
77
|
-
post_content2 = {:body => step1action[:inputs], :follow_redirect => true}
|
78
|
-
step2res = @rally_http_client.post(step1action[:action_url], post_content2)
|
79
|
-
step2action = get_sso_form_info(step2res)
|
80
|
-
step2formdata = {}
|
81
|
-
step2action[:inputs].each_key do |nm|
|
82
|
-
if nm.downcase.include?("name")
|
83
|
-
step2formdata[nm] = sso_user
|
84
|
-
elsif nm.downcase.include?("pass")
|
85
|
-
step2formdata[nm] = sso_password
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
base_url = URI.parse(step1action[:action_url])
|
90
|
-
|
91
|
-
step3_url = "#{base_url.scheme}://#{base_url.host}#{step2action[:action_url]}"
|
92
|
-
post_content3 = {:body => step2formdata, :follow_redirect => true}
|
93
|
-
step3res = @rally_http_client.post(step3_url, post_content3)
|
94
|
-
step3action = get_sso_form_info(step3res)
|
95
|
-
post_content4 = {:body => step3action[:inputs], :follow_redirect => true}
|
96
|
-
|
97
|
-
#step4_url = "#{base_url.scheme}://#{base_url.host}#{step3action[:action_url]}"
|
98
|
-
step4res = @rally_http_client.post(step3action[:action_url], post_content4)
|
99
|
-
log_info("got step4 #{step4res.body}")
|
100
|
-
|
101
|
-
step4action = get_sso_form_info(step4res)
|
102
|
-
post_content5 = {:body => step4action[:inputs], :follow_redirect => true}
|
103
|
-
step5res = @rally_http_client.post(step4action[:action_url], post_content5)
|
104
|
-
log_info("got step5 #{step5res.body}")
|
105
|
-
|
106
|
-
res = @rally_http_client.get("https://rally1.rallydev.com/slm/webservice/1.42/user.js")
|
107
|
-
log_info("final result: #{res.body}")
|
108
|
-
true
|
109
|
-
end
|
110
|
-
|
111
|
-
def get_sso_form_info(form_html)
|
112
|
-
log_info ("===================\nparsing #{form_html.body}\n======================")
|
113
|
-
parsed_html = Nokogiri::HTML(form_html.body)
|
114
|
-
inputs = {}
|
115
|
-
parsed_html.css("//input").each do |inp|
|
116
|
-
next if inp["name"].nil?
|
117
|
-
inputs[inp["name"]] = inp["value"]
|
118
|
-
end
|
119
|
-
|
120
|
-
form = parsed_html.at("//form")
|
121
|
-
form_action = form["action"]
|
122
|
-
return_val = {:action_url => form_action, :inputs => inputs}
|
123
|
-
log_info("\n==========================\n#{return_val}\n============================\n")
|
124
|
-
return_val
|
125
|
-
end
|
126
|
-
#==========================================================================================================
|
127
|
-
|
128
70
|
def logger=(log_dev)
|
129
71
|
@logger = log_dev
|
130
72
|
@rally_http_client.debug_dev = log_dev
|
@@ -14,7 +14,12 @@ module RallyAPI
|
|
14
14
|
attr_reader :rally_object, :type, :warnings
|
15
15
|
|
16
16
|
def initialize(rally_rest, json_hash, warnings = {})
|
17
|
-
|
17
|
+
# handle that we might not get a _ref or a _type
|
18
|
+
if !json_hash["_type"].nil? || !json_hash["_ref"].nil?
|
19
|
+
@type = json_hash["_type"] || json_hash["_ref"].split("/")[-2]
|
20
|
+
else
|
21
|
+
@type = "unknown"
|
22
|
+
end
|
18
23
|
@rally_object = json_hash
|
19
24
|
@rally_rest = rally_rest
|
20
25
|
@warnings = warnings[:warnings]
|
@@ -63,7 +68,7 @@ module RallyAPI
|
|
63
68
|
|
64
69
|
def elements
|
65
70
|
@rally_object.inject({}) do |elements, (key, value)|
|
66
|
-
if key.to_s.
|
71
|
+
if key.to_s.start_with?("c_")
|
67
72
|
key = key.to_s[2..-1]
|
68
73
|
end
|
69
74
|
elements[underscore(key).to_sym] = value
|
@@ -48,14 +48,13 @@ module RallyAPI
|
|
48
48
|
|
49
49
|
attr_accessor :rally_url, :rally_user, :rally_password, :rally_workspace_name, :rally_project_name, :wsapi_version,
|
50
50
|
:rally_headers, :rally_default_workspace, :rally_default_project, :low_debug, :proxy_info,
|
51
|
-
:rally_rest_api_compat, :logger, :rally_alias_types
|
51
|
+
:rally_rest_api_compat, :logger, :rally_alias_types
|
52
52
|
attr_reader :rally_connection
|
53
53
|
|
54
54
|
def initialize(args)
|
55
55
|
@rally_alias_types = { "story" => "HierarchicalRequirement", "userstory" => "HierarchicalRequirement" }
|
56
56
|
|
57
57
|
@rally_url = args[:base_url] || "https://rally1.rallydev.com/slm"
|
58
|
-
@rally_sso_url = args[:rally_sso_url]
|
59
58
|
@rally_user = args[:username]
|
60
59
|
@rally_password = args[:password]
|
61
60
|
@rally_workspace_name = args[:workspace]
|
@@ -64,12 +63,20 @@ module RallyAPI
|
|
64
63
|
@rally_headers = args[:headers] || CustomHttpHeader.new
|
65
64
|
@proxy_info = args[:proxy]
|
66
65
|
@skip_sec_key = args[:skip_sec_key]
|
66
|
+
|
67
67
|
#flag to help RallyRestAPI users to use snake case field names eg Defect.fixed_in_build vs Defect["FixedInBuild"]
|
68
|
-
@rally_rest_api_compat
|
69
|
-
@low_debug = args[:debug] || false
|
70
|
-
@logger = args[:logger] || nil #assumes this is an instance of Logger
|
68
|
+
@rally_rest_api_compat = args[:rally_rest_api_compat] || false
|
71
69
|
|
72
|
-
|
70
|
+
@low_debug = args[:debug] || false
|
71
|
+
@logger = args[:logger] || nil #assumes this is an instance of Logger
|
72
|
+
|
73
|
+
@rally_connection = RallyJsonConnection.new(@rally_headers, @low_debug, @proxy_info)
|
74
|
+
@rally_connection.set_client_user(@rally_url, @rally_user, @rally_password)
|
75
|
+
@rally_connection.logger = @logger unless @logger.nil?
|
76
|
+
|
77
|
+
if @wsapi_version.to_s.include?("v2.") && !@skip_sec_key
|
78
|
+
@rally_connection.setup_security_token(security_url)
|
79
|
+
end
|
73
80
|
|
74
81
|
if !@rally_workspace_name.nil?
|
75
82
|
@rally_default_workspace = find_workspace(@rally_workspace_name)
|
@@ -84,20 +91,6 @@ module RallyAPI
|
|
84
91
|
self
|
85
92
|
end
|
86
93
|
|
87
|
-
def setup_rally_connection
|
88
|
-
@rally_connection = RallyJsonConnection.new(@rally_headers, @low_debug, @proxy_info)
|
89
|
-
@rally_connection.logger = @logger unless @logger.nil?
|
90
|
-
if @rally_sso_url.nil?
|
91
|
-
@rally_connection.set_client_user(@rally_url, @rally_user, @rally_password)
|
92
|
-
else
|
93
|
-
@rally_connection.do_sso_auth(@rally_sso_url, @rally_user, @rally_password)
|
94
|
-
end
|
95
|
-
|
96
|
-
if @wsapi_version.to_s.include?("v2.") && !@skip_sec_key
|
97
|
-
@rally_connection.setup_security_token(security_url)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
94
|
def debug_logging_on
|
102
95
|
@low_debug = true
|
103
96
|
@rally_connection.low_debug = true
|
data/lib/rally_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rally_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
5
|
-
prerelease:
|
4
|
+
version: 0.9.18
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Dave Smith
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-26 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httpclient
|
16
|
-
requirement: &
|
16
|
+
requirement: &70250729329280 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,21 +21,10 @@ dependencies:
|
|
21
21
|
version: 2.3.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: nokogiri
|
27
|
-
requirement: &70356434093080 !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
|
-
requirements:
|
30
|
-
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 1.6.0
|
33
|
-
type: :runtime
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *70356434093080
|
24
|
+
version_requirements: *70250729329280
|
36
25
|
- !ruby/object:Gem::Dependency
|
37
26
|
name: simplecov
|
38
|
-
requirement: &
|
27
|
+
requirement: &70250729355980 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
29
|
requirements:
|
41
30
|
- - ! '>='
|
@@ -43,10 +32,10 @@ dependencies:
|
|
43
32
|
version: '0'
|
44
33
|
type: :development
|
45
34
|
prerelease: false
|
46
|
-
version_requirements: *
|
35
|
+
version_requirements: *70250729355980
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
37
|
name: rspec
|
49
|
-
requirement: &
|
38
|
+
requirement: &70250729355520 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
41
|
- - ! '>='
|
@@ -54,10 +43,10 @@ dependencies:
|
|
54
43
|
version: '0'
|
55
44
|
type: :development
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
46
|
+
version_requirements: *70250729355520
|
58
47
|
- !ruby/object:Gem::Dependency
|
59
48
|
name: rake
|
60
|
-
requirement: &
|
49
|
+
requirement: &70250729355100 !ruby/object:Gem::Requirement
|
61
50
|
none: false
|
62
51
|
requirements:
|
63
52
|
- - ! '>='
|
@@ -65,7 +54,7 @@ dependencies:
|
|
65
54
|
version: '0'
|
66
55
|
type: :development
|
67
56
|
prerelease: false
|
68
|
-
version_requirements: *
|
57
|
+
version_requirements: *70250729355100
|
69
58
|
description: API wrapper for Rally's JSON REST web services api
|
70
59
|
email:
|
71
60
|
- dsmith@rallydev.com
|
@@ -73,7 +62,7 @@ executables: []
|
|
73
62
|
extensions: []
|
74
63
|
extra_rdoc_files: []
|
75
64
|
files:
|
76
|
-
- README.
|
65
|
+
- README.md
|
77
66
|
- Rakefile
|
78
67
|
- lib/rally_api/custom_http_header.rb
|
79
68
|
- lib/rally_api/lookback_api_query.rb
|
@@ -100,9 +89,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
100
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
90
|
none: false
|
102
91
|
requirements:
|
103
|
-
- - ! '
|
92
|
+
- - ! '>='
|
104
93
|
- !ruby/object:Gem::Version
|
105
|
-
version:
|
94
|
+
version: '0'
|
106
95
|
requirements: []
|
107
96
|
rubyforge_project: rally_api
|
108
97
|
rubygems_version: 1.8.6
|