Skip to content

Commit ab6fa2f

Browse files
authored
Merge pull request ceph#54048 from rhcs-dashboard/rgw-bucket-policy
mgr/dashboard: get object bucket policies for a bucket Reviewed-by: Pedro Gonzalez Gomez <[email protected]> Reviewed-by: Ankush Behl <[email protected]>
2 parents 09c4ea8 + 40f053a commit ab6fa2f

File tree

5 files changed

+150
-91
lines changed

5 files changed

+150
-91
lines changed

src/pybind/mgr/dashboard/controllers/rgw.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,10 @@ def _set_locking(self, owner, daemon_name, bucket_name, mode,
276276
retention_period_days,
277277
retention_period_years)
278278

279+
def _get_policy(self, bucket: str):
280+
rgw_client = RgwClient.admin_instance()
281+
return rgw_client.get_bucket_policy(bucket)
282+
279283
@staticmethod
280284
def strip_tenant_from_bucket_name(bucket_name):
281285
# type (str) -> str
@@ -328,6 +332,7 @@ def get(self, bucket, daemon_name=None):
328332
result['encryption'] = encryption['Status']
329333
result['versioning'] = versioning['Status']
330334
result['mfa_delete'] = versioning['MfaDelete']
335+
result['policy'] = self._get_policy(bucket_name)
331336

332337
# Append the locking configuration.
333338
locking = self._get_locking(result['owner'], daemon_name, bucket_name)
Lines changed: 121 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,125 @@
11
<ng-container *ngIf="selection">
2-
<table class="table table-striped table-bordered">
3-
<tbody>
4-
<tr>
5-
<td i18n
6-
class="bold w-25">Versioning</td>
7-
<td class="w-75">{{ selection.versioning }}</td>
8-
</tr>
9-
<tr>
10-
<td i18n
11-
class="bold">Encryption</td>
12-
<td>{{ selection.encryption }}</td>
13-
</tr>
14-
<tr>
15-
<td i18n
16-
class="bold">MFA Delete</td>
17-
<td>{{ selection.mfa_delete }}</td>
18-
</tr>
19-
<tr>
20-
<td i18n
21-
class="bold">Index type</td>
22-
<td>{{ selection.index_type }}</td>
23-
</tr>
24-
<tr>
25-
<td i18n
26-
class="bold">Placement rule</td>
27-
<td>{{ selection.placement_rule }}</td>
28-
</tr>
29-
<tr>
30-
<td i18n
31-
class="bold">Last modification time</td>
32-
<td>{{ selection.mtime | cdDate }}</td>
33-
</tr>
34-
</tbody>
35-
</table>
2+
<nav ngbNav
3+
#nav="ngbNav"
4+
class="nav-tabs"
5+
cdStatefulTab="rgw-bucket-details">
6+
<ng-container ngbNavItem="details">
7+
<a ngbNavLink
8+
i18n>Details</a>
9+
<ng-template ngbNavContent>
3610

37-
<!-- Bucket quota -->
38-
<div>
39-
<legend i18n>Bucket quota</legend>
40-
<table class="table table-striped table-bordered">
41-
<tbody>
42-
<tr>
43-
<td i18n
44-
class="bold w-25">Enabled</td>
45-
<td class="w-75">{{ selection.bucket_quota.enabled | booleanText }}</td>
46-
</tr>
47-
<ng-container *ngIf="selection.bucket_quota.enabled">
48-
<tr>
49-
<td i18n
50-
class="bold">Maximum size</td>
51-
<td *ngIf="selection.bucket_quota.max_size <= -1"
52-
i18n>Unlimited</td>
53-
<td *ngIf="selection.bucket_quota.max_size > -1">
54-
{{ selection.bucket_quota.max_size | dimless }}
55-
</td>
56-
</tr>
57-
<tr>
58-
<td i18n
59-
class="bold">Maximum objects</td>
60-
<td *ngIf="selection.bucket_quota.max_objects <= -1"
61-
i18n>Unlimited</td>
62-
<td *ngIf="selection.bucket_quota.max_objects > -1">
63-
{{ selection.bucket_quota.max_objects }}
64-
</td>
65-
</tr>
66-
</ng-container>
67-
</tbody>
68-
</table>
69-
</div>
11+
<table class="table table-striped table-bordered">
12+
<tbody>
13+
<tr>
14+
<td i18n
15+
class="bold w-25">Versioning</td>
16+
<td class="w-75">{{ selection.versioning }}</td>
17+
</tr>
18+
<tr>
19+
<td i18n
20+
class="bold">Encryption</td>
21+
<td>{{ selection.encryption }}</td>
22+
</tr>
23+
<tr>
24+
<td i18n
25+
class="bold">MFA Delete</td>
26+
<td>{{ selection.mfa_delete }}</td>
27+
</tr>
28+
<tr>
29+
<td i18n
30+
class="bold">Index type</td>
31+
<td>{{ selection.index_type }}</td>
32+
</tr>
33+
<tr>
34+
<td i18n
35+
class="bold">Placement rule</td>
36+
<td>{{ selection.placement_rule }}</td>
37+
</tr>
38+
<tr>
39+
<td i18n
40+
class="bold">Last modification time</td>
41+
<td>{{ selection.mtime | cdDate }}</td>
42+
</tr>
43+
</tbody>
44+
</table>
7045

71-
<!-- Locking -->
72-
<legend i18n>Locking</legend>
73-
<table class="table table-striped table-bordered">
74-
<tbody>
75-
<tr>
76-
<td i18n
77-
class="bold w-25">Enabled</td>
78-
<td class="w-75">{{ selection.lock_enabled | booleanText }}</td>
79-
</tr>
80-
<ng-container *ngIf="selection.lock_enabled">
81-
<tr>
82-
<td i18n
83-
class="bold">Mode</td>
84-
<td>{{ selection.lock_mode }}</td>
85-
</tr>
86-
<tr>
87-
<td i18n
88-
class="bold">Days</td>
89-
<td>{{ selection.lock_retention_period_days }}</td>
90-
</tr>
91-
</ng-container>
92-
</tbody>
93-
</table>
46+
<!-- Bucket quota -->
47+
<div>
48+
<legend i18n>Bucket quota</legend>
49+
<table class="table table-striped table-bordered">
50+
<tbody>
51+
<tr>
52+
<td i18n
53+
class="bold w-25">Enabled</td>
54+
<td class="w-75">{{ selection.bucket_quota.enabled | booleanText }}</td>
55+
</tr>
56+
<ng-container *ngIf="selection.bucket_quota.enabled">
57+
<tr>
58+
<td i18n
59+
class="bold">Maximum size</td>
60+
<td *ngIf="selection.bucket_quota.max_size <= -1"
61+
i18n>Unlimited</td>
62+
<td *ngIf="selection.bucket_quota.max_size > -1">
63+
{{ selection.bucket_quota.max_size | dimless }}
64+
</td>
65+
</tr>
66+
<tr>
67+
<td i18n
68+
class="bold">Maximum objects</td>
69+
<td *ngIf="selection.bucket_quota.max_objects <= -1"
70+
i18n>Unlimited</td>
71+
<td *ngIf="selection.bucket_quota.max_objects > -1">
72+
{{ selection.bucket_quota.max_objects }}
73+
</td>
74+
</tr>
75+
</ng-container>
76+
</tbody>
77+
</table>
78+
</div>
79+
80+
<!-- Locking -->
81+
<legend i18n>Locking</legend>
82+
<table class="table table-striped table-bordered">
83+
<tbody>
84+
<tr>
85+
<td i18n
86+
class="bold w-25">Enabled</td>
87+
<td class="w-75">{{ selection.lock_enabled | booleanText }}</td>
88+
</tr>
89+
<ng-container *ngIf="selection.lock_enabled">
90+
<tr>
91+
<td i18n
92+
class="bold">Mode</td>
93+
<td>{{ selection.lock_mode }}</td>
94+
</tr>
95+
<tr>
96+
<td i18n
97+
class="bold">Days</td>
98+
<td>{{ selection.lock_retention_period_days }}</td>
99+
</tr>
100+
</ng-container>
101+
</tbody>
102+
</table>
103+
</ng-template>
104+
</ng-container>
105+
106+
<ng-container ngbNavItem="permissions">
107+
<a ngbNavLink
108+
i18n>Permissions</a>
109+
<ng-template ngbNavContent>
110+
111+
<table class="table table-striped table-bordered">
112+
<tbody>
113+
<tr>
114+
<td i18n
115+
class="bold w-25">Policy</td>
116+
<td><pre>{{ selection.policy | json}}</pre></td>
117+
</tr>
118+
</tbody>
119+
</table>
120+
</ng-template>
121+
</ng-container>
122+
</nav>
123+
124+
<div [ngbNavOutlet]="nav"></div>
94125
</ng-container>

src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
88
import { SharedModule } from '~/app/shared/shared.module';
99
import { configureTestBed } from '~/testing/unit-test-helper';
1010
import { RgwBucketDetailsComponent } from './rgw-bucket-details.component';
11+
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
1112

1213
describe('RgwBucketDetailsComponent', () => {
1314
let component: RgwBucketDetailsComponent;
@@ -17,7 +18,7 @@ describe('RgwBucketDetailsComponent', () => {
1718

1819
configureTestBed({
1920
declarations: [RgwBucketDetailsComponent],
20-
imports: [SharedModule, HttpClientTestingModule]
21+
imports: [SharedModule, HttpClientTestingModule, NgbNavModule]
2122
});
2223

2324
beforeEach(() => {

src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class RgwBucketDetailsComponent implements OnChanges {
1818
this.rgwBucketService.get(this.selection.bid).subscribe((bucket: object) => {
1919
bucket['lock_retention_period_days'] = this.rgwBucketService.getLockDays(bucket);
2020
this.selection = bucket;
21+
this.selection.policy = JSON.parse(this.selection.policy) || {};
2122
});
2223
}
2324
}

src/pybind/mgr/dashboard/services/rgw_client.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,27 @@ def create_role(self, role_name: str, role_path: str, role_assume_policy_doc: st
852852
f' For more information about the format look at {link}')
853853
raise DashboardException(msg=msg, component='rgw')
854854

855+
@RestClient.api_get('/{bucket_name}?policy')
856+
def get_bucket_policy(self, bucket_name: str, request=None):
857+
"""
858+
Gets the bucket policy for a bucket.
859+
:param bucket_name: The name of the bucket.
860+
:type bucket_name: str
861+
:rtype: None
862+
"""
863+
# pylint: disable=unused-argument
864+
865+
try:
866+
request = request()
867+
return request
868+
except RequestException as e:
869+
if e.content:
870+
content = json_str_to_object(e.content)
871+
if content.get(
872+
'Code') == 'NoSuchBucketPolicy':
873+
return None
874+
raise e
875+
855876
def perform_validations(self, retention_period_days, retention_period_years, mode):
856877
try:
857878
retention_period_days = int(retention_period_days) if retention_period_days else 0

0 commit comments

Comments
 (0)