Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
clarkxuyang committed Jan 13, 2025
1 parent c969ada commit abb88d6
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 65 deletions.
1 change: 1 addition & 0 deletions .github/workflows/publish-azure-cc-enclave-docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ jobs:
echo "jar_version=$(mvn help:evaluate -Dexpression=project.version | grep -e '^[1-9][^\[]')" >> $GITHUB_OUTPUT
echo "git_commit=$(git show --format="%h" --no-patch)" >> $GITHUB_OUTPUT
cp -r target ${{ env.DOCKER_CONTEXT_PATH }}/
cp scripts/confidential_compute.py ${{ env.DOCKER_CONTEXT_PATH }}/
- name: Log in to the Docker container registry
uses: docker/login-action@v3
Expand Down
4 changes: 2 additions & 2 deletions scripts/aws/ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def __run_config_server(self) -> None:
json.dump(self.configs, config_file)
os.chdir("/opt/uid2operator/config-server")
command = ["./bin/flask", "run", "--host", AuxiliaryConfig.LOCALHOST, "--port", AuxiliaryConfig.FLASK_PORT]
self.run_command(command, seperate_process=True)
self.run_command(command, separate_process=True)

def __run_socks_proxy(self) -> None:
"""
Expand Down Expand Up @@ -204,7 +204,7 @@ def __run_nitro_enclave(self):
if self.configs.get('debug_mode', False):
print("Running in debug_mode")
command += ["--debug-mode", "--attach-console"]
self.run_command(command, seperate_process=True)
self.run_command(command, separate_process=True)

def run_compute(self) -> None:
"""Main execution flow for confidential compute."""
Expand Down
8 changes: 5 additions & 3 deletions scripts/azure-cc/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ COPY ./target/${JAR_NAME}-${JAR_VERSION}-sources.jar /app
COPY ./target/${JAR_NAME}-${JAR_VERSION}-static.tar.gz /app/static.tar.gz
COPY ./conf/*.json /app/conf/
COPY ./conf/*.xml /app/conf/
COPY ./azureEntryPoint.py /app
COPY ./confidential_compute.py /app

# Extract and clean up tar.gz
RUN tar xzvf /app/static.tar.gz --no-same-owner --no-same-permissions && \
rm -f /app/static.tar.gz

COPY ./azureEntryPoint.py /app
COPY ./confidential_compute.py /app
RUN chmod a+x /app/*.py

# Create and configure non-root user
RUN adduser -D uid2-operator && \
mkdir -p /opt/uid2 && chmod 777 -R /opt/uid2 && \
Expand All @@ -50,4 +52,4 @@ RUN adduser -D uid2-operator && \
USER uid2-operator

# Run the Python entry point
CMD ["python3", "/app/azureEntryPoint.py"]
CMD python3 /app/azureEntryPoint.py
87 changes: 37 additions & 50 deletions scripts/azure-cc/azureEntryPoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import sys
import shutil
import requests
import logging

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from confidential_compute import ConfidentialCompute, ConfidentialComputeConfig, MissingConfig, ConfidentialComputeStartupException
Expand Down Expand Up @@ -34,26 +35,7 @@ def __check_env_variables(self):
raise MissingConfig(self.__class__.__name__, ["OPERATOR_KEY_SECRET_NAME"])
if AzureEntryPoint.env_name is None:
raise MissingConfig(self.__class__.__name__, ["DEPLOYMENT_ENVIRONMENT"])
print("Env variables validation success")

def __wait_for_sidecar():
url = "http://169.254.169.254/ping"
delay = 2
max_retries = 15

while True:
try:
response = requests.get(url, timeout=5)
if response.status_code == 200:
print("Sidecar started")
break
except requests.RequestException:
print(f"Sidecar not started. Retrying in {delay} seconds...")
time.sleep(delay)
if delay > max_retries:
print("Sidecar failed to start")
break
delay += 1
logging.info("Env variables validation success")

def __set_environment(self):
self.configs["environment"] = AzureEntryPoint.env_name
Expand All @@ -68,54 +50,52 @@ def _set_secret(self, secret_identifier: str = None):
self.configs["api_token"] = secret.value

except CredentialUnavailableError as auth_error:
print(f"Read operator key, authentication error: {auth_error}")
logging.error(f"Read operator key, authentication error: {auth_error}")
raise

except ResourceNotFoundError as not_found_error:
print(f"Read operator key, secret not found: {AzureEntryPoint.secret_name}. Error: {not_found_error}")
logging.error(f"Read operator key, secret not found: {AzureEntryPoint.secret_name}. Error: {not_found_error}")
raise

except HttpResponseError as http_error:
print(f"Read operator key, HTTP error occurred: {http_error}")
logging.error(f"Read operator key, HTTP error occurred: {http_error}")
raise

except Exception as e:
print(f"Read operator key, an unexpected error occurred: {e}")
logging.error(f"Read operator key, an unexpected error occurred: {e}")
raise

def __create_final_config(self):
TARGET_CONFIG = f"/app/conf/{AzureEntryPoint.env_name}-uid2-config.json"
if not os.path.isfile(TARGET_CONFIG):
print(f"Unrecognized config {TARGET_CONFIG}")
logging.error(f"Unrecognized config {TARGET_CONFIG}")
sys.exit(1)

FINAL_CONFIG = "/tmp/final-config.json"
print(f"-- copying {TARGET_CONFIG} to {FINAL_CONFIG}")
logging.info(f"-- copying {TARGET_CONFIG} to {AzureEntryPoint.FINAL_CONFIG}")
try:
shutil.copy(TARGET_CONFIG, FINAL_CONFIG)
shutil.copy(TARGET_CONFIG, AzureEntryPoint.FINAL_CONFIG)
except IOError as e:
print(f"Failed to create {FINAL_CONFIG} with error: {e}")
logging.error(f"Failed to create {AzureEntryPoint.FINAL_CONFIG} with error: {e}")
sys.exit(1)

CORE_BASE_URL = os.getenv("CORE_BASE_URL")
OPTOUT_BASE_URL = os.getenv("OPTOUT_BASE_URL")
if CORE_BASE_URL and OPTOUT_BASE_URL and AzureEntryPoint.env_name != 'prod':
print(f"-- replacing URLs by {CORE_BASE_URL} and {OPTOUT_BASE_URL}")
with open(FINAL_CONFIG, "r") as file:
logging.info(f"-- replacing URLs by {CORE_BASE_URL} and {OPTOUT_BASE_URL}")
with open(AzureEntryPoint.FINAL_CONFIG, "r") as file:
config = file.read()

config = config.replace("https://core-integ.uidapi.com", CORE_BASE_URL)
config = config.replace("https://optout-integ.uidapi.com", OPTOUT_BASE_URL)

with open(FINAL_CONFIG, "w") as file:
with open(AzureEntryPoint.FINAL_CONFIG, "w") as file:
file.write(config)

with open(FINAL_CONFIG, "r") as file:
print(file.read())
with open(AzureEntryPoint.FINAL_CONFIG, "r") as file:
logging.info(file.read())

def __set_baseurls(self):
final_config="/tmp/final-config.json"
with open(final_config, "r") as file:
with open(AzureEntryPoint.FINAL_CONFIG, "r") as file:
jdata = json.load(file)
self.configs["core_base_url"] = jdata["core_attest_url"]
self.configs["optout_base_url"] = jdata["optout_api_uri"]
Expand All @@ -133,28 +113,34 @@ def __run_operator(self):
"-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory",
"-Dlogback.configurationFile=/app/conf/logback.xml",
f"-Dvertx-config-path={AzureEntryPoint.FINAL_CONFIG}",
f"-jar {AzureEntryPoint.jar_name}-{AzureEntryPoint.jar_version}.jar"
"-jar",
f"{AzureEntryPoint.jar_name}-{AzureEntryPoint.jar_version}.jar"
]
print("-- starting java operator application")
self.run_command(java_command, seperate_process=False)
logging.info("-- starting java operator application")
self.run_command(java_command, separate_process=False)

def __wait_for_sidecar(self):
logging.info("Waiting for sidecar ...")

url = "http://169.254.169.254/ping"
delay = 1
max_retries = 15

while True:
try:
response = requests.get(url, timeout=5)
if response.status_code == 200:
print("Sidecar started")
if response.status_code in [200, 204]:
logging.info("Sidecar started")
return
except requests.RequestException:
print(f"Sidecar not started. Retrying in {delay} seconds...")
time.sleep(delay)
else:
error_msg = f"Unexpected status code: {response.status_code}, response: {response.text}"
raise Exception(error_msg)
except Exception as e:
if delay > max_retries:
print("Sidecar failed to start")
break
logging.error(f"Sidecar failed to start after {delay} retries with error {e}", exc_info=True)
sys.exit(1)
logging.info(f"Sidecar not started. Retrying in {delay} seconds... {e}")
time.sleep(delay)
delay += 1

def run_compute(self) -> None:
Expand All @@ -166,7 +152,6 @@ def run_compute(self) -> None:
self.__set_baseurls()
if not self.configs.get("skip_validations"):
self.validate_configuration()

self.__wait_for_sidecar()
self.__run_operator()

Expand All @@ -179,11 +164,13 @@ def _validate_auxiliaries(self) -> None:
pass

if __name__ == "__main__":

logging.basicConfig(level=logging.INFO)
logging.info("Start AzureEntryPoint")
try:
operator = AzureEntryPoint()
operator.run_compute()

except ConfidentialComputeStartupException as e:
print("Failed starting up Azure Confidential Compute. Please checks the logs for errors and retry \n", e)
logging.error(f"Failed starting up Azure Confidential Compute. Please checks the logs for errors and retry {e}", exc_info=True)
except Exception as e:
print("Unexpected failure while starting up Azure Confidential Compute. Please contact UID support team with this log \n ", e)
logging.error(f"Unexpected failure while starting up Azure Confidential Compute. Please contact UID support team with this log {e}", exc_info=True)
21 changes: 11 additions & 10 deletions scripts/confidential_compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from abc import ABC, abstractmethod
from typing import TypedDict, NotRequired, get_type_hints
import subprocess
import logging

class ConfidentialComputeConfig(TypedDict):
api_token: str
Expand Down Expand Up @@ -55,7 +56,7 @@ def __init__(self):

def validate_configuration(self):
""" Validates the paramters specified through configs/secret manager ."""
print("Validating configurations provided")
logging.info("Validating configurations provided")
def validate_operator_key():
""" Validates the operator key format and its environment alignment."""
operator_key = self.configs.get("api_token")
Expand All @@ -66,9 +67,9 @@ def validate_operator_key():
expected_env = "I" if debug_mode or env == "integ" else "P"
if operator_key.split("-")[2] != expected_env:
raise InvalidOperatorKey(self.__class__.__name__)
print("Validated operator key matches environment")
logging.info("Validated operator key matches environment")
else:
print("Skipping operator key validation")
logging.info("Skipping operator key validation")

def validate_url(url_key, environment):
"""URL should include environment except in prod"""
Expand All @@ -77,15 +78,15 @@ def validate_url(url_key, environment):
parsed_url = urlparse(self.configs[url_key])
if parsed_url.scheme != 'https' and parsed_url.path:
raise InvalidConfigValue(self.__class__.__name__, url_key)
print(f"Validated {self.configs[url_key]} matches other config parameters")
logging.info(f"Validated {self.configs[url_key]} matches other config parameters")

def validate_connectivity() -> None:
""" Validates that the core URL is accessible."""
try:
core_url = self.configs["core_base_url"]
core_ip = socket.gethostbyname(urlparse(core_url).netloc)
requests.get(core_url, timeout=5)
print(f"Validated connectivity to {core_url}")
logging.info(f"Validated connectivity to {core_url}")
except (requests.ConnectionError, requests.Timeout) as e:
raise UID2ServicesUnreachable(self.__class__.__name__, core_ip)
except Exception as e:
Expand All @@ -108,7 +109,7 @@ def validate_connectivity() -> None:
validate_url("optout_base_url", environment)
validate_operator_key()
validate_connectivity()
print("Completed static validation of confidential compute config values")
logging.info("Completed static validation of confidential compute config values")

@abstractmethod
def _set_secret(self, secret_identifier: str) -> None:
Expand All @@ -133,13 +134,13 @@ def run_compute(self) -> None:
pass

@staticmethod
def run_command(command, seperate_process=False):
print(f"Running command: {' '.join(command)}")
def run_command(command, separate_process=False):
logging.info(f"Running command: {' '.join(command)}")
try:
if seperate_process:
if separate_process:
subprocess.Popen(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
else:
subprocess.run(command,check=True)
except Exception as e:
print(f"Failed to run command: {str(e)}")
logging.error(f"Failed to run command: {e}", exc_info=True)
raise RuntimeError (f"Failed to start {' '.join(command)} ")

0 comments on commit abb88d6

Please sign in to comment.