Skip to content

Commit e1374d6

Browse files
Added S3 user management
Signed-off-by: utkarshbhatthere <[email protected]>
1 parent c31263e commit e1374d6

File tree

12 files changed

+726
-12
lines changed

12 files changed

+726
-12
lines changed

.github/workflows/tests.yml

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,24 @@ jobs:
4545
runs-on: ubuntu-22.04
4646
needs: build-microceph
4747
steps:
48+
- name: Checkout code
49+
uses: actions/checkout@v3
50+
4851
- name: Download snap
4952
uses: actions/download-artifact@v3
5053
with:
5154
name: snaps
55+
56+
- name: Install dependencies
57+
run: |
58+
# Python script dependencies
59+
sudo python -m pip install --upgrade pip
60+
sudo pip install flake8 pep8-naming boto3
61+
62+
- name: Lint check
63+
run: |
64+
flake8 . --count --show-source --statistics
65+
5266
- name: Install and setup
5367
run: |
5468
set -eux
@@ -160,15 +174,9 @@ jobs:
160174
- name: Exercise RGW
161175
run: |
162176
set -eux
163-
sudo microceph.ceph status
164-
sudo systemctl status snap.microceph.rgw
165-
sudo microceph.radosgw-admin user create --uid=test --display-name=test
166-
sudo microceph.radosgw-admin key create --uid=test --key-type=s3 --access-key fooAccessKey --secret-key fooSecretKey
167-
sudo apt-get -qq install s3cmd
168-
echo hello-radosgw > ~/test.txt
169-
s3cmd --host localhost --host-bucket="localhost/%(bucket)" --access_key=fooAccessKey --secret_key=fooSecretKey --no-ssl mb s3://testbucket
170-
s3cmd --host localhost --host-bucket="localhost/%(bucket)" --access_key=fooAccessKey --secret_key=fooSecretKey --no-ssl put -P ~/test.txt s3://testbucket
171-
curl -s http://localhost/testbucket/test.txt | grep -F hello-radosgw
177+
sudo microceph s3-user create testUser --json > keys.json
178+
sudo python3 ./scripts/appS3.py http://localhost:80 keys.json --obj-num 2
179+
sudo microceph s3-user delete testUser
172180
173181
- name: Test Cluster Config
174182
run: |

docs/conf.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
templates_path = ['_templates']
2020
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'sphinxenv']
2121

22-
23-
2422
# -- Options for HTML output -------------------------------------------------
2523
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
2624

docs/how-to/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ These how-to guides will cover key operations and processes in Microceph.
99
cluster-cfg
1010
service-placement
1111
service-migration
12+
s3-user
1213

docs/how-to/s3-user.rst

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
Use S3 user management on MicroCeph
2+
===================================
3+
4+
MicroCeph provides an easy to use interface for creating, viewing and deleting s3 users for interfacing with the RGW endpoint.
5+
This enables smooth and easy access to Object Storage.
6+
7+
.. list-table:: Supported s3-user operations
8+
:widths: 30 70
9+
:header-rows: 1
10+
11+
* - Operation
12+
- Description
13+
* - create
14+
- Create provided s3 (radosgw) user with optionally provided access-key and secret
15+
* - delete
16+
- Delete provided s3 (radosgw) user
17+
* - get
18+
- Fetch key information of the provided s3 (radosgw) user
19+
* - list
20+
- List all s3 (radosgw) users
21+
.. note:: Users can additionally provide --json flag to create and get commands to dump a much detailed
22+
23+
1. Create an S3 user (optionally provide --access-key --secret and --json)
24+
25+
.. code-block:: shell
26+
27+
$ sudo microceph s3-user create newTestUser --access-key=ThisIsAccessKey --secret=ThisIsSecret --json
28+
{
29+
"user_id": "newTestUser",
30+
"display_name": "newTestUser",
31+
"email": "",
32+
"suspended": 0,
33+
"max_buckets": 1000,
34+
"subusers": [],
35+
"keys": [
36+
{
37+
"user": "newTestUser",
38+
"access_key": "ThisIsAccessKey",
39+
"secret_key": "ThisIsSecret"
40+
}
41+
],
42+
"swift_keys": [],
43+
"caps": [],
44+
"op_mask": "read, write, delete",
45+
"default_placement": "",
46+
"default_storage_class": "",
47+
"placement_tags": [],
48+
"bucket_quota": {
49+
"enabled": false,
50+
"check_on_raw": false,
51+
"max_size": -1,
52+
"max_size_kb": 0,
53+
"max_objects": -1
54+
},
55+
"user_quota": {
56+
"enabled": false,
57+
"check_on_raw": false,
58+
"max_size": -1,
59+
"max_size_kb": 0,
60+
"max_objects": -1
61+
},
62+
"temp_url_keys": [],
63+
"type": "rgw",
64+
"mfa_ids": []
65+
}
66+
67+
2. List all s3 users :
68+
69+
.. code-block:: shell
70+
71+
$ sudo microceph s3-user list
72+
+---+-------------+
73+
| # | NAME |
74+
+---+-------------+
75+
| 1 | newTestUser |
76+
+---+-------------+
77+
| 2 | testUser |
78+
+---+-------------+
79+
80+
3. Get details of a an s3 user (optionally use --json flag to get complete details):
81+
82+
.. code-block:: shell
83+
84+
$ sudo microceph s3-user get testUser
85+
+----------+----------------------+---------+
86+
| NAME | ACCESS KEY | SECRET |
87+
+----------+----------------------+---------+
88+
| testUser | ThisIsAccessKey | ThisIsSecret |
89+
+----------+----------------------+---------+
90+
91+
4. Delete an s3 user:
92+
93+
.. code-block:: shell
94+
95+
$ sudo microceph s3-user delete newTestUser
96+
$ sudo microceph s3-user list
97+
+---+----------+
98+
| # | NAME |
99+
+---+----------+
100+
| 1 | testUser |
101+
+---+----------+
102+
103+
.. warning:: All the related buckets+objects should be deleted before deletion of the user.
104+
105+
For more fine-tuned user management use `radosgw-admin CLI <https://docs.ceph.com/en/latest/man/8/radosgw-admin/>`_
106+

microceph/api/endpoints.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ var Endpoints = []rest.Endpoint{
1010
disksCmd,
1111
resourcesCmd,
1212
servicesCmd,
13-
rgwServiceCmd,
1413
configsCmd,
1514
restartServiceCmd,
1615
mdsServiceCmd,
1716
mgrServiceCmd,
1817
monServiceCmd,
1918
rgwServiceCmd,
19+
s3Cmd,
2020
}

microceph/api/s3.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package api
2+
3+
import (
4+
"encoding/json"
5+
"net/http"
6+
7+
"github.com/canonical/lxd/lxd/response"
8+
"github.com/canonical/microceph/microceph/api/types"
9+
"github.com/canonical/microceph/microceph/ceph"
10+
"github.com/canonical/microcluster/rest"
11+
"github.com/canonical/microcluster/state"
12+
)
13+
14+
// /1.0/resources endpoint.
15+
var s3Cmd = rest.Endpoint{
16+
Path: "services/rgw/user",
17+
Get: rest.EndpointAction{Handler: cmdS3Get, ProxyTarget: true},
18+
Put: rest.EndpointAction{Handler: cmdS3Put, ProxyTarget: true},
19+
Delete: rest.EndpointAction{Handler: cmdS3Delete, ProxyTarget: true},
20+
}
21+
22+
func cmdS3Get(s *state.State, r *http.Request) response.Response {
23+
var err error
24+
var req types.S3User
25+
26+
err = json.NewDecoder(r.Body).Decode(&req)
27+
if err != nil {
28+
return response.InternalError(err)
29+
}
30+
31+
// If a user name is passed.
32+
if len(req.Name) > 0 {
33+
getOutput, err := ceph.GetS3User(req)
34+
if err != nil {
35+
return response.SmartError(err)
36+
}
37+
return response.SyncResponse(true, getOutput)
38+
} else {
39+
listOutput, err := ceph.ListS3Users()
40+
if err != nil {
41+
return response.SmartError(err)
42+
}
43+
return response.SyncResponse(true, listOutput)
44+
}
45+
}
46+
47+
func cmdS3Put(s *state.State, r *http.Request) response.Response {
48+
var err error
49+
var req types.S3User
50+
51+
err = json.NewDecoder(r.Body).Decode(&req)
52+
if err != nil {
53+
return response.InternalError(err)
54+
}
55+
56+
output, err := ceph.CreateS3User(req)
57+
if err != nil {
58+
return response.SmartError(err)
59+
}
60+
61+
return response.SyncResponse(true, output)
62+
}
63+
64+
func cmdS3Delete(s *state.State, r *http.Request) response.Response {
65+
var err error
66+
var req types.S3User
67+
68+
err = json.NewDecoder(r.Body).Decode(&req)
69+
if err != nil {
70+
return response.InternalError(err)
71+
}
72+
73+
err = ceph.DeleteS3User(req.Name)
74+
if err != nil {
75+
return response.SmartError(err)
76+
}
77+
78+
return response.EmptySyncResponse
79+
}

microceph/api/types/s3.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Package types provides shared types and structs.
2+
package types
3+
4+
// holds the name, access and secretkey required for exposing an S3 user.
5+
type S3User struct {
6+
Name string `json:"name" yaml:"name"`
7+
Key string `json:"key" yaml:"key"`
8+
Secret string `json:"secret" yaml:"secret"`
9+
}

microceph/ceph/rgw_s3.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package ceph
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
7+
"github.com/canonical/microceph/microceph/api/types"
8+
)
9+
10+
func CreateS3User(user types.S3User) (string, error) {
11+
args := []string{
12+
"user",
13+
"create",
14+
fmt.Sprintf("--uid=%s", user.Name),
15+
fmt.Sprintf("--display-name=%s", user.Name),
16+
}
17+
18+
if len(user.Key) > 0 {
19+
args = append(args, fmt.Sprintf("--access-key=%s", user.Key))
20+
}
21+
22+
if len(user.Secret) > 0 {
23+
args = append(args, fmt.Sprintf("--secret=%s", user.Secret))
24+
}
25+
26+
output, err := processExec.RunCommand("radosgw-admin", args...)
27+
if err != nil {
28+
return "", err
29+
}
30+
31+
return output, nil
32+
}
33+
34+
func GetS3User(user types.S3User) (string, error) {
35+
args := []string{
36+
"user",
37+
"info",
38+
fmt.Sprintf("--uid=%s", user.Name),
39+
}
40+
41+
output, err := processExec.RunCommand("radosgw-admin", args...)
42+
if err != nil {
43+
return "", err
44+
}
45+
46+
return output, nil
47+
}
48+
49+
func ListS3Users() ([]string, error) {
50+
args := []string{
51+
"user",
52+
"list",
53+
}
54+
55+
output, err := processExec.RunCommand("radosgw-admin", args...)
56+
if err != nil {
57+
return []string{}, err
58+
}
59+
60+
ret := []string{}
61+
json.Unmarshal([]byte(output), &ret)
62+
return ret, nil
63+
}
64+
65+
func DeleteS3User(name string) error {
66+
args := []string{
67+
"user",
68+
"rm",
69+
fmt.Sprintf("--uid=%s", name),
70+
}
71+
72+
_, err := processExec.RunCommand("radosgw-admin", args...)
73+
if err != nil {
74+
return err
75+
}
76+
77+
return nil
78+
}

0 commit comments

Comments
 (0)