Skip to content

Commit

Permalink
work in progress on script consolidation for kubernetes, #172
Browse files Browse the repository at this point in the history
  • Loading branch information
mmguero committed Apr 18, 2023
1 parent 728b55d commit a79483b
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 13 deletions.
60 changes: 48 additions & 12 deletions scripts/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
EscapeForCurl,
EscapeAnsi,
get_iterable,
get_primary_ip,
LoadStrIfJson,
ParseCurlFile,
RemoveEmptyFolders,
Expand All @@ -69,6 +70,7 @@
PrintNodeStatus,
DeleteNamespace,
StartMalcolm,
get_node_hostnames_and_ips,
)

from base64 import b64encode
Expand Down Expand Up @@ -383,6 +385,36 @@ def status():
raise Exception(f'{sys._getframe().f_code.co_name} does not yet support {orchMode}')


###################################################################################################
def printURLs():
global orchMode

if orchMode is OrchestrationFramework.KUBERNETES:
addrs = get_node_hostnames_and_ips(mastersOnly=True)
if not any((addrs['external'], addrs['hostname'])):
addrs = get_node_hostnames_and_ips(mastersOnly=False)
if addrs['external']:
myIp = addrs['external'][0]
elif addrs['hostname']:
myIp = addrs['hostname'][0]
elif addrs['internal']:
myIp = addrs['internal'][0]
else:
myIp = '<cluster IP>'
else:
myIp = get_primary_ip()

print("\nMalcolm services can be accessed via the following URLs:")
print("------------------------------------------------------------------------------")
print(f" - Arkime: https://{myIp}/")
print(f" - OpenSearch Dashboards: https://{myIp}/dashboards/")
print(f" - PCAP upload (web): https://{myIp}/upload/")
print(f" - PCAP upload (sftp): sftp://username@{myIp}:8022/files/")
print(f" - NetBox: https://{myIp}/netbox/")
print(f" - Account management: https://{myIp}/auth/")
print(f" - Documentation: https://{myIp}/readme/")


###################################################################################################
def netboxBackup(backupFileName=None):
global args
Expand Down Expand Up @@ -608,18 +640,9 @@ def logs():
process.wait(timeout=5.0)
except TimeoutExpired:
process.kill()
# # TODO: Replace 'localhost' with an outwards-facing IP since I doubt anybody is
# accessing these from the Malcolm server.
print("\nStarted Malcolm\n\n")
print("Malcolm services can be accessed via the following URLs:")
print("------------------------------------------------------------------------------")
print(" - Arkime: https://localhost/")
print(" - OpenSearch Dashboards: https://localhost/dashboards/")
print(" - PCAP upload (web): https://localhost/upload/")
print(" - PCAP upload (sftp): sftp://[email protected]:8022/files/")
print(" - NetBox: https://localhost/netbox/\n")
print(" - Account management: https://localhost/auth/\n")
print(" - Documentation: https://localhost/readme/\n")

print("\nStarted Malcolm\n")
printURLs()

process.poll()

Expand Down Expand Up @@ -1718,6 +1741,15 @@ def main():
default=False,
help="Display status of Malcolm components",
)
parser.add_argument(
'--urls',
dest='cmdPrintURLs',
type=str2bool,
nargs='?',
const=True,
default=False,
help="Display Malcolm URLs",
)

try:
parser.error = parser.exit
Expand Down Expand Up @@ -1878,6 +1910,10 @@ def main():
if args.cmdStatus:
status()

# display Malcolm URLS
if args.cmdPrintURLs:
printURLs()

# backup NetBox files
if args.netboxBackupFile is not None:
print(f"NetBox configuration database saved to {netboxBackup(args.netboxBackupFile)}")
Expand Down
43 changes: 43 additions & 0 deletions scripts/malcolm_kubernetes.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
MalcolmPath,
)
from malcolm_utils import (
deep_get,
eprint,
file_contents,
remove_suffix,
tablify,
LoadStrIfJson,
val2bool,
)


Expand Down Expand Up @@ -235,6 +238,46 @@ def pod_stats(node, namespace):
return pod_dict


def get_node_hostnames_and_ips(mastersOnly=False):
result = {}
result['hostname'] = list()
result['external'] = list()
result['internal'] = list()

if (
(kubeImported := KubernetesDynamic())
and (k8s_api := kubeImported.client.CoreV1Api())
and (
node_stats := kubeImported.client.CustomObjectsApi().list_cluster_custom_object(
"metrics.k8s.io", "v1beta1", "nodes"
)
)
):
for stat in node_stats['items']:
if (not mastersOnly) or any(
[
val2bool(deep_get(stat, ['metadata', 'labels', l], default=False))
for l in ('node-role.kubernetes.io/control-plane', 'node-role.kubernetes.io/master')
]
):
api_response = k8s_api.read_node_status(stat['metadata']['name'])
result['hostname'].extend(
(list(set([x.address for x in api_response.status.addresses if not x.type.endswith('IP')])))
)
result['external'].extend(
(list(set([x.address for x in api_response.status.addresses if x.type.endswith('ExternalIP')])))
)
result['internal'].extend(
(list(set([x.address for x in api_response.status.addresses if x.type.endswith('InternalIP')])))
)

result['hostname'] = list(set(result['hostname']))
result['external'] = list(set(result['external']))
result['internal'] = list(set(result['internal']))

return result


def PrintNodeStatus():
node_list = load_node_list()
with ThreadPoolExecutor() as executor:
Expand Down
18 changes: 17 additions & 1 deletion scripts/malcolm_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,22 @@ def isipaddress(value):
return result


###################################################################################################
# return the primary IP (the one with a default route) on the local box
def get_primary_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(0)
try:
# this IP doesn't have to be reachable
s.connect(('10.254.254.254', 1))
ip = s.getsockname()[0]
except Exception:
ip = '127.0.0.1'
finally:
s.close()
return ip


###################################################################################################
# attempt to decode a string as JSON, returning the object if it decodes and None otherwise
def LoadStrIfJson(jsonStr):
Expand Down Expand Up @@ -469,7 +485,7 @@ def touch(filename):


###################################################################################################
# read the contents of a text file
# read the contents of a file, first assuming text (with encoding), optionally falling back to binary
def file_contents(filename, encoding='utf-8', binary_fallback=False):
if os.path.isfile(filename):
decodeErr = False
Expand Down

0 comments on commit a79483b

Please sign in to comment.