forked from vivekjuneja/docker_registry_cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
browser.py
252 lines (169 loc) · 6.7 KB
/
browser.py
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
import json
import requests
import sys
''' Disable Warnings when using verify=False'''
'''requests.packages.urllib3.disable_warnings()'''
def get_reqistry_request(url, username=None, password=None, ssl=False):
req = None
if ssl==True:
proto="https://"
else:
proto="http://"
url_endpoint = proto + url
s = requests.Session()
if(username!=None):
s.auth = (username, password)
try:
req = s.get(url_endpoint, verify=False)
except requests.ConnectionError:
print 'Cannot connect to Registry'
return req
def get_registry_catalog_request(url, username=None, password=None, ssl=False):
requrl = url+"/v2/_catalog"
req = get_reqistry_request(requrl, username, password, ssl)
return req
def get_registry_tag_request(url, repo, username=None, password=None, ssl=False):
requrl = url + "/v2/" + repo + "/tags/list"
req = get_reqistry_request(requrl, username, password, ssl)
return req
'''
Extracts the username and password from the url specified in case of Basic Authentication
enabled for a Docker registry
Example:-
If the url specified is like exampleuser:exampleuser@docker_registry_host:port
then, the username is exampleuser, password is exampleuser and url is docker_registry_host:port
'''
def extract_url(url):
uname_pwd_delimeter=":"
auth_ip_delimeter="@"
if url.find(auth_ip_delimeter)==-1:
return None, None, url
else:
delimiter_uname_pwd_pos = url.find(uname_pwd_delimeter)
delimeter_auth_ip_pos = url.find(auth_ip_delimeter, delimiter_uname_pwd_pos)
username = url[:delimiter_uname_pwd_pos]
password = url[delimiter_uname_pwd_pos+1:delimeter_auth_ip_pos]
url_endpoint = url[delimeter_auth_ip_pos+1:]
return username, password, url_endpoint
def get_all_repos(url, ssl=False):
username, password, url_endpoint = extract_url(url)
req = get_registry_catalog_request(url_endpoint, username, password, ssl)
repo_array = None
parsed_json = None
if(req!=None):
parsed_json = json.loads(req.text)
if('repositories' in parsed_json):
repo_array = parsed_json['repositories']
return repo_array
def search_for_repo(url, repo_search_name, ssl=False) :
repo_array = get_all_repos(url, ssl);
repo_dict_search = {}
if repo_search_name in repo_array:
parsed_repo_tag_req_resp = get_tags_for_repo(url, repo_search_name, ssl)
repo_dict_search[repo_search_name] = parsed_repo_tag_req_resp
else:
''' Get all the repos '''
repo_dict = get_all_repo_dict(url, repo_array, ssl)
if any(False if key.find(repo_search_name)==-1 else True for key in repo_dict) == True:
print "available options:- "
for key in repo_dict:
if(key.find(repo_search_name)!=-1):
repo_dict_search[key] = get_tags_for_repo(url, key, ssl)
return repo_dict_search
def get_tags_for_repo(url, repo, ssl=False):
username, password, url_endpoint = extract_url(url)
repo_tag_url_req = get_registry_tag_request(url_endpoint, repo, username, password, ssl)
parsed_repo_tag_req_resp = json.loads(repo_tag_url_req.text)
return parsed_repo_tag_req_resp["tags"]
'''
Gets the entire repository dictionary
'''
def get_all_repo_dict(url, repo_array,ssl=False):
repo_dict = {}
if (repo_array!=None):
for repo in repo_array:
parsed_repo_tag_req_resp = get_tags_for_repo(url, repo, ssl)
repo_dict[repo] = parsed_repo_tag_req_resp
return repo_dict
'''
Decorates the search results to be printed on the screen
'''
def decorate_list(repo_dict):
decorated_list_values = ""
if(len(repo_dict)==0):
return "No results!"
counter = 1;
for repo_key in repo_dict:
decorated_list_values += "\n-----------" + "\n" + str(counter) + ") Name: " + repo_key
decorated_list_values += "\nTags: "
counter+=1;
for tag in repo_dict[repo_key]:
decorated_list_values += tag + '\t'
decorated_list_values += "\n\n" + str(counter-1) + " images found !"
return decorated_list_values
'''
Decorates the search results to be printed on the screen
'''
def decorate_html(repo_dict, regurl):
decorated_list_values = "<html><head><title>Docker Registry Listing</title>\
<script src='http://cdnjs.cloudflare.com/ajax/libs/list.js/1.1.1/list.min.js'></script> \
<link rel='stylesheet' type='text/css' href='/css/browser_web.css'></head> \
<body><h1>Docker Registry Listing</h1> \
<div id='users'>\
<input class='search' placeholder='Search' />\
<button class='sort' data-sort='name'>\
Sort by name </button>"
if(len(repo_dict)==0):
decorated_list_values += "<p><h2>No results!</h2></p></body></html>"
return decorated_list_values
counter = 1;
decorated_list_values += "<p><ul class='list'>"
for repo_key in repo_dict:
decorated_list_values += "<li><h2 class='name'>" + str(counter) + ". " + repo_key +"</h2>"
counter+=1;
for tag in repo_dict[repo_key]:
decorated_list_values += "<p class='born'><b>[" + tag + "]</b>: docker pull " + regurl + "/" + repo_key + ":" + tag + "</p><br />"
decorated_list_values += "</li>"
decorated_list_values += "</ul>";
'''decorated_list_values += "<p><h2>" + + " images found !" + "</h2></p>"'''
decorated_list_values += "<script>var options = { valueNames: [ 'name', 'born' ]}; var userList = new List('users', options);</script></body></html>"
return decorated_list_values
def usage():
return "Usage: browser.py <registry_endpoint> <keyword> <value> <ssl>\
\nValid keywords : search, list \
\nValid values:- \
\nFor keyword search, use the value as the image name. For eg:- search redis\
\nFor keyword list, use the value 'all' without quotes to get a list of all the docker image repos. For eg:- list all\
\nFor eg:- python browser.py uname:pwd@registry_endpoint:port search busybox\
\nIf you use SSL, then specify 'ssl'\
\nFor eg:- python browser.py uname:pwd@registry_endpoint:port search busybox ssl\
\nFor more information, visit:- https://github.com/vivekjuneja/docker_registry_cli/"
if __name__ == "__main__":
len_sys_argv = len(sys.argv[1:])
if len_sys_argv < 3:
print usage()
elif len_sys_argv >= 3:
commandlineargs = sys.argv[1:]
regurl = commandlineargs[0]
keyword = commandlineargs[1]
repo_to_search = commandlineargs[2]
ssl_flag = False
if len_sys_argv == 4:
ssl = commandlineargs[3]
if ssl == "ssl":
ssl_flag = True
search_results = None
if keyword=="search":
search_results = search_for_repo(regurl, repo_to_search, ssl_flag)
print decorate_list(search_results)
elif keyword=="list":
all_repos = get_all_repos(regurl, ssl_flag)
search_results = get_all_repo_dict(regurl, all_repos, ssl_flag)
print decorate_list(search_results)
elif keyword=="html":
all_repos = get_all_repos(regurl, ssl_flag)
search_results = get_all_repo_dict(regurl, all_repos, ssl_flag)
print decorate_html(search_results, regurl)
else:
print usage()
sys.exit(1)