sfrest 0.0.8
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 +7 -0
- data/lib/sfrest/audit.rb +16 -0
- data/lib/sfrest/backup.rb +46 -0
- data/lib/sfrest/connection.rb +173 -0
- data/lib/sfrest/domains.rb +63 -0
- data/lib/sfrest/error.rb +19 -0
- data/lib/sfrest/group.rb +54 -0
- data/lib/sfrest/pathbuilder.rb +24 -0
- data/lib/sfrest/role.rb +101 -0
- data/lib/sfrest/site.rb +99 -0
- data/lib/sfrest/stage.rb +31 -0
- data/lib/sfrest/task.rb +261 -0
- data/lib/sfrest/theme.rb +23 -0
- data/lib/sfrest/update.rb +78 -0
- data/lib/sfrest/user.rb +106 -0
- data/lib/sfrest/variable.rb +28 -0
- data/lib/sfrest/version.rb +3 -0
- data/lib/sfrest.rb +43 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7045fc0312fa3b50c38c0605a27b900a9a50a08e
|
4
|
+
data.tar.gz: 8f31a1b7ecc1e6d1bb13a47e36d7fc20c05bbdc4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c1273edd11d4687be24897f2d76e7210abde28982f8377fcc54acf909af4f7890abedbc9aba15cb4b5c4f9453886243d5bdee90ac0a404d5ed3089ba1e16ae50
|
7
|
+
data.tar.gz: 5021fe6693f4af1bd6624cf9956c9568b5373e24a5bbe61ee483bdde5c08c8ec982f9dcfee990d934ea6699407516bc56fe3d79026c99299ac98cdb414dec06a
|
data/lib/sfrest/audit.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Get all the audit devents.
|
3
|
+
class Audit
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# Lists audit events.
|
10
|
+
# @return [Hash{'count' => Integer, 'changes' => [Hash, Hash]}]
|
11
|
+
def list_audit_events
|
12
|
+
current_path = '/api/v1/audit'
|
13
|
+
@conn.get(current_path)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Backup a site or restore onto that site
|
3
|
+
class Backup
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# cool stuff goes here
|
10
|
+
# @param [Integer] site_id the node id of the site node
|
11
|
+
# @return [Hash]
|
12
|
+
def get_backups(site_id, datum = nil)
|
13
|
+
current_path = "/api/v1/sites/#{site_id}/backups"
|
14
|
+
pb = SFRest::Pathbuilder.new
|
15
|
+
@conn.get URI.parse(URI.encode(pb.build_url_query(current_path, datum))).to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
# Deletes a site backup.
|
19
|
+
# @param [Integer] site_id Node id of site
|
20
|
+
# @param [Integer] backup_id Id of backup to delete
|
21
|
+
def delete_backup(site_id, backup_id)
|
22
|
+
current_path = "/api/v1/sites/#{site_id}/backups/#{backup_id}"
|
23
|
+
@conn.delete(current_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Backs up a site.
|
27
|
+
# @param [Integer] site_id
|
28
|
+
# @param [Hash] datum Options to the backup
|
29
|
+
# @option datum [String] 'label'
|
30
|
+
# @option datum [Url] 'callback_url'
|
31
|
+
# @option datum [String] 'callback_method' GET|POST
|
32
|
+
# @option datum [Json] 'caller_data' json encoded string
|
33
|
+
def create_backup(site_id, datum = nil)
|
34
|
+
current_path = "/api/v1/sites/#{site_id}/backup"
|
35
|
+
@conn.post(current_path, datum.to_json)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Gets a url to download a backup
|
39
|
+
# @param [Integer] site_id Node id of site
|
40
|
+
# @param [Integer] backup_id Id of backup to delete
|
41
|
+
# @param [Integer] lifetime TTL of the url
|
42
|
+
def backup_url(site_id, backup_id, lifetime = 60)
|
43
|
+
@conn.get("/api/v1/sites/#{site_id}/backups/#{backup_id}/url?lifetime=#{lifetime}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Generic http methods
|
3
|
+
# accessors for all the sub classes.
|
4
|
+
class Connection
|
5
|
+
attr_accessor :base_url, :username, :password
|
6
|
+
|
7
|
+
# @param [String] url base url of the SF endpoint e.g. https://www.sfdev.acsitefactory.com
|
8
|
+
# @param [String] user api user
|
9
|
+
# @param [String] password api password
|
10
|
+
def initialize(url, user, password)
|
11
|
+
@base_url = url
|
12
|
+
@username = user
|
13
|
+
@password = password
|
14
|
+
end
|
15
|
+
|
16
|
+
# http request via get
|
17
|
+
# @param [string] uri
|
18
|
+
# @return [Object] ruby representation of the json response
|
19
|
+
# if the reponsebody does not parse, returns
|
20
|
+
# the non-parsed body
|
21
|
+
def get(uri)
|
22
|
+
headers = { 'Content-Type' => 'application/json' }
|
23
|
+
res = Excon.get(@base_url + uri.to_s,
|
24
|
+
headers: headers,
|
25
|
+
user: username,
|
26
|
+
password: password,
|
27
|
+
ssl_verify_peer: false)
|
28
|
+
begin
|
29
|
+
access_check JSON(res.body)
|
30
|
+
rescue JSON::ParserError
|
31
|
+
res.body
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# http request via get
|
36
|
+
# @param [string] uri
|
37
|
+
# @return [Integer, Object] http status and the ruby representation
|
38
|
+
# of the json response if the reponse body
|
39
|
+
# does not parse, returns the non-parsed body
|
40
|
+
def get_with_status(uri)
|
41
|
+
headers = { 'Content-Type' => 'application/json' }
|
42
|
+
res = Excon.get(@base_url + uri.to_s,
|
43
|
+
headers: headers,
|
44
|
+
user: username,
|
45
|
+
password: password,
|
46
|
+
ssl_verify_peer: false)
|
47
|
+
begin
|
48
|
+
data = access_check JSON(res.body)
|
49
|
+
return res.status, data
|
50
|
+
|
51
|
+
rescue JSON::ParserError
|
52
|
+
return res.status, res.body
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# http request via post
|
57
|
+
# @param [string] uri
|
58
|
+
# @return [Object] ruby representation of the json response
|
59
|
+
# if the reponsebody does not parse, returns
|
60
|
+
# the non-parsed body
|
61
|
+
def post(uri, payload)
|
62
|
+
headers = { 'Content-Type' => 'application/json' }
|
63
|
+
res = Excon.post(@base_url + uri.to_s,
|
64
|
+
headers: headers,
|
65
|
+
user: username,
|
66
|
+
password: password,
|
67
|
+
ssl_verify_peer: false,
|
68
|
+
body: payload)
|
69
|
+
begin
|
70
|
+
access_check JSON(res.body)
|
71
|
+
rescue JSON::ParserError
|
72
|
+
res.body
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# http request via put
|
77
|
+
# @param [string] uri
|
78
|
+
# @return [Object] ruby representation of the json response
|
79
|
+
# if the reponsebody does not parse, returns
|
80
|
+
# the non-parsed body
|
81
|
+
def put(uri, payload)
|
82
|
+
headers = { 'Content-Type' => 'application/json' }
|
83
|
+
res = Excon.put(@base_url + uri.to_s,
|
84
|
+
headers: headers,
|
85
|
+
user: username,
|
86
|
+
password: password,
|
87
|
+
ssl_verify_peer: false,
|
88
|
+
body: payload)
|
89
|
+
begin
|
90
|
+
access_check JSON(res.body)
|
91
|
+
rescue JSON::ParserError
|
92
|
+
res.body
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# http request via delete
|
97
|
+
# @param [string] uri
|
98
|
+
# @return [Object] ruby representation of the json response
|
99
|
+
# if the reponsebody does not parse, returns
|
100
|
+
# the non-parsed body
|
101
|
+
def delete(uri)
|
102
|
+
headers = { 'Content-Type' => 'application/json' }
|
103
|
+
res = Excon.delete(@base_url + uri.to_s,
|
104
|
+
headers: headers,
|
105
|
+
user: username,
|
106
|
+
password: password,
|
107
|
+
ssl_verify_peer: false)
|
108
|
+
begin
|
109
|
+
access_check JSON(res.body)
|
110
|
+
rescue JSON::ParserError
|
111
|
+
res.body
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Throws an SFRest exception for requests that have problems
|
116
|
+
# @param [Object] data JSON parsed http reponse of the SFApi
|
117
|
+
# @return [Object] the data object if there are no issues
|
118
|
+
# @raise [SFRest::AccessDeniedError] if Authentication fails
|
119
|
+
# @raise [SFRest::ActionForbiddenError] if the users role cannot perform the request
|
120
|
+
# @raise [SFRest::BadRequestError] if there is something malformed in the request
|
121
|
+
#
|
122
|
+
def access_check(data)
|
123
|
+
return data unless data.is_a?(Hash) # if there is an error message, it will be in a hash.
|
124
|
+
unless data['message'].nil?
|
125
|
+
raise SFRest::AccessDeniedError, data['message'] if data['message'] =~ /Access denied/
|
126
|
+
raise SFRest::ActionForbiddenError, data['message'] if data['message'] =~ /Forbidden: /
|
127
|
+
raise SFRest::BadRequestError, data['message'] if data['message'] =~ /Bad Request:/
|
128
|
+
end
|
129
|
+
data
|
130
|
+
end
|
131
|
+
|
132
|
+
# pings the SF api as an authenticated user
|
133
|
+
# responds with a pong
|
134
|
+
def ping
|
135
|
+
get('/api/v1/ping')
|
136
|
+
end
|
137
|
+
|
138
|
+
# Pings to retrieve a service response.
|
139
|
+
def service_response
|
140
|
+
ping
|
141
|
+
end
|
142
|
+
|
143
|
+
# define the other class accessor methods.
|
144
|
+
# this will instantiate the class with the set creds
|
145
|
+
# and make it possible to do
|
146
|
+
# sfa = SFRest.new url, user, password
|
147
|
+
# sfa.ping
|
148
|
+
# sfa.site.first_site_id
|
149
|
+
#
|
150
|
+
# If a new class is added, add the accessor to this list.
|
151
|
+
# NOTE: accessor == Class_name.to_lower
|
152
|
+
REST_METHODS = %w(audit
|
153
|
+
backup
|
154
|
+
domains
|
155
|
+
group
|
156
|
+
role
|
157
|
+
site
|
158
|
+
stage
|
159
|
+
task
|
160
|
+
theme
|
161
|
+
update
|
162
|
+
user
|
163
|
+
variable).freeze
|
164
|
+
|
165
|
+
REST_METHODS.each do |m|
|
166
|
+
define_method(m) do
|
167
|
+
m.capitalize!
|
168
|
+
sfrest_klass = "SFRest::#{m}"
|
169
|
+
Object.const_get(sfrest_klass).new(self)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Find Staging envs and stage a set of sites
|
3
|
+
class Domains
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# Get the domains information on a node
|
10
|
+
# @param [Integer] node_id The id of the node.
|
11
|
+
#
|
12
|
+
# @return [Hash] { "node_id" => 4966, "node_type" => "site",
|
13
|
+
# "time" => "2016-11-18T20:09:55+00:00",
|
14
|
+
# "domains" => { "protected_domains" =>[ "it252garden4.utest.sfdev.acquia-test.co" ],
|
15
|
+
# "custom_domains" => [ "it252coll3.utest.sfdev.acquia-test.co", "sc1.nikgregory.us" ] } }
|
16
|
+
def get(node_id)
|
17
|
+
current_path = "/api/v1/domains/#{node_id}"
|
18
|
+
@conn.get(current_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get the custom domains on a node
|
22
|
+
# @param [Integer] node_id The id of the node.
|
23
|
+
#
|
24
|
+
# @return [Array] custom(removable) domains on a node
|
25
|
+
def custom_domains(node_id)
|
26
|
+
get(node_id)['domains']['custom_domains']
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get the protetect domains on a node
|
30
|
+
# @param [Integer] node_id The id of the node.
|
31
|
+
#
|
32
|
+
# @return [Array] protected (non-removable) domains on a node
|
33
|
+
def protected_domains(node_id)
|
34
|
+
get(node_id)['domains']['protected_domains']
|
35
|
+
end
|
36
|
+
|
37
|
+
# Add a domain
|
38
|
+
# @param [Integer] node_id The id of the node to which add a domain
|
39
|
+
# @param [String] domain_name domain to add. e.g. www.example.com
|
40
|
+
#
|
41
|
+
# @return [Hash] { "node_type": "site_collection",
|
42
|
+
# "domain": "www.example.com",
|
43
|
+
# "added": true,
|
44
|
+
# "messages": [ "Your domain name was successfully added to the site collection."] }
|
45
|
+
def add(node_id, domain_name)
|
46
|
+
payload = { 'domain_name' => domain_name }.to_json
|
47
|
+
@conn.post("/api/v1/domains/#{node_id}/add", payload)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Remove a domain
|
51
|
+
# @param [Integer] node_id The id of the node to which remove a domain
|
52
|
+
# @param [String] domain_name domain to remove. e.g. www.example.com
|
53
|
+
#
|
54
|
+
# @return [Hash] { "node_type": "site_collection",
|
55
|
+
# "domain": "www.example.com",
|
56
|
+
# "removed": true,
|
57
|
+
# "messages": [ "Your domain name was successfully removed from the site collection." ] }
|
58
|
+
def remove(node_id, domain_name)
|
59
|
+
payload = { 'domain_name' => domain_name }.to_json
|
60
|
+
@conn.post("/api/v1/domains/#{node_id}/remove", payload)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/sfrest/error.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Error classes for SFRest
|
3
|
+
|
4
|
+
# Extends StandardError so we can catch SFRest::SFError
|
5
|
+
class SFError < StandardError; end
|
6
|
+
|
7
|
+
# Throw this when a user cannot successfuly authenticate
|
8
|
+
class AccessDeniedError < SFRest::SFError; end
|
9
|
+
|
10
|
+
# Throw this when a user does not have permission to perform an action
|
11
|
+
class ActionForbiddenError < SFRest::SFError; end
|
12
|
+
|
13
|
+
# Throw this when the request is incomplete or otherwise cannot be processed by
|
14
|
+
# the factory
|
15
|
+
class BadRequestError < SFRest::SFError; end
|
16
|
+
|
17
|
+
# Throw when a task appears to be running too long
|
18
|
+
class TaskNotDoneError < SFRest::SFError; end
|
19
|
+
end
|
data/lib/sfrest/group.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module SFRest
|
2
|
+
# SF Group management
|
3
|
+
class Group
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# Creates a site group with specified group name.
|
10
|
+
# This currently will only create a group in the root
|
11
|
+
# @param [String] groupname Name of the group to be created
|
12
|
+
def create_group(groupname)
|
13
|
+
current_path = '/api/v1/groups'
|
14
|
+
payload = { 'group_name' => groupname }.to_json
|
15
|
+
@conn.post(current_path, payload)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Gets a site group with a specified group id.
|
19
|
+
# @param [Integer] group_id Id of the group to fetch
|
20
|
+
# @return [Hash] group object from the SF Api
|
21
|
+
def get_group(group_id = 0)
|
22
|
+
current_path = '/api/v1/groups/' << group_id.to_s
|
23
|
+
@conn.get(current_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Gets a list of all site groups.
|
27
|
+
# @return [Hash] all the groups on the factory plus a count
|
28
|
+
# {'count' => count, 'groups' => Hash }
|
29
|
+
# this will iterate through the group pages
|
30
|
+
def group_list
|
31
|
+
page = 1
|
32
|
+
not_done = true
|
33
|
+
count = 0
|
34
|
+
while not_done
|
35
|
+
current_path = '/api/v1/groups?page=' << page.to_s
|
36
|
+
res = @conn.get(current_path)
|
37
|
+
if res['groups'] == []
|
38
|
+
not_done = false
|
39
|
+
elsif !res['message'].nil?
|
40
|
+
return { 'message' => res['message'] }
|
41
|
+
elsif page == 1
|
42
|
+
count = res['count']
|
43
|
+
groups = res['groups']
|
44
|
+
else
|
45
|
+
res['groups'].each do |group|
|
46
|
+
groups << group
|
47
|
+
end
|
48
|
+
end
|
49
|
+
page += 1
|
50
|
+
end
|
51
|
+
{ 'count' => count, 'groups' => groups }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module SFRest
|
2
|
+
# make a url querypath
|
3
|
+
# so that if the are multiple items in a get request
|
4
|
+
# we can get a path like /api/v1/foo?bar=boo&bat=gah ...
|
5
|
+
class Pathbuilder
|
6
|
+
# build a get query
|
7
|
+
# @param [String] current_path the uri like /api/v1/foo
|
8
|
+
# @param [Hash] datum k,v hash of get query param and value
|
9
|
+
def build_url_query(current_path, datum = nil)
|
10
|
+
unless datum.nil?
|
11
|
+
current_path += '?'
|
12
|
+
datum.each do |key, value|
|
13
|
+
current_path += '&' if needs_new_parameter? current_path
|
14
|
+
current_path += key.to_s + '=' + value.to_s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
current_path
|
18
|
+
end
|
19
|
+
|
20
|
+
private def needs_new_parameter?(path)
|
21
|
+
path[-1, 1] != '?' # if path has '?' then we need to create a new parameter
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/sfrest/role.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
module SFRest
|
2
|
+
# create, delete, update, roles
|
3
|
+
class Role
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# roles
|
10
|
+
# Gets the complete list of roles
|
11
|
+
# @return [Hash] all the roles on the factory plus a count
|
12
|
+
# {'count' => count, 'roles' => Hash }
|
13
|
+
# this will iterate through the roles pages
|
14
|
+
def role_list
|
15
|
+
page = 1
|
16
|
+
not_done = true
|
17
|
+
count = 0
|
18
|
+
while not_done
|
19
|
+
current_path = '/api/v1/roles?page=' << page.to_s
|
20
|
+
res = @conn.get(current_path)
|
21
|
+
if res['roles'] == []
|
22
|
+
not_done = false
|
23
|
+
elsif !res['message'].nil?
|
24
|
+
return { 'message' => res['message'] }
|
25
|
+
elsif page == 1
|
26
|
+
count = res['count']
|
27
|
+
roles = res['roles']
|
28
|
+
else
|
29
|
+
res['roles'].each do |roleid, rolename|
|
30
|
+
roles[roleid] = rolename
|
31
|
+
end
|
32
|
+
end
|
33
|
+
page += 1
|
34
|
+
end
|
35
|
+
{ 'count' => count, 'roles' => roles }
|
36
|
+
end
|
37
|
+
|
38
|
+
# gets the role ID for the role named rolename
|
39
|
+
# will page through all the roles available searching for the site
|
40
|
+
# @param [String] rolename the name of the role to find
|
41
|
+
# @return [Integer] the id of rolename
|
42
|
+
# this will iterate through the roles pages
|
43
|
+
def get_role_id(rolename)
|
44
|
+
pglimit = 100
|
45
|
+
res = @conn.get('/api/v1/roles&limit=' + pglimit.to_s)
|
46
|
+
rolecount = res['count'].to_i
|
47
|
+
id = role_data_from_results(res, rolename)
|
48
|
+
return id if id
|
49
|
+
pages = (rolecount / pglimit) + 1
|
50
|
+
2.upto(pages) do |i|
|
51
|
+
res = @conn.get('/api/v1/roles&limit=' + pglimit.to_s + '?page=' + i.to_s)
|
52
|
+
id = role_data_from_results(res, rolename)
|
53
|
+
return id if id
|
54
|
+
end
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
58
|
+
# Extract the role data for rolename based on the role result object
|
59
|
+
# @param [Hash] res result from a request to /roles
|
60
|
+
# @param [String] rolename
|
61
|
+
# @return [Object] Integer, String, Array, Hash depending on the user data
|
62
|
+
def role_data_from_results(res, rolename)
|
63
|
+
roles = res['roles']
|
64
|
+
roles.each do |role|
|
65
|
+
return role[0].to_i if role[1] == rolename
|
66
|
+
end
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
# Gets role data for a specific role id
|
71
|
+
# @param [Integer] id the role id
|
72
|
+
# @return [Hash] the role
|
73
|
+
def role_data(id)
|
74
|
+
@conn.get('/api/v1/roles/' + id.to_s)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Creates a role.
|
78
|
+
# @param [String] name name of the role to create
|
79
|
+
def create_role(name)
|
80
|
+
current_path = '/api/v1/roles'
|
81
|
+
payload = { 'name' => name }.to_json
|
82
|
+
@conn.post(current_path, payload)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Updates a role (changes the name).
|
86
|
+
# @param [Integer] id the id of the role to rename
|
87
|
+
# @param [String] name the new role name
|
88
|
+
def update_role(id, name)
|
89
|
+
current_path = "/api/v1/roles/#{id}/update"
|
90
|
+
payload = { 'new_name' => name }.to_json
|
91
|
+
@conn.put(current_path, payload)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Delete a role.
|
95
|
+
# @param [Integer] id the role id of the role to delete
|
96
|
+
def delete_role(id)
|
97
|
+
current_path = "/api/v1/roles/#{id}"
|
98
|
+
@conn.delete(current_path)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/sfrest/site.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Find sites, create a site,
|
3
|
+
class Site
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# gets the site ID for the site named sitename
|
10
|
+
# will page through all the sites available searching for the site
|
11
|
+
# @param [String] sitename the name of the site
|
12
|
+
# @return [Integer] the id of sitename
|
13
|
+
def get_site_id(sitename)
|
14
|
+
pglimit = 100
|
15
|
+
res = @conn.get('/api/v1/sites&limit=' + pglimit.to_s)
|
16
|
+
sitecount = res['count'].to_i
|
17
|
+
id = site_data_from_results(res, sitename, 'id')
|
18
|
+
return id if id
|
19
|
+
pages = (sitecount / pglimit) + 1
|
20
|
+
2.upto(pages) do |i|
|
21
|
+
res = @conn.get('/api/v1/sites&limit=' + pglimit.to_s + '?page=' + i.to_s)
|
22
|
+
id = site_data_from_results(res, sitename, 'id')
|
23
|
+
return id if id
|
24
|
+
end
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
# Extract the site data for 'key' based on the site result object
|
29
|
+
# @param [Hash] res result from a request to /sites
|
30
|
+
# @param [String] sitename
|
31
|
+
# @param [String] key one of the user data returned (id, site, domain...)
|
32
|
+
# @return [Object] Integer, String, Array, Hash depending on the site data
|
33
|
+
def site_data_from_results(res, sitename, key)
|
34
|
+
sites = res['sites']
|
35
|
+
sites.each do |site|
|
36
|
+
return site[key] if site['site'] == sitename
|
37
|
+
end
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# Gets the site data for a specific site id
|
42
|
+
# @param [Integer] site_id the site id
|
43
|
+
# @return [Hash]
|
44
|
+
def get_site_data(site_id)
|
45
|
+
@conn.get('/api/v1/sites/' + site_id.to_s)
|
46
|
+
end
|
47
|
+
|
48
|
+
# gets the site id of the 1st one found using the api
|
49
|
+
# @return [Integer] the site id
|
50
|
+
def first_site_id
|
51
|
+
res = @conn.get('/api/v1/sites')
|
52
|
+
res['sites'].first['id']
|
53
|
+
end
|
54
|
+
|
55
|
+
# Gets the complete list of users
|
56
|
+
# Makes multiple requests to the factory to get all the sites on the factory
|
57
|
+
# @return [Hash{'count' => Integer, 'sites' => Hash}]
|
58
|
+
def site_list
|
59
|
+
page = 1
|
60
|
+
not_done = true
|
61
|
+
count = 0
|
62
|
+
while not_done
|
63
|
+
current_path = '/api/v1/sites?page=' << page.to_s
|
64
|
+
res = @conn.get(current_path)
|
65
|
+
if res['sites'] == []
|
66
|
+
not_done = false
|
67
|
+
elsif !res['message'].nil?
|
68
|
+
return { 'message' => res['message'] }
|
69
|
+
elsif page == 1
|
70
|
+
count = res['count']
|
71
|
+
sites = res['sites']
|
72
|
+
else
|
73
|
+
res['sites'].each do |site|
|
74
|
+
sites << site
|
75
|
+
end
|
76
|
+
end
|
77
|
+
page += 1
|
78
|
+
end
|
79
|
+
{ 'count' => count, 'sites' => sites }
|
80
|
+
end
|
81
|
+
|
82
|
+
# Creates a site.
|
83
|
+
# @param [String] sitename The name of the site to create
|
84
|
+
# @param [Integer] group_id The Id of the group the site is to be a member of
|
85
|
+
# @param [String] install_profile The install profile to use when creating the site
|
86
|
+
def create_site(sitename, group_id, install_profile = nil)
|
87
|
+
current_path = '/api/v1/sites'
|
88
|
+
payload = { 'site_name' => sitename, 'group_ids' => [group_id],
|
89
|
+
'install_profile' => install_profile }.to_json
|
90
|
+
@conn.post(current_path, payload)
|
91
|
+
end
|
92
|
+
|
93
|
+
# accessors for backups/restore
|
94
|
+
# so that you can do site.backup.list_backups
|
95
|
+
def backup
|
96
|
+
@conn.backup
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/sfrest/stage.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Find Staging envs and stage a set of sites
|
3
|
+
class Stage
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# Stage a site
|
10
|
+
# @param [String] to_env the name of of target env. defaults to test
|
11
|
+
# @param [Array] sites Array of site nids to stage
|
12
|
+
# @param [Boolean] email_site_status send an email about the staging status of each site
|
13
|
+
# @param [Boolean] skip_gardener skip staging the gardener and only stage the sites
|
14
|
+
#
|
15
|
+
# @return [Integer] Id of the staging task created.
|
16
|
+
def stage(to_env = 'test', sites = nil, email_site_status = false, skip_gardener = false)
|
17
|
+
payload = { 'to_env' => to_env, 'sites' => sites,
|
18
|
+
'detailed_status' => email_site_status,
|
19
|
+
'skip_gardener' => skip_gardener }.to_json
|
20
|
+
@conn.post('/api/v1/stage', payload)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Query for available staging environments
|
24
|
+
#
|
25
|
+
# @return environments
|
26
|
+
def list_staging_environments
|
27
|
+
current_path = '/api/v1/stage'
|
28
|
+
@conn.get(current_path)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/sfrest/task.rb
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Deal with tasks, find them, pause them...
|
3
|
+
class Task
|
4
|
+
STATUS_NOT_STARTED = 1 # Task has been added to queue but not picked up
|
5
|
+
STATUS_RESTARTED = 2 # Task has been re-added to the queue but not picked up
|
6
|
+
STATUS_TO_BE_RUN = 3 # Restarted + not started
|
7
|
+
STATUS_IN_PROCESS = 4 # A wip process is actively processing a task
|
8
|
+
STATUS_WAITING = 8 # Task has been released from active processing
|
9
|
+
STATUS_RUNNING = 12 # Running = in process + waiting to be processed
|
10
|
+
STATUS_COMPLETED = 16 # Task is successfully processed (exited with success)
|
11
|
+
STATUS_ERROR = 32 # Task unsccuessfully completed (exited with failure)
|
12
|
+
STATUS_KILLED = 64 # Task is terminated
|
13
|
+
STATUS_WARNING = 144 # Completed bit + 128 bit(warning).
|
14
|
+
STATUS_DONE = 240 # Completed + error + killed + 128 bit(warning)
|
15
|
+
|
16
|
+
# @param [SFRest::Connection] conn
|
17
|
+
def initialize(conn)
|
18
|
+
@conn = conn
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns true only if the status evaluates to completed
|
22
|
+
# @param [Integer] status
|
23
|
+
# @return [Boolean]
|
24
|
+
def status_completed?(status)
|
25
|
+
return true if status.to_i == STATUS_COMPLETED
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns true if the status evaluates to either
|
30
|
+
# waiting or in process
|
31
|
+
# @param [Integer] status
|
32
|
+
# @return [Boolean]
|
33
|
+
def status_running?(status)
|
34
|
+
return true if (status.to_i & STATUS_RUNNING) > 0
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns true only if the status evaluates to errored
|
39
|
+
# @param [Integer] status
|
40
|
+
# @return [Boolean]
|
41
|
+
def status_error?(status)
|
42
|
+
return true if status.to_i == STATUS_ERROR
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns true only if the status evaluates to killed
|
47
|
+
# @param [Integer] status
|
48
|
+
# @return [Boolean]
|
49
|
+
def status_killed?(status)
|
50
|
+
return true if status.to_i == STATUS_KILLED
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns true if the status evaluates to a state that is
|
55
|
+
# considered done
|
56
|
+
# @param [Integer] status
|
57
|
+
# @return [Boolean]
|
58
|
+
def status_done?(status)
|
59
|
+
return true if (status.to_i & STATUS_DONE) > 0
|
60
|
+
false
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns true only if WIP reports the status as running
|
64
|
+
# @param [Integer] task_id
|
65
|
+
# @return [Boolean]
|
66
|
+
def task_running?(task_id)
|
67
|
+
task_path = "/api/v1/wip/task/#{task_id}/status"
|
68
|
+
|
69
|
+
res = @conn.get task_path
|
70
|
+
status = res['wip_task']['status']
|
71
|
+
status_running?(status)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns true only if WIP reports the status as completed
|
75
|
+
# @param [Integer] task_id
|
76
|
+
# @return [Boolean]
|
77
|
+
def task_completed?(task_id)
|
78
|
+
task_path = "/api/v1/wip/task/#{task_id}/status"
|
79
|
+
|
80
|
+
res = @conn.get task_path
|
81
|
+
status = res['wip_task']['status']
|
82
|
+
status_completed?(status)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns true if WIP reports the status in a state that is
|
86
|
+
# considered done
|
87
|
+
# @param [Integer] task_id
|
88
|
+
# @return [Boolean]
|
89
|
+
def task_done?(task_id)
|
90
|
+
task_path = "/api/v1/wip/task/#{task_id}/status"
|
91
|
+
|
92
|
+
res = @conn.get task_path
|
93
|
+
status = res['wip_task']['status']
|
94
|
+
status_done?(status)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns true only if WIP reports the status as killed
|
98
|
+
# @param [Integer] task_id
|
99
|
+
# @return [Boolean]
|
100
|
+
def task_killed?(task_id)
|
101
|
+
task_path = "/api/v1/wip/task/#{task_id}/status"
|
102
|
+
|
103
|
+
res = @conn.get task_path
|
104
|
+
status = res['wip_task']['status']
|
105
|
+
status_killed?(status)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns true only if WIP reports the status as errored
|
109
|
+
# @param [Integer] task_id
|
110
|
+
# @return [Boolean]
|
111
|
+
def task_errored?(task_id)
|
112
|
+
task_path = "/api/v1/wip/task/#{task_id}/status"
|
113
|
+
|
114
|
+
res = @conn.get task_path
|
115
|
+
status = res['wip_task']['status']
|
116
|
+
status_error?(status)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Find a set of task ids.
|
120
|
+
# @param [Integer] limit max amount of results to return per request
|
121
|
+
# @param [Integer] page page of request
|
122
|
+
# @param [String] group task group
|
123
|
+
# @param [String] klass task class
|
124
|
+
# @param [Integer] status Integerish the status of the task
|
125
|
+
# see SFRest::Task::STATUS_*
|
126
|
+
# @return [Array[Integer]]
|
127
|
+
def find_task_ids(limit = nil, page = nil, group = nil, klass = nil, status = nil)
|
128
|
+
res = find_tasks limit: limit, page: page, group: group, klass: klass, status: status
|
129
|
+
task_ids = []
|
130
|
+
i = 0
|
131
|
+
res.each do |task|
|
132
|
+
task_ids[i] = task['id']
|
133
|
+
i += 1
|
134
|
+
end
|
135
|
+
task_ids
|
136
|
+
end
|
137
|
+
|
138
|
+
# Find a set of tasks.
|
139
|
+
# @param [Hash] datum Hash of filters
|
140
|
+
# @option datum [Integer] :limit max amount of results to return per request
|
141
|
+
# @option datum [Integer] :page page of request
|
142
|
+
# @option datum [String] :group task group
|
143
|
+
# @option datum [String] :class task class
|
144
|
+
# @option datum [Integer] :status Integerish the status of the task
|
145
|
+
# see SFRest::Task::STATUS_*
|
146
|
+
def find_tasks(datum = nil)
|
147
|
+
current_path = '/api/v1/tasks'
|
148
|
+
pb = SFRest::Pathbuilder.new
|
149
|
+
@conn.get URI.parse(URI.encode(pb.build_url_query(current_path, datum))).to_s
|
150
|
+
end
|
151
|
+
|
152
|
+
# Looks for a task with a specific name
|
153
|
+
# @param [String] name display name of the task
|
154
|
+
# @param [String] group task group filter
|
155
|
+
# @param [String] klass task class filter
|
156
|
+
# @param [String] status task status filter
|
157
|
+
def get_task_id(name, group = nil, klass = nil, status = nil)
|
158
|
+
page_size = 100
|
159
|
+
page = 0
|
160
|
+
loop do
|
161
|
+
tasks = find_tasks(limit: page_size, page: page, group: group, class: klass, status: status)
|
162
|
+
tasks.each do |task|
|
163
|
+
return task['id'].to_i if task['name'] =~ /#{name}/
|
164
|
+
page += 1
|
165
|
+
end
|
166
|
+
break if tasks.size < page_size
|
167
|
+
end
|
168
|
+
nil
|
169
|
+
end
|
170
|
+
|
171
|
+
# Pauses all tasks.
|
172
|
+
def pause_all_tasks
|
173
|
+
current_path = '/api/v1/pause'
|
174
|
+
payload = { 'paused' => true }.to_json
|
175
|
+
@conn.post(current_path, payload)
|
176
|
+
end
|
177
|
+
|
178
|
+
# Resumes all tasks.
|
179
|
+
def resume_all_tasks
|
180
|
+
current_path = '/api/v1/pause'
|
181
|
+
payload = { 'paused' => false }.to_json
|
182
|
+
@conn.post(current_path, payload)
|
183
|
+
end
|
184
|
+
|
185
|
+
# Get a specific task's logs
|
186
|
+
# @param [Integer] task_id
|
187
|
+
def get_task_logs(task_id)
|
188
|
+
current_path = '/api/v1/tasks/' << task_id.to_s << '/logs'
|
189
|
+
@conn.get(current_path)
|
190
|
+
end
|
191
|
+
|
192
|
+
# Gets the value of a vairable
|
193
|
+
# @TODO: this is missnamed becasue it does not check the global paused variable
|
194
|
+
# @param [String] variable_name
|
195
|
+
# @return [Object]
|
196
|
+
def globally_paused?(variable_name)
|
197
|
+
current_path = "/api/v1/variables?name=#{variable_name}"
|
198
|
+
res = @conn.get(current_path)
|
199
|
+
res[variable_name]
|
200
|
+
end
|
201
|
+
|
202
|
+
# Pauses a specific task identified by its task id.
|
203
|
+
# This can pause either the task and it's children or just the task
|
204
|
+
# @param [Integer] task_id
|
205
|
+
# @param [String] level family|task
|
206
|
+
def pause_task(task_id, level = 'family')
|
207
|
+
current_path = '/api/v1/pause/' << task_id.to_s
|
208
|
+
payload = { 'paused' => true, 'level' => level }.to_json
|
209
|
+
@conn.post(current_path, payload)
|
210
|
+
end
|
211
|
+
|
212
|
+
# Resumes a specific task identified by its task id.
|
213
|
+
# This can resume either the task and it's children or just the task
|
214
|
+
# @param [Integer] task_id
|
215
|
+
# @param [String] level family|task
|
216
|
+
def resume_task(task_id, level = 'family')
|
217
|
+
current_path = '/api/v1/pause/' << task_id.to_s
|
218
|
+
payload = { 'paused' => false, 'level' => level }.to_json
|
219
|
+
@conn.post(current_path, payload)
|
220
|
+
end
|
221
|
+
|
222
|
+
# returns the classes that are either softpaused or softpause-for-update
|
223
|
+
# @param [String] type softpaused | softpause-for-update
|
224
|
+
# @return [Array] Array of wip classes
|
225
|
+
def get_task_class_info(type = '')
|
226
|
+
current_path = '/api/v1/classes/' << type
|
227
|
+
@conn.get(current_path)
|
228
|
+
end
|
229
|
+
|
230
|
+
# Get the status of a wip task by id.
|
231
|
+
# @param [Integer] task_id
|
232
|
+
# @return [Hash{"wip_task" => {"id" => Integer, "status" => Integer}, "time" => timestamp}]
|
233
|
+
def get_wip_task_status(task_id)
|
234
|
+
current_path = "/api/v1/wip/task/#{task_id}/status"
|
235
|
+
@conn.get(current_path)
|
236
|
+
end
|
237
|
+
|
238
|
+
# Blocks until a task is done
|
239
|
+
# @param [Integer] task_id
|
240
|
+
# @param [Integer] max_nap seconds to try before giving up
|
241
|
+
def wait_until_done(task_id, max_nap = 600)
|
242
|
+
wait_until_state(task_id, 'done', max_nap)
|
243
|
+
end
|
244
|
+
|
245
|
+
# Blocks until a task reaches a specific status
|
246
|
+
# @param [Integer] task_id
|
247
|
+
# @param [String] state state to reach
|
248
|
+
# @param [Integer] max_nap seconds to try before giving up
|
249
|
+
def wait_until_state(task_id, state, max_nap)
|
250
|
+
blink_time = 5 # wake up and scan
|
251
|
+
nap_start = Time.now
|
252
|
+
state_method = method("task_#{state}?".to_sym)
|
253
|
+
loop do
|
254
|
+
break if state_method.call(task_id)
|
255
|
+
raise TaskNotDoneError, "Task: #{task_id} has taken too long to complete!" if Time.new > (nap_start + max_nap)
|
256
|
+
sleep blink_time
|
257
|
+
end
|
258
|
+
task_id
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
data/lib/sfrest/theme.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Tell the Factory that there is theme work to do
|
3
|
+
class Theme
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# Sends a theme notification.
|
10
|
+
def send_theme_notification(scope = 'site', event = 'modify', nid = 0, theme = '')
|
11
|
+
current_path = '/api/v1/theme/notification'
|
12
|
+
payload = { 'scope' => scope, 'event' => event, 'nid' => nid, 'theme' => theme }.to_json
|
13
|
+
@conn.post(current_path, payload)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Processes a theme notification.
|
17
|
+
def process_theme_notification(sitegroup_id = 0)
|
18
|
+
current_path = '/api/v1/theme/process'
|
19
|
+
payload = { 'sitegroup_id' => sitegroup_id }.to_json
|
20
|
+
@conn.post(current_path, payload)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Drive updates on the Site Factory
|
3
|
+
class Update
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# Gets the status information.
|
10
|
+
def status_info
|
11
|
+
current_path = '/api/v1/status'
|
12
|
+
@conn.get(current_path)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Modifies the status information.
|
16
|
+
def modify_status(site_creation, site_duplication, domain_management, bulk_operations)
|
17
|
+
current_path = '/api/v1/status'
|
18
|
+
payload = { 'site_creation' => site_creation,
|
19
|
+
'site_duplication' => site_duplication,
|
20
|
+
'domain_management' => domain_management,
|
21
|
+
'bulk_operations' => bulk_operations }.to_json
|
22
|
+
@conn.put(current_path, payload)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Lists vcs refs.
|
26
|
+
def list_vcs_refs(type = 'sites')
|
27
|
+
current_path = '/api/v1/vcs?type=' << type
|
28
|
+
@conn.get(current_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Starts an update.
|
32
|
+
def start_update(ref)
|
33
|
+
update_data = { scope: 'sites', sites_type: 'code, db', sites_ref: ref }
|
34
|
+
update(update_data)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Starts an update. The rest api supports the following
|
38
|
+
# scope: sites|factory|both (defaults to 'sites')
|
39
|
+
# start_time:
|
40
|
+
# sites_type: code|code, db| code, db, registry (defaults to 'code, db')
|
41
|
+
# factory_type: code|code, db (defaults to 'code, db')
|
42
|
+
# sites_ref:
|
43
|
+
# factory_ref:
|
44
|
+
# This method does not filter or validate so that it can be used for
|
45
|
+
# negative cases. (missing data)
|
46
|
+
def update(datum)
|
47
|
+
current_path = '/api/v1/update'
|
48
|
+
payload = datum.to_json
|
49
|
+
@conn.post(current_path, payload)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Gets the list of updates.
|
53
|
+
def update_list
|
54
|
+
current_path = '/api/v1/update'
|
55
|
+
@conn.get(current_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Gets the progress of an update by id.
|
59
|
+
def update_progress(update_id)
|
60
|
+
current_path = '/api/v1/update/' + update_id.to_s + '/status'
|
61
|
+
@conn.get(current_path)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Pauses current update.
|
65
|
+
def pause_update
|
66
|
+
current_path = '/api/v1/update/pause'
|
67
|
+
payload = { 'pause' => true }.to_json
|
68
|
+
@conn.post(current_path, payload)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Resumes current update.
|
72
|
+
def resume_update
|
73
|
+
current_path = '/api/v1/update/pause'
|
74
|
+
payload = { 'pause' => false }.to_json
|
75
|
+
@conn.post(current_path, payload)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/sfrest/user.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Do User actions within the Site Factory
|
3
|
+
class User
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# Gets the complete list of users
|
10
|
+
# Makes multiple requests to the factory to get all the users on the factory
|
11
|
+
# @return [Hash{'count' => Integer, 'users' => Hash}]
|
12
|
+
def user_list
|
13
|
+
page = 1
|
14
|
+
not_done = true
|
15
|
+
count = 0
|
16
|
+
while not_done
|
17
|
+
current_path = '/api/v1/users?page=' << page.to_s
|
18
|
+
res = @conn.get(current_path)
|
19
|
+
if res['users'] == []
|
20
|
+
not_done = false
|
21
|
+
elsif !res['message'].nil?
|
22
|
+
return { 'message' => res['message'] }
|
23
|
+
elsif page == 1
|
24
|
+
count = res['count']
|
25
|
+
users = res['users']
|
26
|
+
else
|
27
|
+
res['users'].each do |user|
|
28
|
+
users << user
|
29
|
+
end
|
30
|
+
end
|
31
|
+
page += 1
|
32
|
+
end
|
33
|
+
{ 'count' => count, 'users' => users }
|
34
|
+
end
|
35
|
+
|
36
|
+
# gets the site ID for the site named sitename
|
37
|
+
# will page through all the sites available searching for the site
|
38
|
+
# @param [String] username drupal username (not email)
|
39
|
+
# @return [Integer] the uid of the drupal user
|
40
|
+
def get_user_id(username)
|
41
|
+
pglimit = 100
|
42
|
+
res = @conn.get('/api/v1/users&limit=' + pglimit.to_s)
|
43
|
+
usercount = res['count'].to_i
|
44
|
+
id = user_data_from_results(res, username, 'uid')
|
45
|
+
return id if id
|
46
|
+
pages = (usercount / pglimit) + 1
|
47
|
+
2.upto(pages) do |i|
|
48
|
+
res = @conn.get('/api/v1/users&limit=' + pglimit.to_s + '?page=' + i.to_s)
|
49
|
+
id = user_data_from_results(res, username, 'uid')
|
50
|
+
return id if id
|
51
|
+
end
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
# Extract the user data for 'key' based on the user result object
|
56
|
+
# @param [Hash] res result from a request to /users
|
57
|
+
# @param [String] username
|
58
|
+
# @param [String] key one of the user data returned (uid, mail, tfa_status...)
|
59
|
+
# @return [Object] Integer, String, Array, Hash depending on the user data
|
60
|
+
def user_data_from_results(res, username, key)
|
61
|
+
users = res['users']
|
62
|
+
users.each do |user|
|
63
|
+
return user[key] if user['name'] == username
|
64
|
+
end
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
|
68
|
+
# Gets the data for user UID
|
69
|
+
# @param [int] uid site id
|
70
|
+
# @return [Hash]
|
71
|
+
def get_user_data(uid)
|
72
|
+
@conn.get('/api/v1/users/' + uid.to_s)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Creates a user.
|
76
|
+
# @param [String] name
|
77
|
+
# @param [String] email
|
78
|
+
# @param [Hash] datum hash with elements :pass => string,
|
79
|
+
# :status => 0|1,
|
80
|
+
# :roles => Array
|
81
|
+
def create_user(name, email, datum = nil)
|
82
|
+
current_path = '/api/v1/users'
|
83
|
+
payload = { name: name, mail: email }
|
84
|
+
payload.merge!(datum) unless datum.nil?
|
85
|
+
@conn.post(current_path, payload.to_json)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Updates a user.
|
89
|
+
# @param [Integer] uid user id of the drupal user to update
|
90
|
+
# @param [Hash] datum hash with elements :name => string, :pass => string,
|
91
|
+
# :status => 0|1, :roles => Array,
|
92
|
+
# :mail => string@string, :tfa_status => 0|1
|
93
|
+
def update_user(uid, datum = nil)
|
94
|
+
current_path = "/api/v1/users/#{uid}/update"
|
95
|
+
payload = datum.to_json unless datum.nil?
|
96
|
+
@conn.put(current_path, payload)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Delete a user.
|
100
|
+
# @param [integer] uid Uid of the user to be deleted
|
101
|
+
def delete_user(uid)
|
102
|
+
current_path = "/api/v1/users/#{uid}"
|
103
|
+
@conn.delete(current_path)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SFRest
|
2
|
+
# Perform actions against variables in the Factory
|
3
|
+
class Variable
|
4
|
+
# @param [SFRest::Connection] conn
|
5
|
+
def initialize(conn)
|
6
|
+
@conn = conn
|
7
|
+
end
|
8
|
+
|
9
|
+
# Gets the list of variables.
|
10
|
+
def variable_list
|
11
|
+
current_path = '/api/v1/variables'
|
12
|
+
@conn.get(current_path)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Gets the value of a specific variable.
|
16
|
+
def get_variable(name)
|
17
|
+
current_path = '/api/v1/variables?name=' << name
|
18
|
+
@conn.get(current_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Sets the key and value of a variable.
|
22
|
+
def set_variable(name, value)
|
23
|
+
current_path = '/api/v1/variables'
|
24
|
+
payload = { 'name' => name, 'value' => value }.to_json
|
25
|
+
@conn.put(current_path, payload)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/sfrest.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# Simple wrappper around RestClient.Resource
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__)) unless
|
3
|
+
$LOAD_PATH.include?(File.dirname(__FILE__)) ||
|
4
|
+
$LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
5
|
+
|
6
|
+
require 'excon'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
require 'sfrest/audit'
|
10
|
+
require 'sfrest/backup'
|
11
|
+
require 'sfrest/connection'
|
12
|
+
require 'sfrest/domains'
|
13
|
+
require 'sfrest/error'
|
14
|
+
require 'sfrest/group'
|
15
|
+
require 'sfrest/pathbuilder'
|
16
|
+
require 'sfrest/role'
|
17
|
+
require 'sfrest/site'
|
18
|
+
require 'sfrest/stage'
|
19
|
+
require 'sfrest/task'
|
20
|
+
require 'sfrest/theme'
|
21
|
+
require 'sfrest/update'
|
22
|
+
require 'sfrest/user'
|
23
|
+
require 'sfrest/variable'
|
24
|
+
|
25
|
+
# Base Class for SF rest API sdk
|
26
|
+
module SFRest
|
27
|
+
# Class set to work as an sdk for the Site Factory Rest api
|
28
|
+
# most of the interesting pieces happen in the connection class and others
|
29
|
+
class << self
|
30
|
+
attr_accessor :base_url, :user, :password, :conn
|
31
|
+
|
32
|
+
# returns a connection object to the SF Rest api for a specific factory
|
33
|
+
# @param [String] url Base url of the Site Factory
|
34
|
+
# @param [String] user username of a user on the factory
|
35
|
+
# @param [String] password api password for the user on the factory
|
36
|
+
def new(url, user, password)
|
37
|
+
@base_url = url
|
38
|
+
@user = user
|
39
|
+
@password = password
|
40
|
+
@conn = SFRest::Connection.new(@base_url, @user, @password)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sfrest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.8
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ACSF Engineering
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: excon
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.11'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.11'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: webmock
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.24'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.24'
|
83
|
+
description: Wrapper methods around the ACSF Rest API.
|
84
|
+
email:
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- lib/sfrest.rb
|
90
|
+
- lib/sfrest/audit.rb
|
91
|
+
- lib/sfrest/backup.rb
|
92
|
+
- lib/sfrest/connection.rb
|
93
|
+
- lib/sfrest/domains.rb
|
94
|
+
- lib/sfrest/error.rb
|
95
|
+
- lib/sfrest/group.rb
|
96
|
+
- lib/sfrest/pathbuilder.rb
|
97
|
+
- lib/sfrest/role.rb
|
98
|
+
- lib/sfrest/site.rb
|
99
|
+
- lib/sfrest/stage.rb
|
100
|
+
- lib/sfrest/task.rb
|
101
|
+
- lib/sfrest/theme.rb
|
102
|
+
- lib/sfrest/update.rb
|
103
|
+
- lib/sfrest/user.rb
|
104
|
+
- lib/sfrest/variable.rb
|
105
|
+
- lib/sfrest/version.rb
|
106
|
+
homepage: http://github.com/acquia/sf-sdk-ruby
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.5.1
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Acquia Site Factory Rest API.
|
130
|
+
test_files: []
|