-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
790f506
commit 1f0ef43
Showing
3 changed files
with
285 additions
and
347 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,177 +0,0 @@ | ||
|
||
import argparse | ||
import json | ||
import logging | ||
import os | ||
import socket | ||
import ssl | ||
import threading | ||
import traceback | ||
from base64 import b64encode | ||
from datetime import datetime, timedelta | ||
from functools import partial | ||
|
||
import uvicorn | ||
from cryptography import x509 | ||
from cryptography.hazmat.backends import default_backend | ||
from cryptography.hazmat.primitives import hashes, serialization | ||
from cryptography.hazmat.primitives.asymmetric import rsa | ||
from cryptography.x509.oid import NameOID | ||
from dns import resolver, reversename | ||
from fastapi import Depends, FastAPI, HTTPException, Request, status | ||
from fastapi.encoders import jsonable_encoder | ||
from fastapi.responses import ( | ||
JSONResponse, | ||
PlainTextResponse, | ||
Response, | ||
) | ||
from fastapi.security import ( | ||
HTTPBasic, | ||
HTTPBasicCredentials, | ||
) | ||
from ropt.enums import OptimizerExitCode | ||
|
||
from ert.config import QueueSystem | ||
from ert.ensemble_evaluator import EvaluatorServerConfig | ||
from ert.run_models.everest_run_model import EverestRunModel | ||
from everest import export_to_csv, export_with_progress | ||
from everest.config import EverestConfig, ServerConfig | ||
from everest.detached import ServerStatus, get_opt_status, update_everserver_status | ||
from everest.export import check_for_errors | ||
from everest.simulator import JOB_FAILURE | ||
from everest.strings import ( | ||
EVEREST, | ||
OPT_FAILURE_REALIZATIONS, | ||
OPT_PROGRESS_ENDPOINT, | ||
SIM_PROGRESS_ENDPOINT, | ||
STOP_ENDPOINT, | ||
) | ||
from everest.util import configure_logger, makedirs_if_needed, version_info | ||
|
||
|
||
def _get_machine_name() -> str: | ||
"""Returns a name that can be used to identify this machine in a network | ||
A fully qualified domain name is returned if available. Otherwise returns | ||
the string `localhost` | ||
""" | ||
hostname = socket.gethostname() | ||
try: | ||
# We need the ip-address to perform a reverse lookup to deal with | ||
# differences in how the clusters are getting their fqdn's | ||
ip_addr = socket.gethostbyname(hostname) | ||
reverse_name = reversename.from_address(ip_addr) | ||
resolved_hosts = [ | ||
str(ptr_record).rstrip(".") | ||
for ptr_record in resolver.resolve(reverse_name, "PTR") | ||
] | ||
resolved_hosts.sort() | ||
return resolved_hosts[0] | ||
except (resolver.NXDOMAIN, resolver.NoResolverConfiguration): | ||
# If local address and reverse lookup not working - fallback | ||
# to socket fqdn which are using /etc/hosts to retrieve this name | ||
return socket.getfqdn() | ||
except socket.gaierror: | ||
logging.debug(traceback.format_exc()) | ||
return "localhost" | ||
|
||
|
||
|
||
|
||
def _find_open_port(host, lower, upper) -> int: | ||
for port in range(lower, upper): | ||
try: | ||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
sock.bind((host, port)) | ||
sock.close() | ||
return port | ||
except socket.error: | ||
logging.getLogger("everserver").info( | ||
"Port {} for host {} is taken".format(port, host) | ||
) | ||
msg = "No open port for host {} in the range {}-{}".format(host, lower, upper) | ||
logging.getLogger("everserver").exception(msg) | ||
raise Exception(msg) | ||
|
||
|
||
def _write_hostfile(host_file_path, host, port, cert, auth) -> None: | ||
if not os.path.exists(os.path.dirname(host_file_path)): | ||
os.makedirs(os.path.dirname(host_file_path)) | ||
data = { | ||
"host": host, | ||
"port": port, | ||
"cert": cert, | ||
"auth": auth, | ||
} | ||
json_string = json.dumps(data) | ||
|
||
with open(host_file_path, "w", encoding="utf-8") as f: | ||
f.write(json_string) | ||
|
||
|
||
|
||
|
||
|
||
def _generate_authentication(): | ||
n_bytes = 128 | ||
random_bytes = bytes(os.urandom(n_bytes)) | ||
return b64encode(random_bytes).decode("utf-8") | ||
|
||
|
||
|
||
def _generate_certificate(cert_folder: str): | ||
"""Generate a private key and a certificate signed with it | ||
Both the certificate and the key are written to files in the folder given | ||
by `get_certificate_dir(config)`. The key is encrypted before being | ||
stored. | ||
Returns the path to the certificate file, the path to the key file, and | ||
the password used for encrypting the key | ||
""" | ||
# Generate private key | ||
key = rsa.generate_private_key( | ||
public_exponent=65537, key_size=4096, backend=default_backend() | ||
) | ||
|
||
# Generate the certificate and sign it with the private key | ||
cert_name = _get_machine_name() | ||
subject = issuer = x509.Name( | ||
[ | ||
x509.NameAttribute(NameOID.COUNTRY_NAME, "NO"), | ||
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Bergen"), | ||
x509.NameAttribute(NameOID.LOCALITY_NAME, "Sandsli"), | ||
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Equinor"), | ||
x509.NameAttribute(NameOID.COMMON_NAME, "{}".format(cert_name)), | ||
] | ||
) | ||
cert = ( | ||
x509.CertificateBuilder() | ||
.subject_name(subject) | ||
.issuer_name(issuer) | ||
.public_key(key.public_key()) | ||
.serial_number(x509.random_serial_number()) | ||
.not_valid_before(datetime.utcnow()) | ||
.not_valid_after(datetime.utcnow() + timedelta(days=365)) # 1 year | ||
.add_extension( | ||
x509.SubjectAlternativeName([x509.DNSName("{}".format(cert_name))]), | ||
critical=False, | ||
) | ||
.sign(key, hashes.SHA256(), default_backend()) | ||
) | ||
|
||
# Write certificate and key to disk | ||
makedirs_if_needed(cert_folder) | ||
cert_path = os.path.join(cert_folder, cert_name + ".crt") | ||
with open(cert_path, "wb") as f: | ||
f.write(cert.public_bytes(serialization.Encoding.PEM)) | ||
key_path = os.path.join(cert_folder, cert_name + ".key") | ||
pw = bytes(os.urandom(28)) | ||
with open(key_path, "wb") as f: | ||
f.write( | ||
key.private_bytes( | ||
encoding=serialization.Encoding.PEM, | ||
format=serialization.PrivateFormat.TraditionalOpenSSL, | ||
encryption_algorithm=serialization.BestAvailableEncryption(pw), | ||
) | ||
) | ||
return cert_path, key_path, pw | ||
Oops, something went wrong.