1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
5 * Ceph - scalable distributed file system
7 * Copyright (C) 2018 Red Hat, Inc.
9 * This is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License version 2.1, as published by the Free Software
12 * Foundation. See file COPYING.
18 #include "rgw_basic_types.h"
22 struct rgw_sync_symmetric_group
{
24 std::set
<rgw_zone_id
> zones
;
26 rgw_sync_symmetric_group() {}
27 rgw_sync_symmetric_group(const std::string
& _id
,
28 const std::set
<rgw_zone_id
> _zones
) : id(_id
), zones(_zones
) {}
31 void encode(bufferlist
& bl
) const {
32 ENCODE_START(1, 1, bl
);
38 void decode(bufferlist::const_iterator
& bl
) {
45 void dump(ceph::Formatter
*f
) const;
46 void decode_json(JSONObj
*obj
);
48 WRITE_CLASS_ENCODER(rgw_sync_symmetric_group
)
50 struct rgw_sync_directional_rule
{
51 rgw_zone_id source_zone
;
52 rgw_zone_id dest_zone
;
54 void encode(bufferlist
& bl
) const {
55 ENCODE_START(1, 1, bl
);
56 encode(source_zone
, bl
);
57 encode(dest_zone
, bl
);
61 void decode(bufferlist::const_iterator
& bl
) {
63 decode(source_zone
, bl
);
64 decode(dest_zone
, bl
);
68 void dump(ceph::Formatter
*f
) const;
69 void decode_json(JSONObj
*obj
);
71 WRITE_CLASS_ENCODER(rgw_sync_directional_rule
)
73 struct rgw_sync_bucket_entity
{
74 std::optional
<rgw_zone_id
> zone
; /* define specific zones */
75 std::optional
<rgw_bucket
> bucket
; /* define specific bucket */
77 static bool match_str(const std::string
& s1
, const std::string
& s2
) { /* empty std::string is wildcard */
83 bool all_zones
{false};
85 rgw_sync_bucket_entity() {}
86 rgw_sync_bucket_entity(const rgw_zone_id
& _zone
,
87 std::optional
<rgw_bucket
> _bucket
) : zone(_zone
),
88 bucket(_bucket
.value_or(rgw_bucket())) {}
90 bool specific() const {
91 return zone
&& bucket
;
94 void encode(bufferlist
& bl
) const {
95 ENCODE_START(1, 1, bl
);
96 encode(all_zones
, bl
);
102 void decode(bufferlist::const_iterator
& bl
) {
104 decode(all_zones
, bl
);
110 void dump(ceph::Formatter
*f
) const;
111 void decode_json(JSONObj
*obj
);
113 rgw_bucket
get_bucket() const {
114 return bucket
.value_or(rgw_bucket());
117 std::string
bucket_key() const;
119 bool match_zone(const rgw_zone_id
& z
) const {
130 void apply_zone(const rgw_zone_id
& z
) {
135 static bool match_bucket_id(const std::string
& bid1
, const std::string
& bid2
) {
136 return (bid1
.empty() || bid2
.empty() || (bid1
== bid2
));
139 bool match_bucket(std::optional
<rgw_bucket
> b
) const {
148 return (match_str(bucket
->tenant
, b
->tenant
) &&
149 match_str(bucket
->name
, b
->name
) &&
150 match_bucket_id(bucket
->bucket_id
, b
->bucket_id
));
153 bool match(const rgw_sync_bucket_entity
& entity
) const {
155 return match_bucket(entity
.bucket
);
157 return (match_zone(*entity
.zone
) && match_bucket(entity
.bucket
));
160 const bool operator<(const rgw_sync_bucket_entity
& e
) const {
161 if (all_zones
&& !e
.all_zones
) {
164 if (!all_zones
&& e
.all_zones
) {
173 return (bucket
< e
.bucket
);
176 void apply_bucket(std::optional
<rgw_bucket
> _b
);
178 WRITE_CLASS_ENCODER(rgw_sync_bucket_entity
)
180 struct rgw_sync_pipe_filter_tag
{
184 rgw_sync_pipe_filter_tag() {}
185 rgw_sync_pipe_filter_tag(const std::string
& s
) {
188 rgw_sync_pipe_filter_tag(const std::string
& _key
,
189 const std::string
& _value
) : key(_key
),
192 void encode(bufferlist
& bl
) const {
193 ENCODE_START(1, 1, bl
);
199 void decode(bufferlist::const_iterator
& bl
) {
206 void dump(ceph::Formatter
*f
) const;
207 void decode_json(JSONObj
*obj
);
209 bool from_str(const std::string
& s
);
211 bool operator<(const rgw_sync_pipe_filter_tag
& t
) const {
218 return (value
< t
.value
);
221 bool operator==(const std::string
& s
) const;
223 WRITE_CLASS_ENCODER(rgw_sync_pipe_filter_tag
)
225 struct rgw_sync_pipe_filter
{
226 std::optional
<std::string
> prefix
;
227 std::set
<rgw_sync_pipe_filter_tag
> tags
;
229 void set_prefix(std::optional
<std::string
> opt_prefix
,
231 void set_tags(std::list
<std::string
>& tags_add
,
232 std::list
<std::string
>& tags_rm
);
234 void encode(bufferlist
& bl
) const;
235 void decode(bufferlist::const_iterator
& bl
);
237 void dump(ceph::Formatter
*f
) const;
238 void decode_json(JSONObj
*obj
);
240 bool is_subset_of(const rgw_sync_pipe_filter
& f
) const;
242 bool has_tags() const;
243 bool check_tag(const std::string
& s
) const;
244 bool check_tag(const std::string
& k
, const std::string
& v
) const;
245 bool check_tags(const std::vector
<std::string
>& tags
) const;
246 bool check_tags(const RGWObjTags::tag_map_t
& tags
) const;
248 WRITE_CLASS_ENCODER(rgw_sync_pipe_filter
)
250 struct rgw_sync_pipe_acl_translation
{
253 void encode(bufferlist
& bl
) const {
254 ENCODE_START(1, 1, bl
);
259 void decode(bufferlist::const_iterator
& bl
) {
265 void dump(ceph::Formatter
*f
) const;
266 void decode_json(JSONObj
*obj
);
268 bool operator==(const rgw_sync_pipe_acl_translation
& aclt
) const {
269 return (owner
== aclt
.owner
);
272 WRITE_CLASS_ENCODER(rgw_sync_pipe_acl_translation
)
274 struct rgw_sync_pipe_source_params
{
275 rgw_sync_pipe_filter filter
;
277 void encode(bufferlist
& bl
) const {
278 ENCODE_START(1, 1, bl
);
283 void decode(bufferlist::const_iterator
& bl
) {
289 void dump(ceph::Formatter
*f
) const;
290 void decode_json(JSONObj
*obj
);
292 WRITE_CLASS_ENCODER(rgw_sync_pipe_source_params
)
294 struct rgw_sync_pipe_dest_params
{
295 std::optional
<rgw_sync_pipe_acl_translation
> acl_translation
;
296 std::optional
<std::string
> storage_class
;
298 void encode(bufferlist
& bl
) const {
299 ENCODE_START(1, 1, bl
);
300 encode(acl_translation
, bl
);
301 encode(storage_class
, bl
);
305 void decode(bufferlist::const_iterator
& bl
) {
307 decode(acl_translation
, bl
);
308 decode(storage_class
, bl
);
312 void set_storage_class(const std::string
& sc
) {
316 void set_owner(const rgw_user
& owner
) {
318 acl_translation
.reset();
320 acl_translation
.emplace();
321 acl_translation
->owner
= owner
;
325 void dump(ceph::Formatter
*f
) const;
326 void decode_json(JSONObj
*obj
);
328 bool operator==(const rgw_sync_pipe_dest_params
& rhs
) const {
329 return (acl_translation
== rhs
.acl_translation
&&
330 storage_class
== rhs
.storage_class
);
333 WRITE_CLASS_ENCODER(rgw_sync_pipe_dest_params
)
335 struct rgw_sync_pipe_params
{
336 rgw_sync_pipe_source_params source
;
337 rgw_sync_pipe_dest_params dest
;
345 void encode(bufferlist
& bl
) const {
346 ENCODE_START(1, 1, bl
);
349 encode(priority
, bl
);
350 encode((uint8_t)mode
, bl
);
355 void decode(bufferlist::const_iterator
& bl
) {
359 decode(priority
, bl
);
367 void dump(ceph::Formatter
*f
) const;
368 void decode_json(JSONObj
*obj
);
370 WRITE_CLASS_ENCODER(rgw_sync_pipe_params
)
372 struct rgw_sync_bucket_pipe
{
374 rgw_sync_bucket_entity source
;
375 rgw_sync_bucket_entity dest
;
377 rgw_sync_pipe_params params
;
379 bool specific() const {
380 return source
.specific() && dest
.specific();
383 void encode(bufferlist
& bl
) const {
384 ENCODE_START(1, 1, bl
);
392 void decode(bufferlist::const_iterator
& bl
) {
401 const bool operator<(const rgw_sync_bucket_pipe
& p
) const {
408 if (source
< p
.source
) {
411 if (p
.source
< source
) {
414 return (dest
< p
.dest
);
417 void dump(ceph::Formatter
*f
) const;
418 void decode_json(JSONObj
*obj
);
420 WRITE_CLASS_ENCODER(rgw_sync_bucket_pipe
)
422 struct rgw_sync_bucket_entities
{
423 std::optional
<rgw_bucket
> bucket
; /* define specific bucket */
424 std::optional
<std::set
<rgw_zone_id
> > zones
; /* define specific zones, if not set then all zones */
426 bool all_zones
{false};
429 void encode(bufferlist
& bl
) const {
430 ENCODE_START(1, 1, bl
);
433 encode(all_zones
, bl
);
437 void decode(bufferlist::const_iterator
& bl
) {
441 decode(all_zones
, bl
);
445 void dump(ceph::Formatter
*f
) const;
446 void decode_json(JSONObj
*obj
);
448 bool match_bucket(std::optional
<rgw_bucket
> b
) const {
457 return (rgw_sync_bucket_entity::match_str(bucket
->tenant
, b
->tenant
) &&
458 rgw_sync_bucket_entity::match_str(bucket
->name
, b
->name
) &&
459 rgw_sync_bucket_entity::match_str(bucket
->bucket_id
, b
->bucket_id
));
462 void add_zones(const std::vector
<rgw_zone_id
>& new_zones
);
463 void remove_zones(const std::vector
<rgw_zone_id
>& rm_zones
);
464 void set_bucket(std::optional
<std::string
> tenant
,
465 std::optional
<std::string
> bucket_name
,
466 std::optional
<std::string
> bucket_id
);
467 void remove_bucket(std::optional
<std::string
> tenant
,
468 std::optional
<std::string
> bucket_name
,
469 std::optional
<std::string
> bucket_id
);
471 bool match_zone(const rgw_zone_id
& zone
) const {
479 return (zones
->find(zone
) != zones
->end());
482 std::vector
<rgw_sync_bucket_entity
> expand() const;
484 rgw_bucket
get_bucket() const {
485 return bucket
.value_or(rgw_bucket());
488 static std::string
bucket_key(std::optional
<rgw_bucket
> b
);
490 void set_all_zones(bool state
) {
497 WRITE_CLASS_ENCODER(rgw_sync_bucket_entities
)
499 struct rgw_sync_bucket_pipes
{
501 rgw_sync_bucket_entities source
;
502 rgw_sync_bucket_entities dest
;
504 rgw_sync_pipe_params params
;
506 void encode(bufferlist
& bl
) const {
507 ENCODE_START(1, 1, bl
);
515 void decode(bufferlist::const_iterator
& bl
) {
524 bool match_source(const rgw_zone_id
& zone
, std::optional
<rgw_bucket
> b
) const {
525 return (source
.match_zone(zone
) && source
.match_bucket(b
));
528 bool match_dest(const rgw_zone_id
& zone
, std::optional
<rgw_bucket
> b
) const {
529 return (dest
.match_zone(zone
) && dest
.match_bucket(b
));
532 bool contains_zone_bucket(const rgw_zone_id
& zone
, std::optional
<rgw_bucket
> b
) const {
533 return (match_source(zone
, b
) || match_dest(zone
, b
));
536 void dump(ceph::Formatter
*f
) const;
537 void decode_json(JSONObj
*obj
);
539 std::vector
<rgw_sync_bucket_pipe
> expand() const;
541 void get_potential_related_buckets(const rgw_bucket
& bucket
,
542 std::set
<rgw_bucket
> *sources
,
543 std::set
<rgw_bucket
> *dests
) const;
545 WRITE_CLASS_ENCODER(rgw_sync_bucket_pipes
)
547 std::ostream
& operator<<(std::ostream
& os
, const rgw_sync_bucket_entity
& e
);
548 std::ostream
& operator<<(std::ostream
& os
, const rgw_sync_bucket_pipe
& pipe
);
549 std::ostream
& operator<<(std::ostream
& os
, const rgw_sync_bucket_entities
& e
);
550 std::ostream
& operator<<(std::ostream
& os
, const rgw_sync_bucket_pipes
& pipe
);
553 * define data flow between zones. Symmetrical: zones sync from each other.
554 * Directional: one zone fetches data from another.
556 struct rgw_sync_data_flow_group
{
557 std::vector
<rgw_sync_symmetric_group
> symmetrical
;
558 std::vector
<rgw_sync_directional_rule
> directional
;
560 void encode(bufferlist
& bl
) const {
561 ENCODE_START(1, 1, bl
);
562 encode(symmetrical
, bl
);
563 encode(directional
, bl
);
567 void decode(bufferlist::const_iterator
& bl
) {
569 decode(symmetrical
, bl
);
570 decode(directional
, bl
);
574 void dump(ceph::Formatter
*f
) const;
575 void decode_json(JSONObj
*obj
);
578 return (symmetrical
.empty() && directional
.empty());
581 bool find_or_create_symmetrical(const std::string
& flow_id
, rgw_sync_symmetric_group
**flow_group
);
582 void remove_symmetrical(const std::string
& flow_id
, std::optional
<std::vector
<rgw_zone_id
> > zones
);
583 bool find_or_create_directional(const rgw_zone_id
& source_zone
, const rgw_zone_id
& dest_zone
, rgw_sync_directional_rule
**flow_group
);
584 void remove_directional(const rgw_zone_id
& source_zone
, const rgw_zone_id
& dest_zone
);
586 void init_default(const std::set
<rgw_zone_id
>& zones
);
588 WRITE_CLASS_ENCODER(rgw_sync_data_flow_group
)
591 struct rgw_sync_policy_group
{
594 rgw_sync_data_flow_group data_flow
; /* override data flow, howver, will not be able to
595 add new flows that don't exist at higher level */
596 std::vector
<rgw_sync_bucket_pipes
> pipes
; /* if not defined then applies to all
601 FORBIDDEN
= 1, /* sync not allowed */
602 ALLOWED
= 2, /* sync allowed */
603 ENABLED
= 3, /* sync should happen */
606 void encode(bufferlist
& bl
) const {
607 ENCODE_START(1, 1, bl
);
609 encode(data_flow
, bl
);
611 encode((uint32_t)status
, bl
);
615 void decode(bufferlist::const_iterator
& bl
) {
618 decode(data_flow
, bl
);
626 void dump(ceph::Formatter
*f
) const;
627 void decode_json(JSONObj
*obj
);
629 bool set_status(const std::string
& s
) {
630 if (s
== "forbidden") {
631 status
= rgw_sync_policy_group::Status::FORBIDDEN
;
632 } else if (s
== "allowed") {
633 status
= rgw_sync_policy_group::Status::ALLOWED
;
634 } else if (s
== "enabled") {
635 status
= rgw_sync_policy_group::Status::ENABLED
;
637 status
= rgw_sync_policy_group::Status::UNKNOWN
;
644 bool find_pipe(const std::string
& pipe_id
, bool create
, rgw_sync_bucket_pipes
**pipe
);
645 void remove_pipe(const std::string
& pipe_id
);
647 void get_potential_related_buckets(const rgw_bucket
& bucket
,
648 std::set
<rgw_bucket
> *sources
,
649 std::set
<rgw_bucket
> *dests
) const;
652 WRITE_CLASS_ENCODER(rgw_sync_policy_group
)
654 struct rgw_sync_policy_info
{
655 std::map
<std::string
, rgw_sync_policy_group
> groups
;
657 void encode(bufferlist
& bl
) const {
658 ENCODE_START(1, 1, bl
);
663 void decode(bufferlist::const_iterator
& bl
) {
669 void dump(ceph::Formatter
*f
) const;
670 void decode_json(JSONObj
*obj
);
673 return groups
.empty();
676 void get_potential_related_buckets(const rgw_bucket
& bucket
,
677 std::set
<rgw_bucket
> *sources
,
678 std::set
<rgw_bucket
> *dests
) const;
680 WRITE_CLASS_ENCODER(rgw_sync_policy_info
)