summaryrefslogtreecommitdiffstats
path: root/src/rgw/driver/rados/rgw_otp.cc
blob: aac10338d88367bf35de13e1376bca64b0288c07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab ft=cpp

#include "rgw_otp.h"
#include <list>
#include <fmt/format.h>
#include "services/svc_cls.h"
#include "services/svc_mdlog.h"
#include "services/svc_sys_obj.h"
#include "rgw_metadata.h"
#include "rgw_metadata_lister.h"
#include "rgw_zone.h"


class MetadataObject : public RGWMetadataObject {
public:
  std::list<rados::cls::otp::otp_info_t> devices;

  MetadataObject(std::list<rados::cls::otp::otp_info_t> devices,
                 const obj_version& v, ceph::real_time m)
    : RGWMetadataObject(v, m), devices(std::move(devices))
  {}

  void dump(Formatter* f) const override {
    encode_json("devices", devices, f);
  }
};

class MetadataHandler : public RGWMetadataHandler {
  RGWSI_SysObj& sysobj;
  RGWSI_Cls::MFA& mfa;
  RGWSI_MDLog& mdlog;
  const RGWZoneParams& zone;
 public:
  MetadataHandler(RGWSI_SysObj& sysobj, RGWSI_Cls::MFA& mfa,
                  RGWSI_MDLog& mdlog, const RGWZoneParams& zone)
    : sysobj(sysobj), mfa(mfa), mdlog(mdlog), zone(zone) {}

  std::string get_type() override { return "otp"; }

  RGWMetadataObject* get_meta_obj(JSONObj* obj,
                                  const obj_version& objv,
                                  const ceph::real_time& mtime) override
  {
    std::list<rados::cls::otp::otp_info_t> devices;
    try {
      JSONDecoder::decode_json("devices", devices, obj);
    } catch (const JSONDecoder::err&) {
      return nullptr;
    }
    return new MetadataObject(std::move(devices), objv, mtime);
  }

  int get(std::string& entry, RGWMetadataObject** obj,
          optional_yield y, const DoutPrefixProvider* dpp) override
  {
    std::list<rados::cls::otp::otp_info_t> devices;
    RGWObjVersionTracker objv;
    ceph::real_time mtime;

    int r = mfa.list_mfa(dpp, entry, &devices, &objv, &mtime, y);
    if (r < 0) {
      return r;
    }

    *obj = new MetadataObject(std::move(devices), objv.read_version, mtime);
    return 0;
  }

  int put(std::string& entry, RGWMetadataObject* obj,
          RGWObjVersionTracker& objv, optional_yield y,
          const DoutPrefixProvider* dpp,
          RGWMDLogSyncType type, bool from_remote_zone) override
  {
    auto otp_obj = static_cast<MetadataObject*>(obj);
    int r = mfa.set_mfa(dpp, entry, otp_obj->devices, true,
                        &objv, obj->get_mtime(), y);
    if (r < 0) {
      return r;
    }
    return mdlog.complete_entry(dpp, y, "otp", entry, &objv);
  }

  int remove(std::string& entry, RGWObjVersionTracker& objv,
             optional_yield y, const DoutPrefixProvider* dpp) override
  {
    int r = rgw_delete_system_obj(dpp, &sysobj, zone.otp_pool, entry, &objv, y);
    if (r < 0) {
      return r;
    }
    return mdlog.complete_entry(dpp, y, "otp", entry, &objv);
  }

  int mutate(const std::string& entry,
             const ceph::real_time& mtime,
             RGWObjVersionTracker* objv,
             optional_yield y,
             const DoutPrefixProvider* dpp,
             RGWMDLogStatus op_type,
             std::function<int()> f) override
  {
    int r = f();
    if (r < 0) {
      return r;
    }
    return mdlog.complete_entry(dpp, y, "otp", entry, objv);
  }


  int list_keys_init(const DoutPrefixProvider* dpp,
                     const std::string& marker, void** phandle) override
  {
    auto lister = std::make_unique<RGWMetadataLister>(sysobj.get_pool(zone.otp_pool));
    int r = lister->init(dpp, marker, ""); // no prefix
    if (r < 0) {
      return r;
    }
    *phandle = lister.release();
    return 0;
  }

  int list_keys_next(const DoutPrefixProvider* dpp, void* handle, int max,
                     std::list<std::string>& keys, bool* truncated) override
  {
    auto lister = static_cast<RGWMetadataLister*>(handle);
    return lister->get_next(dpp, max, keys, truncated);
  }

  void list_keys_complete(void* handle) override
  {
    delete static_cast<RGWMetadataLister*>(handle);
  }

  std::string get_marker(void* handle) override
  {
    auto lister = static_cast<RGWMetadataLister*>(handle);
    return lister->get_marker();
  }
};


// public interface
namespace rgwrados::otp {

std::string get_meta_key(const rgw_user& user)
{
  return fmt::format("otp:user:{}", user.to_str());
}

auto create_metadata_handler(RGWSI_SysObj& sysobj, RGWSI_Cls& cls,
                             RGWSI_MDLog& mdlog, const RGWZoneParams& zone)
    -> std::unique_ptr<RGWMetadataHandler>
{
  return std::make_unique<MetadataHandler>(sysobj, cls.mfa, mdlog, zone);
}

} // namespace rgwrados::otp