]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rgw/rgw_multi/zone_ps.py
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / test / rgw / rgw_multi / zone_ps.py
1 import logging
2 import httplib
3 import urllib
4 import hmac
5 import hashlib
6 import base64
7 from time import gmtime, strftime
8 from multisite import Zone
9
10 log = logging.getLogger('rgw_multi.tests')
11
12
13 class PSZone(Zone): # pylint: disable=too-many-ancestors
14 """ PubSub zone class """
15 def is_read_only(self):
16 return True
17
18 def tier_type(self):
19 return "pubsub"
20
21 def create(self, cluster, args=None, **kwargs):
22 if args is None:
23 args = ''
24 args += ['--tier-type', self.tier_type()]
25 return self.json_command(cluster, 'create', args)
26
27 def has_buckets(self):
28 return False
29
30
31 NO_HTTP_BODY = ''
32
33
34 def make_request(conn, method, resource, parameters=None):
35 """generic request sending to pubsub radogw
36 should cover: topics, notificatios and subscriptions
37 """
38 url_params = ''
39 if parameters is not None:
40 url_params = urllib.urlencode(parameters)
41 # remove 'None' from keys with no values
42 url_params = url_params.replace('=None', '')
43 url_params = '?' + url_params
44 string_date = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
45 string_to_sign = method + '\n\n\n' + string_date + '\n' + resource
46 signature = base64.b64encode(hmac.new(conn.aws_secret_access_key,
47 string_to_sign.encode('utf-8'),
48 hashlib.sha1).digest())
49 headers = {'Authorization': 'AWS '+conn.aws_access_key_id+':'+signature,
50 'Date': string_date,
51 'Host': conn.host+':'+str(conn.port)}
52 http_conn = httplib.HTTPConnection(conn.host, conn.port)
53 if log.getEffectiveLevel() <= 10:
54 http_conn.set_debuglevel(5)
55 http_conn.request(method, resource+url_params, NO_HTTP_BODY, headers)
56 response = http_conn.getresponse()
57 data = response.read()
58 status = response.status
59 http_conn.close()
60 return data, status
61
62
63 class PSTopic:
64 """class to set/get/delete a topic
65 PUT /topics/<topic name>
66 GET /topics/<topic name>
67 DELETE /topics/<topic name>
68 """
69 def __init__(self, conn, topic_name):
70 self.conn = conn
71 assert topic_name.strip()
72 self.resource = '/topics/'+topic_name
73
74 def send_request(self, method):
75 """send request to radosgw"""
76 return make_request(self.conn, method, self.resource)
77
78 def get_config(self):
79 """get topic info"""
80 return self.send_request('GET')
81
82 def set_config(self):
83 """set topic"""
84 return self.send_request('PUT')
85
86 def del_config(self):
87 """delete topic"""
88 return self.send_request('DELETE')
89
90
91 class PSNotification:
92 """class to set/get/delete a notification
93 PUT /notifications/bucket/<bucket>?topic=<topic-name>[&events=<event>[,<event>]]
94 GET /notifications/bucket/<bucket>
95 DELETE /notifications/bucket/<bucket>?topic=<topic-name>
96 """
97 def __init__(self, conn, bucket_name, topic_name, events=''):
98 self.conn = conn
99 assert bucket_name.strip()
100 assert topic_name.strip()
101 self.resource = '/notifications/bucket/'+bucket_name
102 if events.strip():
103 self.parameters = {'topic': topic_name, 'events': events}
104 else:
105 self.parameters = {'topic': topic_name}
106
107 def send_request(self, method, parameters=None):
108 """send request to radosgw"""
109 return make_request(self.conn, method, self.resource, parameters)
110
111 def get_config(self):
112 """get notification info"""
113 return self.send_request('GET')
114
115 def set_config(self):
116 """setnotification"""
117 return self.send_request('PUT', self.parameters)
118
119 def del_config(self):
120 """delete notification"""
121 return self.send_request('DELETE', self.parameters)
122
123
124 class PSSubscription:
125 """class to set/get/delete a subscription:
126 PUT /subscriptions/<sub-name>?topic=<topic-name>
127 GET /subscriptions/<sub-name>
128 DELETE /subscriptions/<sub-name>
129 also to get list of events, and ack them:
130 GET /subscriptions/<sub-name>?events[&max-entries=<max-entries>][&marker=<marker>]
131 POST /subscriptions/<sub-name>?ack&event-id=<event-id>
132 """
133 def __init__(self, conn, sub_name, topic_name):
134 self.conn = conn
135 assert topic_name.strip()
136 self.resource = '/subscriptions/'+sub_name
137 self.parameters = {'topic': topic_name}
138
139 def send_request(self, method, parameters=None):
140 """send request to radosgw"""
141 return make_request(self.conn, method, self.resource, parameters)
142
143 def get_config(self):
144 """get subscription info"""
145 return self.send_request('GET')
146
147 def set_config(self):
148 """set subscription"""
149 return self.send_request('PUT', self.parameters)
150
151 def del_config(self):
152 """delete subscription"""
153 return self.send_request('DELETE')
154
155 def get_events(self, max_entries=None, marker=None):
156 """ get events from subscription """
157 parameters = {'events': None}
158 if max_entries is not None:
159 parameters['max-entries'] = max_entries
160 if marker is not None:
161 parameters['marker'] = marker
162 return self.send_request('GET', parameters)
163
164 def ack_events(self, event_id):
165 """ ack events in a subscription """
166 parameters = {'ack': None, 'event-id': event_id}
167 return self.send_request('POST', parameters)