sfrest 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|