]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_lc_s3.cc
update sources to 12.2.7
[ceph.git] / ceph / src / rgw / rgw_lc_s3.cc
CommitLineData
7c673cae
FG
1#include <string.h>
2
3#include <iostream>
4#include <map>
5
6#include "include/types.h"
7
8#include "rgw_user.h"
9#include "rgw_lc_s3.h"
10
11
12#define dout_subsys ceph_subsys_rgw
13
14using namespace std;
15
16bool LCExpiration_S3::xml_end(const char * el) {
17 LCDays_S3 *lc_days = static_cast<LCDays_S3 *>(find_first("Days"));
31f18b77 18 LCDeleteMarker_S3 *lc_dm = static_cast<LCDeleteMarker_S3 *>(find_first("ExpiredObjectDeleteMarker"));
224ce89b 19 LCDate_S3 *lc_date = static_cast<LCDate_S3 *>(find_first("Date"));
7c673cae 20
224ce89b
WB
21 if ((!lc_days && !lc_dm && !lc_date) || (lc_days && lc_dm)
22 || (lc_days && lc_date) || (lc_dm && lc_date)) {
7c673cae 23 return false;
31f18b77
FG
24 }
25 if (lc_days) {
26 days = lc_days->get_data();
27 } else if (lc_dm) {
28 dm_expiration = lc_dm->get_data().compare("true") == 0;
29 if (!dm_expiration) {
30 return false;
31 }
224ce89b
WB
32 } else {
33 date = lc_date->get_data();
34 //We need return xml error according to S3
35 if (boost::none == ceph::from_iso_8601(date)) {
36 return false;
37 }
31f18b77 38 }
7c673cae
FG
39 return true;
40}
41
42bool LCNoncurExpiration_S3::xml_end(const char *el) {
43 LCDays_S3 *lc_noncur_days = static_cast<LCDays_S3 *>(find_first("NoncurrentDays"));
44 if (!lc_noncur_days) {
45 return false;
46 }
47 days = lc_noncur_days->get_data();
48 return true;
49}
50
51bool LCMPExpiration_S3::xml_end(const char *el) {
52 LCDays_S3 *lc_mp_days = static_cast<LCDays_S3 *>(find_first("DaysAfterInitiation"));
53 if (!lc_mp_days) {
54 return false;
55 }
56 days = lc_mp_days->get_data();
57 return true;
58}
59
60bool RGWLifecycleConfiguration_S3::xml_end(const char *el) {
61 XMLObjIter iter = find("Rule");
62 LCRule_S3 *rule = static_cast<LCRule_S3 *>(iter.get_next());
28e407b8
AA
63 if (!rule)
64 return false;
7c673cae
FG
65 while (rule) {
66 add_rule(rule);
67 rule = static_cast<LCRule_S3 *>(iter.get_next());
68 }
69 return true;
70}
71
72bool LCRule_S3::xml_end(const char *el) {
73 LCID_S3 *lc_id;
74 LCPrefix_S3 *lc_prefix;
75 LCStatus_S3 *lc_status;
76 LCExpiration_S3 *lc_expiration;
77 LCNoncurExpiration_S3 *lc_noncur_expiration;
78 LCMPExpiration_S3 *lc_mp_expiration;
79
80 id.clear();
81 prefix.clear();
82 status.clear();
31f18b77 83 dm_expiration = false;
7c673cae 84
181888fb
FG
85 // S3 generates a 48 bit random ID, maybe we could generate shorter IDs
86 static constexpr auto LC_ID_LENGTH = 48;
87
7c673cae 88 lc_id = static_cast<LCID_S3 *>(find_first("ID"));
181888fb
FG
89 if (lc_id){
90 id = lc_id->get_data();
91 } else {
b32b8144 92 gen_rand_alphanumeric_lower(cct, &id, LC_ID_LENGTH);
181888fb
FG
93 }
94
95
96 XMLObj *obj = find_first("Filter");
97
98 if (obj){
99 string _prefix;
100 RGWXMLDecoder::decode_xml("Prefix", _prefix, obj);
101 filter.set_prefix(std::move(_prefix));
102 } else {
103 // Ideally the following code should be deprecated and we should return
104 // False here, The new S3 LC configuration xml spec. makes Filter mandatory
105 // and Prefix optional. However older clients including boto2 still generate
106 // xml according to the older spec, where Prefix existed outside of Filter
107 // and S3 itself seems to be sloppy on enforcing the mandatory Filter
108 // argument. A day will come when S3 enforces their own xml-spec, but it is
109 // not this day
110
111 lc_prefix = static_cast<LCPrefix_S3 *>(find_first("Prefix"));
112
113 if (!lc_prefix){
114 return false;
115 }
116
117 prefix = lc_prefix->get_data();
118 }
7c673cae 119
7c673cae
FG
120
121 lc_status = static_cast<LCStatus_S3 *>(find_first("Status"));
122 if (!lc_status)
123 return false;
124 status = lc_status->get_data();
125 if (status.compare("Enabled") != 0 && status.compare("Disabled") != 0)
126 return false;
127
128 lc_expiration = static_cast<LCExpiration_S3 *>(find_first("Expiration"));
129 lc_noncur_expiration = static_cast<LCNoncurExpiration_S3 *>(find_first("NoncurrentVersionExpiration"));
130 lc_mp_expiration = static_cast<LCMPExpiration_S3 *>(find_first("AbortIncompleteMultipartUpload"));
131 if (!lc_expiration && !lc_noncur_expiration && !lc_mp_expiration) {
132 return false;
133 } else {
134 if (lc_expiration) {
224ce89b 135 if (lc_expiration->has_days()) {
31f18b77 136 expiration.set_days(lc_expiration->get_days_str());
224ce89b
WB
137 } else if (lc_expiration->has_date()) {
138 expiration.set_date(lc_expiration->get_date());
31f18b77
FG
139 } else {
140 dm_expiration = lc_expiration->get_dm_expiration();
141 }
7c673cae
FG
142 }
143 if (lc_noncur_expiration) {
144 noncur_expiration = *lc_noncur_expiration;
145 }
146 if (lc_mp_expiration) {
147 mp_expiration = *lc_mp_expiration;
148 }
149 }
150
151 return true;
152}
153
b32b8144 154void LCRule_S3::to_xml(ostream& out) {
7c673cae
FG
155 out << "<Rule>" ;
156 out << "<ID>" << id << "</ID>";
181888fb
FG
157 if (!filter.empty()) {
158 LCFilter_S3& lc_filter = static_cast<LCFilter_S3&>(filter);
159 lc_filter.to_xml(out);
160 } else {
161 out << "<Prefix>" << prefix << "</Prefix>";
162 }
7c673cae 163 out << "<Status>" << status << "</Status>";
31f18b77 164 if (!expiration.empty() || dm_expiration) {
224ce89b 165 LCExpiration_S3 expir(expiration.get_days_str(), expiration.get_date(), dm_expiration);
7c673cae
FG
166 expir.to_xml(out);
167 }
168 if (!noncur_expiration.empty()) {
169 LCNoncurExpiration_S3& noncur_expir = static_cast<LCNoncurExpiration_S3&>(noncur_expiration);
170 noncur_expir.to_xml(out);
171 }
172 if (!mp_expiration.empty()) {
173 LCMPExpiration_S3& mp_expir = static_cast<LCMPExpiration_S3&>(mp_expiration);
174 mp_expir.to_xml(out);
175 }
176 out << "</Rule>";
177}
178
179int RGWLifecycleConfiguration_S3::rebuild(RGWRados *store, RGWLifecycleConfiguration& dest)
180{
181 int ret = 0;
182 multimap<string, LCRule>::iterator iter;
183 for (iter = rule_map.begin(); iter != rule_map.end(); ++iter) {
184 LCRule& src_rule = iter->second;
185 ret = dest.check_and_add_rule(&src_rule);
186 if (ret < 0)
187 return ret;
188 }
224ce89b 189 if (!dest.valid()) {
7c673cae
FG
190 ret = -ERR_INVALID_REQUEST;
191 }
192 return ret;
193}
194
195void RGWLifecycleConfiguration_S3::dump_xml(Formatter *f) const
196{
197 f->open_object_section_in_ns("LifecycleConfiguration", XMLNS_AWS_S3);
198
199 for (auto iter = rule_map.begin(); iter != rule_map.end(); ++iter) {
200 const LCRule_S3& rule = static_cast<const LCRule_S3&>(iter->second);
201 rule.dump_xml(f);
202 }
203
204 f->close_section(); // Lifecycle
205}
206
207XMLObj *RGWLCXMLParser_S3::alloc_obj(const char *el)
208{
209 XMLObj * obj = NULL;
210 if (strcmp(el, "LifecycleConfiguration") == 0) {
211 obj = new RGWLifecycleConfiguration_S3(cct);
212 } else if (strcmp(el, "Rule") == 0) {
b32b8144 213 obj = new LCRule_S3(cct);
7c673cae
FG
214 } else if (strcmp(el, "ID") == 0) {
215 obj = new LCID_S3();
216 } else if (strcmp(el, "Prefix") == 0) {
217 obj = new LCPrefix_S3();
218 } else if (strcmp(el, "Status") == 0) {
219 obj = new LCStatus_S3();
220 } else if (strcmp(el, "Expiration") == 0) {
221 obj = new LCExpiration_S3();
222 } else if (strcmp(el, "Days") == 0) {
223 obj = new LCDays_S3();
224ce89b
WB
224 } else if (strcmp(el, "Date") == 0) {
225 obj = new LCDate_S3();
31f18b77
FG
226 } else if (strcmp(el, "ExpiredObjectDeleteMarker") == 0) {
227 obj = new LCDeleteMarker_S3();
7c673cae
FG
228 } else if (strcmp(el, "NoncurrentVersionExpiration") == 0) {
229 obj = new LCNoncurExpiration_S3();
230 } else if (strcmp(el, "NoncurrentDays") == 0) {
231 obj = new LCDays_S3();
232 } else if (strcmp(el, "AbortIncompleteMultipartUpload") == 0) {
233 obj = new LCMPExpiration_S3();
234 } else if (strcmp(el, "DaysAfterInitiation") == 0) {
235 obj = new LCDays_S3();
236 }
237 return obj;
238}