fog-profitbricks 3.0.0 → 4.0.0
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 +4 -4
- data/.travis.yml +0 -3
- data/README.md +437 -3
- data/lib/fog/profitbricks/compute.rb +138 -80
- data/lib/fog/profitbricks/helpers/compute/data_helper.rb +1 -1
- data/lib/fog/profitbricks/models/compute/contract_resource.rb +35 -0
- data/lib/fog/profitbricks/models/compute/contract_resources.rb +19 -0
- data/lib/fog/profitbricks/models/compute/group.rb +66 -0
- data/lib/fog/profitbricks/models/compute/groups.rb +26 -0
- data/lib/fog/profitbricks/models/compute/lan.rb +3 -0
- data/lib/fog/profitbricks/models/compute/location.rb +1 -0
- data/lib/fog/profitbricks/models/compute/resource.rb +30 -0
- data/lib/fog/profitbricks/models/compute/resources.rb +32 -0
- data/lib/fog/profitbricks/models/compute/share.rb +59 -0
- data/lib/fog/profitbricks/models/compute/shares.rb +33 -0
- data/lib/fog/profitbricks/models/compute/user.rb +75 -0
- data/lib/fog/profitbricks/models/compute/users.rb +45 -0
- data/lib/fog/profitbricks/models/compute/volume.rb +2 -0
- data/lib/fog/profitbricks/requests/compute/add_share.rb +64 -0
- data/lib/fog/profitbricks/requests/compute/add_user_to_group.rb +89 -0
- data/lib/fog/profitbricks/requests/compute/create_group.rb +85 -0
- data/lib/fog/profitbricks/requests/compute/create_lan.rb +1 -0
- data/lib/fog/profitbricks/requests/compute/create_user.rb +83 -0
- data/lib/fog/profitbricks/requests/compute/create_volume.rb +1 -0
- data/lib/fog/profitbricks/requests/compute/delete_group.rb +43 -0
- data/lib/fog/profitbricks/requests/compute/delete_share.rb +42 -0
- data/lib/fog/profitbricks/requests/compute/delete_user.rb +43 -0
- data/lib/fog/profitbricks/requests/compute/get_all_contract_resources.rb +55 -0
- data/lib/fog/profitbricks/requests/compute/get_all_groups.rb +62 -0
- data/lib/fog/profitbricks/requests/compute/get_all_lans.rb +1 -0
- data/lib/fog/profitbricks/requests/compute/get_all_resources.rb +66 -0
- data/lib/fog/profitbricks/requests/compute/get_all_shares.rb +46 -0
- data/lib/fog/profitbricks/requests/compute/get_all_users.rb +70 -0
- data/lib/fog/profitbricks/requests/compute/get_group.rb +64 -0
- data/lib/fog/profitbricks/requests/compute/get_group_users.rb +78 -0
- data/lib/fog/profitbricks/requests/compute/get_lan.rb +1 -0
- data/lib/fog/profitbricks/requests/compute/get_resource_by_type.rb +73 -0
- data/lib/fog/profitbricks/requests/compute/get_resources_by_type.rb +44 -0
- data/lib/fog/profitbricks/requests/compute/get_share.rb +52 -0
- data/lib/fog/profitbricks/requests/compute/get_user.rb +72 -0
- data/lib/fog/profitbricks/requests/compute/remove_user_from_group.rb +49 -0
- data/lib/fog/profitbricks/requests/compute/update_group.rb +85 -0
- data/lib/fog/profitbricks/requests/compute/update_lan.rb +1 -0
- data/lib/fog/profitbricks/requests/compute/update_share.rb +67 -0
- data/lib/fog/profitbricks/requests/compute/update_user.rb +94 -0
- data/lib/fog/profitbricks/version.rb +1 -1
- data/tests/profitbricks/models/compute/compute_tests.rb +6 -0
- data/tests/profitbricks/requests/compute/location_tests.rb +4 -4
- data/tests/profitbricks/requests/compute/nic_tests.rb +7 -19
- data/tests/profitbricks/requests/compute/server_tests.rb +9 -21
- metadata +58 -28
- data/gemfiles/Gemfile.1.9.2- +0 -5
@@ -11,6 +11,7 @@ module Fog
|
|
11
11
|
# properties
|
12
12
|
attribute :name
|
13
13
|
attribute :public
|
14
|
+
attribute :ip_failover, :aliases => 'ipFailover'
|
14
15
|
|
15
16
|
# metadata
|
16
17
|
attribute :created_date, :aliases => 'createdDate', :type => :time
|
@@ -33,6 +34,7 @@ module Fog
|
|
33
34
|
properties = {}
|
34
35
|
properties[:name] = name if name
|
35
36
|
properties[:public] = public if public
|
37
|
+
properties[:ipFailover] = ip_failover if ip_failover
|
36
38
|
|
37
39
|
entities = {}
|
38
40
|
entities[:nics] = nics if nics
|
@@ -48,6 +50,7 @@ module Fog
|
|
48
50
|
options = {}
|
49
51
|
options[:name] = name if name
|
50
52
|
options[:public] = public if public
|
53
|
+
options[:ipFailover] = ip_failover if ip_failover
|
51
54
|
|
52
55
|
data = service.update_lan(datacenter_id, id, options)
|
53
56
|
merge_attributes(flatten(data.body))
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path('../../../helpers/compute/data_helper', __FILE__)
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Compute
|
5
|
+
class ProfitBricks
|
6
|
+
class Resource < Fog::Models::ProfitBricks::Base
|
7
|
+
include Fog::Helpers::ProfitBricks::DataHelper
|
8
|
+
|
9
|
+
identity :id
|
10
|
+
|
11
|
+
# metadata
|
12
|
+
attribute :created_date, :aliases => 'createdDate'
|
13
|
+
attribute :created_by, :aliases => 'createdBy'
|
14
|
+
attribute :etag
|
15
|
+
attribute :last_modified_date, :aliases => 'lastModifiedDate'
|
16
|
+
attribute :last_modified_by, :aliases => 'lastModifiedBy'
|
17
|
+
attribute :state
|
18
|
+
|
19
|
+
# entities
|
20
|
+
attribute :groups
|
21
|
+
|
22
|
+
attr_accessor :options
|
23
|
+
|
24
|
+
def initialize(attributes = {})
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path('../resource', __FILE__)
|
2
|
+
require File.expand_path('../../../helpers/compute/data_helper', __FILE__)
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Compute
|
6
|
+
class ProfitBricks
|
7
|
+
class Resources < Fog::Collection
|
8
|
+
include Fog::Helpers::ProfitBricks::DataHelper
|
9
|
+
model Fog::Compute::ProfitBricks::Resource
|
10
|
+
|
11
|
+
def all
|
12
|
+
response = service.get_all_resources
|
13
|
+
|
14
|
+
load(response.body['items'].each { |resource| flatten(resource) })
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_resource_by_type(resource_type, resource_id)
|
18
|
+
response = service.get_resource_by_type(resource_type, resource_id)
|
19
|
+
share = response.body
|
20
|
+
|
21
|
+
new(flatten(share))
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_by_type(resource_type)
|
25
|
+
response = service.get_resources_by_type(resource_type)
|
26
|
+
|
27
|
+
load(response.body['items'].each { |resource| flatten(resource) })
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path('../../../helpers/compute/data_helper', __FILE__)
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Compute
|
5
|
+
class ProfitBricks
|
6
|
+
class Share < Fog::Models::ProfitBricks::Base
|
7
|
+
include Fog::Helpers::ProfitBricks::DataHelper
|
8
|
+
|
9
|
+
identity :id
|
10
|
+
|
11
|
+
# properties
|
12
|
+
attribute :edit_privilege, :aliases => 'editPrivilege'
|
13
|
+
attribute :share_privilege, :aliases => 'sharePrivilege'
|
14
|
+
|
15
|
+
attribute :group_id, :aliases => 'groupId'
|
16
|
+
attribute :resource_id, :aliases => 'resourceId'
|
17
|
+
|
18
|
+
attr_accessor :options
|
19
|
+
|
20
|
+
def initialize(attributes = {})
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def save
|
25
|
+
requires :group_id, :resource_id
|
26
|
+
|
27
|
+
options = {}
|
28
|
+
|
29
|
+
options[:editPrivilege] = edit_privilege if edit_privilege
|
30
|
+
options[:sharePrivilege] = share_privilege if share_privilege
|
31
|
+
|
32
|
+
data = service.add_share(group_id, resource_id, options).body
|
33
|
+
data['group_id'] = group_id
|
34
|
+
data['resource_id'] = resource_id
|
35
|
+
merge_attributes(flatten(data))
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
def update
|
40
|
+
requires :group_id, :resource_id
|
41
|
+
|
42
|
+
options = {}
|
43
|
+
options[:editPrivilege] = edit_privilege if edit_privilege
|
44
|
+
options[:sharePrivilege] = share_privilege if share_privilege
|
45
|
+
|
46
|
+
data = service.update_share(group_id, resource_id, options)
|
47
|
+
merge_attributes(flatten(data.body))
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
def delete
|
52
|
+
requires :group_id, :resource_id
|
53
|
+
service.delete_share(group_id, resource_id)
|
54
|
+
true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path('../share', __FILE__)
|
2
|
+
require File.expand_path('../../../helpers/compute/data_helper', __FILE__)
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Compute
|
6
|
+
class ProfitBricks
|
7
|
+
class Shares < Fog::Collection
|
8
|
+
include Fog::Helpers::ProfitBricks::DataHelper
|
9
|
+
model Fog::Compute::ProfitBricks::Share
|
10
|
+
|
11
|
+
def all(group_id)
|
12
|
+
result = service.get_all_shares(group_id)
|
13
|
+
|
14
|
+
load(result.body['items'].each do |share|
|
15
|
+
share['group_id'] = group_id
|
16
|
+
share['resource_id'] = share['id']
|
17
|
+
flatten(share)
|
18
|
+
end)
|
19
|
+
end
|
20
|
+
|
21
|
+
def get(group_id, resource_id)
|
22
|
+
response = service.get_share(group_id, resource_id)
|
23
|
+
share = response.body
|
24
|
+
|
25
|
+
share['group_id'] = group_id
|
26
|
+
share['resource_id'] = resource_id
|
27
|
+
|
28
|
+
new(flatten(share))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require File.expand_path('../../../helpers/compute/data_helper', __FILE__)
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Compute
|
5
|
+
class ProfitBricks
|
6
|
+
class User < Fog::Models::ProfitBricks::Base
|
7
|
+
include Fog::Helpers::ProfitBricks::DataHelper
|
8
|
+
|
9
|
+
identity :id
|
10
|
+
|
11
|
+
# metadata
|
12
|
+
attribute :etag
|
13
|
+
attribute :creation_date, :aliases => 'creationDate'
|
14
|
+
attribute :last_login, :aliases => 'lastLogin'
|
15
|
+
|
16
|
+
# properties
|
17
|
+
attribute :firstname
|
18
|
+
attribute :lastname
|
19
|
+
attribute :email
|
20
|
+
attribute :password
|
21
|
+
attribute :administrator
|
22
|
+
attribute :force_sec_auth, :aliases => 'forceSecAuth'
|
23
|
+
attribute :sec_auth_active, :aliases => 'secAuthActive'
|
24
|
+
|
25
|
+
# metadata
|
26
|
+
attribute :owns
|
27
|
+
attribute :groups
|
28
|
+
|
29
|
+
attr_accessor :options
|
30
|
+
|
31
|
+
def initialize(attributes = {})
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
def save
|
36
|
+
requires :firstname, :lastname, :email, :password
|
37
|
+
|
38
|
+
options = {}
|
39
|
+
|
40
|
+
options[:firstname] = firstname
|
41
|
+
options[:lastname] = lastname
|
42
|
+
options[:email] = email
|
43
|
+
options[:password] = password
|
44
|
+
options[:administrator] = administrator if administrator
|
45
|
+
options[:forceSecAuth] = force_sec_auth if force_sec_auth
|
46
|
+
|
47
|
+
data = service.create_user(options)
|
48
|
+
merge_attributes(flatten(data.body))
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
def update
|
53
|
+
requires :id, :firstname, :lastname, :email, :administrator, :force_sec_auth
|
54
|
+
|
55
|
+
options = {}
|
56
|
+
options[:firstname] = firstname
|
57
|
+
options[:lastname] = lastname
|
58
|
+
options[:email] = email
|
59
|
+
options[:administrator] = administrator
|
60
|
+
options[:forceSecAuth] = force_sec_auth
|
61
|
+
|
62
|
+
data = service.update_user(id, options)
|
63
|
+
merge_attributes(flatten(data.body))
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
def delete
|
68
|
+
requires :id
|
69
|
+
service.delete_user(id)
|
70
|
+
true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path('../user', __FILE__)
|
2
|
+
require File.expand_path('../../../helpers/compute/data_helper', __FILE__)
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Compute
|
6
|
+
class ProfitBricks
|
7
|
+
class Users < Fog::Collection
|
8
|
+
include Fog::Helpers::ProfitBricks::DataHelper
|
9
|
+
model Fog::Compute::ProfitBricks::User
|
10
|
+
|
11
|
+
def all
|
12
|
+
response = service.get_all_users
|
13
|
+
|
14
|
+
load(response.body['items'].each { |user| flatten(user) })
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(user_id)
|
18
|
+
response = service.get_user(user_id)
|
19
|
+
share = response.body
|
20
|
+
|
21
|
+
new(flatten(share))
|
22
|
+
end
|
23
|
+
|
24
|
+
def list_group_users(group_id)
|
25
|
+
response = service.get_group_users(group_id)
|
26
|
+
|
27
|
+
load(response.body['items'].each { |user| flatten(user) })
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_group_user(group_id, user_id)
|
31
|
+
response = service.add_user_to_group(group_id, user_id)
|
32
|
+
user = response.body
|
33
|
+
|
34
|
+
new(flatten(user))
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_group_user(group_id, user_id)
|
38
|
+
service.remove_user_from_group(group_id, user_id)
|
39
|
+
|
40
|
+
true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -12,6 +12,7 @@ module Fog
|
|
12
12
|
attribute :name
|
13
13
|
attribute :size
|
14
14
|
attribute :image
|
15
|
+
attribute :image_alias, :aliases => 'imageAlias'
|
15
16
|
attribute :bus
|
16
17
|
attribute :type
|
17
18
|
attribute :availability_zone, :aliases => 'availabilityZone'
|
@@ -54,6 +55,7 @@ module Fog
|
|
54
55
|
options[:size] = size
|
55
56
|
options[:bus] = bus if bus
|
56
57
|
options[:image] = image if image
|
58
|
+
options[:imageAlias] = image_alias if image_alias
|
57
59
|
options[:type] = type
|
58
60
|
options[:licenceType] = licence_type if licence_type
|
59
61
|
options[:imagePassword] = image_password if image_password
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class ProfitBricks
|
4
|
+
class Real
|
5
|
+
# Adds a specific resource share to a group and optionally allows the setting of permissions
|
6
|
+
# for that resource. As an example, you might use this to grant permissions to use an image
|
7
|
+
# or snapshot to a specific group.
|
8
|
+
#
|
9
|
+
# ==== Parameters
|
10
|
+
# * options<~Hash>:
|
11
|
+
# * group_id<~String> - Required, The ID of the specific group to add a resource to.
|
12
|
+
# * resource_id<~String> - Required, The ID of the specific resource to add.
|
13
|
+
# * editPrivilege<~Boolean> - The group has permission to edit privileges on this resource.
|
14
|
+
# * sharePrivilege<~Boolean> - The group has permission to share this resource.
|
15
|
+
#
|
16
|
+
# ==== Returns
|
17
|
+
# * response<~Excon::Response>:
|
18
|
+
# * body<~Hash>:
|
19
|
+
# * id<~String> - The resource's unique identifier.
|
20
|
+
# * type<~String> - The type of the created resource.
|
21
|
+
# * href<~String> - URL to the object's representation (absolute path).
|
22
|
+
# * properties<~Hash> - A collection of properties.
|
23
|
+
# * editPrivilege<~Boolean> - The group has permission to edit privileges on this resource.
|
24
|
+
# * sharePrivilege<~Boolean> - The group has permission to share this resource.
|
25
|
+
#
|
26
|
+
# {ProfitBricks API Documentation}[https://devops.profitbricks.com/api/cloud/v4/#add-a-share]
|
27
|
+
def add_share(group_id, resource_id, options = {})
|
28
|
+
share = {
|
29
|
+
:properties => options
|
30
|
+
}
|
31
|
+
|
32
|
+
request(
|
33
|
+
:expects => [202],
|
34
|
+
:method => 'POST',
|
35
|
+
:path => "/um/groups/#{group_id}/shares/#{resource_id}",
|
36
|
+
:body => Fog::JSON.encode(share)
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Mock
|
42
|
+
def add_share(group_id, resource_id, options = {})
|
43
|
+
response = Excon::Response.new
|
44
|
+
response.status = 202
|
45
|
+
|
46
|
+
share = {
|
47
|
+
'id' => resource_id,
|
48
|
+
'type' => 'resource',
|
49
|
+
'href' => "https=>//api.profitbricks.com/rest/v4/um/groups/#{group_id}/shares/#{resource_id}",
|
50
|
+
'properties' => {
|
51
|
+
'editPrivilege' => options[:edit_privilege],
|
52
|
+
'sharePrivilege' => options[:share_privilege]
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
data[:shares]['items'] << share
|
57
|
+
|
58
|
+
response.body = share
|
59
|
+
response
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class ProfitBricks
|
4
|
+
class Real
|
5
|
+
# Add an existing user to a group.
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * group_id<~String> - Required, The ID of the specific group you want to add a user to.
|
9
|
+
# * user_id<~String> - Required, The ID of the specific user to add to the group.
|
10
|
+
#
|
11
|
+
# ==== Returns
|
12
|
+
# * response<~Excon::Response>:
|
13
|
+
# * body<~Hash>:
|
14
|
+
# * id<~String> - The resource's unique identifier.
|
15
|
+
# * type<~String> - The type of the created resource.
|
16
|
+
# * href<~String> - URL to the object's representation (absolute path).
|
17
|
+
# * metadata<~Hash> - Hash containing metadata for the user.
|
18
|
+
# * etag<~String> - ETag of the user.
|
19
|
+
# * creationDate<~String> - A time and date stamp indicating when the user was created.
|
20
|
+
# * lastLogin<~String> - A time and date stamp indicating when the user last logged in.
|
21
|
+
# * properties<~Hash> - Hash containing the user's properties.
|
22
|
+
# * firstname<~String> - The first name of the user.
|
23
|
+
# * lastname<~String> - The last name of the user.
|
24
|
+
# * email<~String> - The e-mail address of the user.
|
25
|
+
# * administrator<~Boolean> - Indicates if the user has administrative rights.
|
26
|
+
# * forceSecAuth<~Boolean> - Indicates if secure (two-factor) authentication was enabled for the user.
|
27
|
+
# * secAuthActive<~Boolean> - Indicates if secure (two-factor) authentication is enabled for the user.
|
28
|
+
# * entities<~Hash> - Hash containing resources the user owns, and groups the user is a member of.
|
29
|
+
# * owns<~Hash> - Hash containing resources the user owns.
|
30
|
+
# * id<~String> - The resource's unique identifier.
|
31
|
+
# * type<~String> - The type of the created resource.
|
32
|
+
# * href<~String> - URL to the object's representation (absolute path).
|
33
|
+
# * items<~Array>
|
34
|
+
# * id<~String> - The resource's unique identifier.
|
35
|
+
# * type<~String> - The type of the created resource.
|
36
|
+
# * href<~String> - URL to the object's representation (absolute path).
|
37
|
+
# * groups<~Hash> - Hash containing groups the user is a member of.
|
38
|
+
# * id<~String> - The resource's unique identifier.
|
39
|
+
# * type<~String> - The type of the created resource.
|
40
|
+
# * href<~String> - URL to the object's representation (absolute path).
|
41
|
+
# * items<~Array>
|
42
|
+
# * id<~String> - The resource's unique identifier.
|
43
|
+
# * type<~String> - The type of the created resource.
|
44
|
+
# * href<~String> - URL to the object's representation (absolute path).
|
45
|
+
#
|
46
|
+
# {ProfitBricks API Documentation}[https://devops.profitbricks.com/api/cloud/v4/#add-user-to-group]
|
47
|
+
def add_user_to_group(group_id, user_id)
|
48
|
+
usr = {
|
49
|
+
:id => user_id
|
50
|
+
}
|
51
|
+
|
52
|
+
request(
|
53
|
+
:expects => [202],
|
54
|
+
:method => 'POST',
|
55
|
+
:path => "/um/groups/#{group_id}/users",
|
56
|
+
:body => Fog::JSON.encode(usr)
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Mock
|
62
|
+
def add_user_to_group(group_id, user_id)
|
63
|
+
response = Excon::Response.new
|
64
|
+
response.status = 202
|
65
|
+
|
66
|
+
if group = data[:groups]['items'].find do |grp|
|
67
|
+
grp["id"] == group_id
|
68
|
+
end
|
69
|
+
else
|
70
|
+
raise Excon::Error::HTTPStatus, "The requested resource could not be found"
|
71
|
+
end
|
72
|
+
|
73
|
+
if user = data[:users]['items'].find do |usr|
|
74
|
+
usr["id"] == user_id
|
75
|
+
end
|
76
|
+
else
|
77
|
+
raise Excon::Error::HTTPStatus, "The requested resource could not be found"
|
78
|
+
end
|
79
|
+
|
80
|
+
group['users'] << user
|
81
|
+
user['groups'] << group
|
82
|
+
|
83
|
+
response.body = user
|
84
|
+
response
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|