Skip to content

Commit 5764025

Browse files
committed
Fix: more python3 stuff
Fix: Compliance get url now works with python3 & https ^^ Add: first compliance url with python3
1 parent 477cb45 commit 5764025

File tree

10 files changed

+113
-50
lines changed

10 files changed

+113
-50
lines changed

data/global-configuration/packs/core-cli-compliance/cli/cli.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
# Gabes Jean, [email protected]
66

77
from __future__ import print_function
8-
import json
98
import time
109
import sys
1110

@@ -15,6 +14,7 @@
1514
from opsbro.cli import get_opsbro_local, put_opsbro_json
1615
from opsbro.cli_display import print_h1, print_h2, get_terminal_size
1716
from opsbro.compliancemgr import COMPLIANCE_LOG_COLORS, COMPLIANCE_STATES, COMPLIANCE_STATE_COLORS
17+
from opsbro.jsonmgr import jsoner
1818

1919

2020
def __print_rule_entry(rule):
@@ -74,7 +74,7 @@ def do_compliance_state(compliance_name=''):
7474
return
7575

7676
try:
77-
compliances = json.loads(r)
77+
compliances = jsoner.loads(r)
7878
except ValueError as exp: # bad json
7979
logger.error('Bad return from the server %s' % exp)
8080
return
@@ -87,12 +87,12 @@ def do_compliance_state(compliance_name=''):
8787
if pack_name not in packs:
8888
packs[pack_name] = {}
8989
packs[pack_name][cname] = compliance
90-
pnames = packs.keys()
90+
pnames = list(packs.keys()) # python3
9191
pnames.sort()
9292
for pname in pnames:
9393
pack_entries = packs[pname]
9494
cprint('* Pack %s' % pname, color='blue')
95-
cnames = pack_entries.keys()
95+
cnames = list(pack_entries.keys()) # python3
9696
cnames.sort()
9797
for cname in cnames:
9898
cprint(' - %s' % pname, color='blue', end='')
@@ -109,7 +109,7 @@ def do_compliance_history():
109109
return
110110

111111
try:
112-
histories = json.loads(r)
112+
histories = jsoner.loads(r)
113113
except ValueError as exp: # bad json
114114
logger.error('Bad return from the server %s' % exp)
115115
return
@@ -147,7 +147,7 @@ def do_compliance_wait_compliant(compliance_name, timeout=30, exit_if_ok=True):
147147
spinners = itertools.cycle(CHARACTERS.spinners)
148148

149149
current_state = COMPLIANCE_STATES.UNKNOWN
150-
for i in xrange(timeout):
150+
for i in range(timeout): # no xrange in python3
151151
uri = '/compliance/state'
152152
try:
153153
(code, r) = get_opsbro_local(uri)
@@ -156,7 +156,7 @@ def do_compliance_wait_compliant(compliance_name, timeout=30, exit_if_ok=True):
156156
return
157157

158158
try:
159-
compliances = json.loads(r)
159+
compliances = jsoner.loads(r)
160160
except ValueError as exp: # bad json
161161
logger.error('Bad return from the server %s' % exp)
162162
return
@@ -179,7 +179,7 @@ def do_compliance_wait_compliant(compliance_name, timeout=30, exit_if_ok=True):
179179
except: # beware, maybe we don't have a tty
180180
terminal_width = 100
181181
cprint('\r' + ' ' * terminal_width, end='')
182-
cprint('\r %s ' % spinners.next(), color='blue', end='')
182+
cprint('\r %s ' % next(spinners), color='blue', end='') # no spinnner.next in python3
183183
cprint('%s' % compliance_name, color='magenta', end='')
184184
cprint(' is ', end='')
185185
cprint('%15s ' % current_state, color=COMPLIANCE_STATE_COLORS.get(current_state, 'cyan'), end='')

data/global-configuration/packs/core-functions/compliancebackends/compliancebackend_geturl.py

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
from __future__ import print_function
2-
import urllib2
32
import shutil
43
import os
5-
import urlparse
6-
import ssl
4+
5+
try: # Python 2
6+
from urlparse import urlparse
7+
except ImportError:
8+
from urllib.parse import urlparse
79
import hashlib
810

911
from opsbro.compliancemgr import InterfaceComplianceDriver
1012
from opsbro.util import make_dir
13+
from opsbro.httpclient import get_http_exceptions, httper
1114

1215

1316
class GetURLDriver(InterfaceComplianceDriver):
@@ -16,17 +19,6 @@ class GetURLDriver(InterfaceComplianceDriver):
1619

1720
def __init__(self):
1821
super(GetURLDriver, self).__init__()
19-
20-
# NOTE: ssl.SSLContext is only availabe on last python 2.7 versions
21-
if hasattr(ssl, 'SSLContext'):
22-
# NOTE: was before, but seems to be not as large as default context
23-
## self.ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
24-
self.ssl_context = ssl.create_default_context()
25-
self.ssl_context.options &= ~ssl.OP_NO_SSLv3 # reenable SSLv3 if need
26-
self.ssl_context.check_hostname = False
27-
self.ssl_context.verify_mode = ssl.CERT_NONE
28-
else:
29-
self.ssl_context = None
3022

3123

3224
# environments: <- take first to win
@@ -67,7 +59,7 @@ def launch(self, rule):
6759
rule.set_error()
6860
return
6961

70-
parsed_uri = urlparse.urlparse(url)
62+
parsed_uri = urlparse(url)
7163
file_name = os.path.basename(parsed_uri.path)
7264
self.logger.debug("TRY DOWNLOADING %s => %s " % (url, file_name))
7365

@@ -95,12 +87,8 @@ def launch(self, rule):
9587

9688
self.logger.debug('START DOWNLOAd', url)
9789
try:
98-
args = {}
99-
if self.ssl_context:
100-
args['context'] = self.ssl_context
101-
filedata = urllib2.urlopen(url, **args)
102-
data = filedata.read()
103-
except Exception as exp:
90+
data = httper.get(url)
91+
except get_http_exceptions() as exp:
10492
err = 'ERROR: downloading the uri: %s did fail withthe error: %s' % (url, exp)
10593
rule.add_error(err)
10694
rule.set_error()

opsbro/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ def wait_for_agent_started(timeout=30, visual_wait=False, exit_if_stopped=False,
213213
if agent_state == 'ok':
214214
break
215215
if visual_wait:
216-
cprint('\r %s ' % spinners.next(), color='blue', end='')
216+
cprint('\r %s ' % next(spinners), color='blue', end='') # note: spinners.next() do not exists in python3
217217
cprint(' agent is still ', end='')
218218
cprint('initializing', color='yellow', end='')
219219
cprint(' (collector, detector,... are not finish)', end='')

opsbro/httpclient.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import urllib
3+
import ssl
34

45
try:
56
from httplib import HTTPException
@@ -8,9 +9,9 @@
89
from socket import error as SocketError
910

1011
try:
11-
from urllib2 import Request, build_opener, URLError, HTTPError, HTTPHandler, HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler
12+
from urllib2 import Request, build_opener, URLError, HTTPError, HTTPHandler, HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, HTTPSHandler
1213
except ImportError:
13-
from urllib.request import Request, build_opener, HTTPHandler, HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler
14+
from urllib.request import Request, build_opener, HTTPHandler, HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, HTTPSHandler
1415
from urllib.error import URLError, HTTPError
1516

1617
_HTTP_EXCEPTIONS = None
@@ -27,23 +28,34 @@ def get_http_exceptions():
2728

2829
class Httper(object):
2930
def __init__(self):
30-
pass
31+
# NOTE: ssl.SSLContext is only availabe on last python 2.7 versions
32+
if hasattr(ssl, 'SSLContext'):
33+
# NOTE: was before, but seems to be not as large as default context
34+
## self.ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
35+
self.ssl_context = ssl.create_default_context()
36+
self.ssl_context.options &= ~ssl.OP_NO_SSLv3 # reenable SSLv3 if need
37+
self.ssl_context.check_hostname = False
38+
self.ssl_context.verify_mode = ssl.CERT_NONE
39+
else:
40+
self.ssl_context = None
3141

3242

33-
@staticmethod
34-
def get(uri, params={}, headers={}, with_status_code=False, timeout=10, user=None, password=None):
43+
def get(self, uri, params={}, headers={}, with_status_code=False, timeout=10, user=None, password=None):
3544
data = None # always none in GET
3645

3746
if params:
3847
uri = "%s?%s" % (uri, urllib.urlencode(params))
3948

40-
# We need both user & password to use them
41-
if not user or not password:
42-
handler = HTTPHandler
43-
else:
49+
# SSL, user/password and basic
50+
# NOTE: currently don't manage ssl & user/password
51+
if uri.startswith('https://'):
52+
handler = HTTPSHandler(context=self.ssl_context)
53+
elif user and password:
4454
passwordMgr = HTTPPasswordMgrWithDefaultRealm()
4555
passwordMgr.add_password(None, uri, user, password)
4656
handler = HTTPBasicAuthHandler(passwordMgr)
57+
else:
58+
handler = HTTPHandler
4759

4860
url_opener = build_opener(handler)
4961

opsbro/jsonmgr.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import json
2-
from .util import byteify
2+
from .util import byteify, string_decode
33

44

55
# Class to wrap several things to json, like manage some utf8 things and such things
@@ -13,6 +13,7 @@ def dumps(self, o):
1313

1414

1515
def loads(self, s):
16+
s = string_decode(s)
1617
return json.loads(s)
1718

1819

opsbro/log.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
from .misc.colorama import init as init_colorama
1818

19+
# Lasy load to avoid recursive import
20+
string_decode = None
21+
1922

2023
def is_tty():
2124
# TODO: what about windows? how to have beautiful & Windows?
@@ -59,17 +62,33 @@ def sprintf(s, color='', end=''):
5962
stdout_utf8 = codecs.getwriter("utf-8")(sys.stdout)
6063

6164

65+
# stdout_utf8.errors = 'ignore'
66+
6267
def cprint(s, color='', on_color='', end='\n'):
68+
global string_decode
69+
if string_decode is None:
70+
from .util import string_decode
71+
string_decode = string_decode
6372
if not isinstance(s, basestring):
6473
s = str(s)
65-
if (PY3 and isinstance(s, bytes)):
66-
print('\n\nTYPE OF s: %s\n\n' % type(s))
67-
s = s.decode('utf8', 'ignore')
68-
if end == '':
69-
stdout_utf8.write(s)
70-
else:
71-
stdout_utf8.write(s)
72-
stdout_utf8.write('\n')
74+
# Python 2 and 3: good luck for unicode in a terminal.
75+
# It's a nightmare to manage all of this, if you have a common code
76+
# that allow to run WITHOUT a terminal, I take it :)
77+
if PY3:
78+
s = string_decode(s)
79+
raw_bytes, consumed = stdout_utf8.encode(s, 'strict')
80+
if end == '':
81+
sys.stdout.buffer.write(raw_bytes)
82+
# stdout_utf8.write(s)
83+
else:
84+
sys.stdout.buffer.write(raw_bytes)
85+
sys.stdout.buffer.write(b'\n')
86+
else: # PY2
87+
if end == '':
88+
stdout_utf8.write(s)
89+
else:
90+
stdout_utf8.write(s)
91+
stdout_utf8.write('\n')
7392

7493

7594
def sprintf(s, color='', end=''):

opsbro/unixclient.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77

88
import os
9-
import json
109
import socket
1110

1211
try: # Python 2
@@ -30,6 +29,7 @@
3029
from urllib.parse import urlsplit
3130

3231
from .log import logger
32+
from .jsonmgr import jsoner
3333

3434
#### For local socket handling
3535
DEFAULT_SOCKET_TIMEOUT = 5
@@ -151,7 +151,7 @@ def get_json(uri, local_socket='', params={}, multi=False, method='GET', timeout
151151
r = "[{0}]".format(r.replace("}{", "},{"))
152152

153153
try:
154-
d = json.loads(r)
154+
d = jsoner.loads(r)
155155
except ValueError as exp: # bad json
156156
logger.debug("ERROR local unix get json raw return did raise an exception in bad json (%s) %s" % (r, exp))
157157
logger.error('Bad return from the server %s: "%s"' % (exp, r))

spike/test_https.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
# -*- coding: utf-8 -*-
3+
import sys
4+
5+
6+
sys.path.insert(0, '.')
7+
8+
uri = 'https://binaries.cockroachdb.com/cockroach-v2.0.0.linux-amd64.tgz'
9+
from opsbro.httpclient import get_http_exceptions, httper
10+
r = httper.get(uri)
11+
print('Result: r')

test/docker-files/docker-file-COMPLIANCE-GET-URL-debian9.txt renamed to test/docker-files/docker-file-COMPLIANCE-GET-URL-PYTHON2-debian9.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ RUN /apt_get_install python-apt
1313

1414
RUN /apt_get_install procps
1515

16+
1617
ADD . /root/opsbro-oss
1718

1819

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FROM debian:9
2+
MAINTAINER Jean Gabes <[email protected]>
3+
4+
ADD test/docker-helper/ /
5+
6+
RUN /apt_get_install python3
7+
# All need for debian, so faster test (we are testging feature here, not install)
8+
RUN /apt_get_install python3-jinja2
9+
RUN /apt_get_install python3-crypto
10+
RUN /apt_get_install python3-setuptools
11+
RUN /apt_get_install python3-apt
12+
13+
# Set python3 as default python
14+
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1
15+
16+
17+
RUN /apt_get_install procps
18+
19+
ADD . /root/opsbro-oss
20+
21+
22+
WORKDIR /root/opsbro-oss
23+
24+
RUN python setup.py install
25+
26+
# Copy the mail pack into a local one to enable modification
27+
RUN opsbro packs overload global.linux
28+
# Copy the new compliance value
29+
ADD test/test-files/test-compliance-get-uri/compliance/install-cockroachdb.yml /var/lib/opsbro/local-configuration/packs/linux/compliance/
30+
31+
ENTRYPOINT test/test_feature_compliance-get-url.sh

0 commit comments

Comments
 (0)