Skip to content

Commit 7ebaebf

Browse files
authored
Merge pull request #16 from IBM/v6.1
merge code changes for v6.1.1
2 parents f698063 + 16f35c4 commit 7ebaebf

File tree

10 files changed

+282
-67
lines changed

10 files changed

+282
-67
lines changed

example_deployment_scripts/bridge_deployment/bridge-deployment.yaml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ spec:
5656
- name: SERVER
5757
value: $(IBM_SPECTRUM_SCALE_PERF_QUERY_SERVICE_HOST)
5858
- name: TLSKEYPATH
59-
value: /opt/registry/certs
59+
value: /etc/bridge_ssl/certs
60+
- name: TLSKEYFILE
61+
value: "tls.key"
62+
- name: TLSCERTFILE
63+
value: "tls.crt"
6064
- name: PORT
6165
value: "8443"
6266
imagePullPolicy: Always
@@ -67,16 +71,17 @@ spec:
6771
containerPort: 8443
6872
volumeMounts:
6973
- name: logfiles
70-
mountPath: /opt/IBM/bridge/logs
74+
mountPath: /var/log/ibm_bridge_for_grafana/
7175
- name: config
7276
mountPath: /opt/IBM/zimon/
7377
readOnly: true
7478
optional: true
7579
- name: secret-volume
76-
mountPath: /opt/registry/certs
80+
mountPath: /etc/bridge_ssl/certs
81+
type: DirectoryOrCreate
7782
initContainers:
7883
- name: init-scale-perf-query-service
79-
image: busybox:1.28
84+
image: busybox:latest
8085
command: ['sh', '-c', "until nslookup ibm-spectrum-scale-perf-query.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for ibm-spectrum-scale-perf-query service; sleep 2; done"]
8186
#######################################################################################################################
8287
#

source/Dockerfile

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,16 @@ ARG HTTPPORT=4242
2323
ENV PORT=$HTTPPORT
2424
RUN echo "the HTTP/S port is set to $PORT"
2525

26-
ARG CERTPATH
26+
ARG CERTPATH=None
2727
ENV TLSKEYPATH=$CERTPATH
28-
RUN if [ -z "$TLSKEYPATH" ] && [ "$PORT" -eq 8443 ]; then echo "TLSKEYPATH FOR SSL CONNECTION NOT SET - ERROR"; exit 1; else echo "PASS"; fi
28+
29+
ARG KEYFILE=None
30+
ENV TLSKEYFILE=$KEYFILE
31+
32+
ARG CERTFILE=None
33+
ENV TLSCERTFILE=$CERTFILE
34+
35+
RUN if [ -z "$TLSKEYPATH" ] || [ -z "$TLSCERTFILE" ] || [ -z "$TLSKEYFILE" ] && [ "$PORT" -eq 8443 ]; then echo "TLSKEYPATH FOR SSL CONNECTION NOT SET - ERROR"; exit 1; else echo "PASS"; fi
2936
RUN echo "the ssl certificates path is set to $TLSKEYPATH"
3037

3138
ARG PMCOLLECTORIP=0.0.0.0
@@ -35,7 +42,7 @@ RUN echo "the pmcollector server ip is set to $SERVER"
3542

3643
WORKDIR /opt/IBM/bridge
3744

38-
ARG DEFAULTLOGPATH='./logs/zserver.log'
45+
ARG DEFAULTLOGPATH='/var/log/ibm_bridge_for_grafanalogs/install.log'
3946
ENV LOGPATH=$DEFAULTLOGPATH
4047
RUN mkdir -p $(dirname $LOGPATH)
4148
RUN echo "the log will use $(dirname $LOGPATH)"
@@ -47,7 +54,7 @@ RUN echo "pmcollector_server: $SERVER" >> $LOGPATH
4754
RUN echo "ssl certificates location: $TLSKEYPATH" >> $LOGPATH
4855
RUN echo "HTTP/S port: $PORT" >> $LOGPATH
4956

50-
CMD ["sh", "-c", "python3 zimonGrafanaIntf.py -c 10 -s $SERVER -p $PORT -t $TLSKEYPATH"]
57+
CMD ["sh", "-c", "python3 zimonGrafanaIntf.py -c 10 -s $SERVER -p $PORT -t $TLSKEYPATH --tlsKeyFile $TLSKEYFILE --tlsCertFile $TLSCERTFILE"]
5158

5259
EXPOSE 4242 8443
5360

source/__init__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'''
2+
##############################################################################
3+
# Copyright 2019 IBM Corp.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
##############################################################################
17+
18+
Created on Apr 4, 2017
19+
20+
@author: HWASSMAN
21+
'''
22+
import os
23+
import sys
24+
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))

source/confParser.py

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,67 @@
2424
import os
2525
import logging.handlers
2626
from messages import MSG
27+
import configparser
2728

2829

29-
def findKeyFile(path):
30-
for name in ["privkey.pem", "tls.key"]:
31-
for root, dirs, files in os.walk(path):
32-
if name in files:
33-
return name
34-
return None
30+
def checkFileExists(path, filename):
31+
for root, dirs, files in os.walk(path):
32+
if filename in files:
33+
return True
34+
return False
3535

3636

37-
def findCertFile(path):
38-
for name in ["cert.pem", "tls.crt"]:
39-
for root, dirs, files in os.walk(path):
40-
if name in files:
41-
return name
42-
return None
37+
def checkTLSsettings(args):
38+
if args.get('port') == 8443 and (not args.get('tlsKeyPath') or not args.get('tlsKeyFile') or not args.get('tlsCertFile')):
39+
return False, MSG['MissingParm']
40+
elif args.get('port') == 8443 and not os.path.exists(args.get('tlsKeyPath')):
41+
return False, MSG['KeyPathError']
42+
elif args.get('port') == 8443:
43+
if (not checkFileExists(args.get('tlsKeyPath'), args.get('tlsCertFile'))) or (not checkFileExists(args.get('tlsKeyPath'), args.get('tlsKeyFile'))):
44+
return False, MSG['CertError']
45+
return True, ''
46+
47+
48+
def getSettings(argv):
49+
settings = {}
50+
msg = ''
51+
args, msg = parse_cmd_args(argv)
52+
defaults = parse_defaults_from_config_file()
53+
if args and defaults:
54+
settings = merge_defaults_and_args(defaults, args)
55+
elif args:
56+
settings = args
57+
else:
58+
return None, msg
59+
# check TLS settings
60+
valid, msg = checkTLSsettings(settings)
61+
if valid:
62+
return settings, ''
63+
return None, msg
64+
65+
66+
def merge_defaults_and_args(defaults, args):
67+
'''merge default config parameters with input parameters from the command line'''
68+
brConfig = {}
69+
brConfig = dict(defaults)
70+
args = vars(args)
71+
brConfig.update({k: v for k, v in args.items() if v is not None})
72+
return brConfig
73+
74+
75+
def parse_defaults_from_config_file(fileName='config.ini'):
76+
'''parse default parameters from a config file'''
77+
defaults = {}
78+
dirname, filename = os.path.split(os.path.abspath(__file__))
79+
conf_file = os.path.join(dirname, fileName)
80+
if os.path.isfile(conf_file):
81+
config = configparser.ConfigParser()
82+
config.optionxform = str
83+
config.read(conf_file)
84+
for sect in config.sections():
85+
for name, value in config.items(sect):
86+
defaults[name] = value
87+
return defaults
4388

4489

4590
def parse_cmd_args(argv):
@@ -51,21 +96,13 @@ def parse_cmd_args(argv):
5196
NOTE: Per default ZIMon does not accept queries from remote machines. \
5297
To run the bridge from outside of the ZIMon collector, you need to modify ZIMon queryinterface settings (\'ZIMonCollector.cfg\')')
5398
parser.add_argument('-P', '--serverPort', action="store", type=int, default=9084, help='ZIMon collector port number (Default: 9084)')
54-
parser.add_argument('-l', '--logFile', action="store", default="./logs/zserver.log", help='location of the log file (Default: ./logs/zserver.log')
99+
parser.add_argument('-l', '--logPath', action="store", default="/var/log/ibm_bridge_for_grafana", help='location path of the log file (Default: /var/log/ibm_bridge_for_grafana')
100+
parser.add_argument('-f', '--logFile', action="store", default="zserver.log", help='Name of the log file (Default: zserver.log')
55101
parser.add_argument('-c', '--logLevel', action="store", type=int, default=logging.INFO, help='log level 10 (DEBUG), 20 (INFO), 30 (WARN), 40 (ERROR) (Default: 20)')
56102
parser.add_argument('-p', '--port', action="store", type=int, choices=[4242, 8443], default=4242, help='port number listening on for HTTP(S) connections (Default: 4242)')
57-
parser.add_argument('-t', '--tlsKeyPath', action="store", help='Directory path of tls privkey.pem and cert.pem file location (Required only for HTTPS port 8443)')
103+
parser.add_argument('-t', '--tlsKeyPath', action="store", default=None, help='Directory path of tls privkey.pem and cert.pem file location (Required only for HTTPS port 8443)')
104+
parser.add_argument('-k', '--tlsKeyFile', action="store", default=None, help='Name of TLS key file, f.e.: privkey.pem (Required only for HTTPS port 8443)')
105+
parser.add_argument('-m', '--tlsCertFile', action="store", default=None, help='Name of TLS certificate file, f.e.: cert.pem (Required only for HTTPS port 8443)')
58106

59107
args = parser.parse_args(argv)
60-
61-
if args.port == 8443 and not args.tlsKeyPath:
62-
return None, MSG['MissingParm']
63-
elif args.port == 8443 and not os.path.exists(args.tlsKeyPath):
64-
return None, MSG['KeyPathError']
65-
elif args.port == 8443:
66-
certFile = findCertFile(args.tlsKeyPath)
67-
keyFile = findKeyFile(args.tlsKeyPath)
68-
if (not certFile) or (not keyFile):
69-
return None, MSG['CertError']
70-
71108
return args, ''

source/config.ini

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
##################### Grafana Connection Defaults ############################
2+
[connection]
3+
# port number the bridge listening on for Grafana data requests
4+
# 4242 - for HTTP connections
5+
# 8443 - for HTTPS connections
6+
# (Default: 4242)
7+
port = 4242
8+
9+
#################################### Grafana Generic OAuth ####################
10+
[tls]
11+
# Directory path of tls key and cert file location
12+
#tlsKeyPath = /etc/bridge_cert/
13+
14+
#
15+
#tlsKeyFile = privkey.pem
16+
17+
#
18+
#tlsCertFile = cert.pem
19+
20+
#################################### GPFS Server ##############################
21+
[server]
22+
# The ip address to bind to, empty will bind to all interfaces
23+
server = localhost
24+
25+
# The http port to use
26+
serverPort = 9084
27+
28+
#################################### Logging ##################################
29+
[logging]
30+
# Directory where the bridge can store logs
31+
logPath = /var/log/ibm_bridge_for_grafana
32+
33+
# log level 10 (DEBUG), 20 (INFO), 30 (WARN), 40 (ERROR) (Default: 20)
34+
logLevel = 20
35+
36+
# Log file name (Default: zserver.log)
37+
logFile = zserver.log

source/messages.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,6 @@
5252
'TimerInfo': 'Processing {} took {} seconds',
5353
'Query2port': 'For better bridge performance multithreaded port {} will be used',
5454
'CollectorConnInfo': 'Connection to the collector server established successfully',
55-
'BridgeVersionInfo': ' *** IBM Spectrum Scale bridge for Grafana - Version: {} ***'
55+
'BridgeVersionInfo': ' *** IBM Spectrum Scale bridge for Grafana - Version: {} ***',
56+
'FileNotFound': 'The file {} not found.'
5657
}

source/zimonGrafanaIntf.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from queryHandler import SensorConfig
3535
from __version__ import __version__
3636
from messages import ERR, MSG
37-
from confParser import parse_cmd_args, findCertFile, findKeyFile
37+
from confParser import getSettings
3838
from collections import defaultdict
3939
from timeit import default_timer as timer
4040

@@ -534,11 +534,11 @@ def processFormJSON(entity):
534534
cherrypy.serving.request.json = json.loads('{}')
535535

536536

537-
def configureLogging(logfile, loglevel):
537+
def configureLogging(logPath, logfile, loglevel):
538538
# create the logfile path if needed
539-
path, folder = os.path.split(logfile)
540-
if not os.path.exists(path):
541-
os.makedirs(path)
539+
if not os.path.exists(logPath):
540+
os.makedirs(logPath)
541+
logfile = os.path.join(logPath, logfile)
542542

543543
# prepare the logger
544544
logger = logging.getLogger('zimonGrafanaIntf')
@@ -556,32 +556,32 @@ def configureLogging(logfile, loglevel):
556556

557557
def validateCollectorConf(args, logger):
558558

559-
if not (args.server == 'localhost') and not (args.server == '127.0.0.1'):
559+
if not (args.get('server') == 'localhost') and not (args.get('server') == '127.0.0.1'):
560560
try:
561561
s = socket.socket()
562-
s.connect((args.server, args.serverPort))
562+
s.connect((args.get('server'), args.get('serverPort')))
563563
print(MSG['CollectorConnInfo'])
564564
finally:
565565
s.close()
566566
else:
567567
# get queryport
568568
foundPorts = SensorConfig.getCollectorPorts(logger)
569-
if foundPorts and str(args.serverPort) not in foundPorts:
569+
if foundPorts and str(args.get('serverPort')) not in foundPorts:
570570
raise Exception("Invalid serverPort specified. Try with: %s" % str(foundPorts))
571-
elif foundPorts[1] and not (args.serverPort == int(foundPorts[1])):
572-
args.serverPort = int(foundPorts[1])
573-
logger.info(MSG['Query2port'].format(args.serverPort))
571+
elif foundPorts[1] and not (args.get('serverPort') == int(foundPorts[1])):
572+
args['serverPort'] = int(foundPorts[1])
573+
logger.info(MSG['Query2port'].format(args['serverPort']))
574574

575575

576576
def updateCherrypyConf(args):
577577

578-
path, folder = os.path.split(args.logFile)
578+
path = args.get('logPath')
579579
if not os.path.exists(path):
580580
os.makedirs(path)
581581
accesslog = os.path.join(path, 'cherrypy_access.log')
582582
errorlog = os.path.join(path, 'cherrypy_error.log')
583583

584-
globalConfig = {'global': {'server.socket_port': args.port,
584+
globalConfig = {'global': {'server.socket_port': args.get('port'),
585585
'log.access_file': accesslog,
586586
'log.error_file': errorlog}}
587587

@@ -593,8 +593,8 @@ def updateCherrypyConf(args):
593593

594594

595595
def updateCherrypySslConf(args):
596-
certPath = os.path.join(args.tlsKeyPath, findCertFile(args.tlsKeyPath))
597-
keyPath = os.path.join(args.tlsKeyPath, findKeyFile(args.tlsKeyPath))
596+
certPath = os.path.join(args.get('tlsKeyPath'), args.get('tlsCertFile'))
597+
keyPath = os.path.join(args.get('tlsKeyPath'), args.get('tlsKeyFile'))
598598
sslConfig = {'global': {'server.ssl_module': 'builtin',
599599
'server.ssl_certificate': certPath,
600600
'server.ssl_private_key': keyPath}}
@@ -604,25 +604,26 @@ def updateCherrypySslConf(args):
604604
def main(argv):
605605

606606
# parse input arguments
607-
args, msg = parse_cmd_args(argv)
607+
args, msg = getSettings(argv)
608608
if not args:
609609
print(msg)
610+
return
610611

611612
# prepare the logger
612-
logger = configureLogging(args.logFile, args.logLevel)
613-
logger.info('zimonGrafanaItf invoked with parameters:%s', str(args))
613+
logger = configureLogging(args.get('logPath'), args.get('logFile'), args.get('logLevel'))
614614

615615
# prepare cherrypy server configuration
616616
updateCherrypyConf(args)
617-
if args.port == 8443:
617+
if args.get('port') == 8443:
618618
updateCherrypySslConf(args)
619619

620620
# prepare metadata
621621
try:
622622
print("\n" + MSG['BridgeVersionInfo'].format(__version__))
623623
logger.info("%s", MSG['BridgeVersionInfo'].format(__version__))
624+
logger.info('zimonGrafanaItf invoked with parameters:\n %s', "\n".join("{}={}".format(k, v) for k, v in args.items()))
624625
validateCollectorConf(args, logger)
625-
mdHandler = MetadataHandler(logger, args.server, args.serverPort)
626+
mdHandler = MetadataHandler(logger, args.get('server'), args.get('serverPort'))
626627
print(MSG['MetaSuccess'])
627628
print(MSG['ReceivAttrValues'].format('sensors', "\n\n" + "\t".join(mdHandler.metaData.sensorsSpec.keys())))
628629
except (AttributeError, ValueError, TypeError) as e:

0 commit comments

Comments
 (0)