Skip to content
Snippets Groups Projects
Commit 4a7fb922 authored by Diaz de Arcaya Serrano, Josu's avatar Diaz de Arcaya Serrano, Josu
Browse files

y3

parent 9872248e
Branches y3
No related tags found
No related merge requests found
Showing
with 402 additions and 242 deletions
3.9.7
3.9.10
FROM hashicorp/terraform:1.1.4
ARG API_KEY
COPY requirements.txt /tmp/requirements.txt
RUN apk add py3-pip cargo g++ python3-dev file libffi-dev openssl-dev bash python3=3.9.16-r0 gnupg
RUN pip3 install -r /tmp/requirements.txt
# install docker stack
RUN apk add docker docker-compose
ENV API_KEY=$API_KEY
ENV API_KEY=changeme
ENV IEM_HOME=/opt/iem/
ENV DOCKERIZED=true
COPY src/resources/ansible.cfg /etc/ansible/ansible.cfg
COPY requirements.txt /tmp/requirements.txt
COPY src ${IEM_HOME}src
COPY main.py ${IEM_HOME}main.py
RUN apk add py3-pip cargo g++ python3-dev file libffi-dev openssl-dev bash python3=3.9.13-r1 gnupg
RUN pip3 install -r /tmp/requirements.txt
# RUN adduser -h ${IEM_HOME} -S -D iem
COPY certs/config ${IEM_HOME}.ssh/config
......@@ -28,7 +27,14 @@ RUN ansible-galaxy collection install community.general
COPY roles.yml /tmp/roles.yml
RUN ansible-galaxy install -r /tmp/roles.yml
RUN mkdir -p ${IEM_HOME}db && \
mkdir -p ${IEM_HOME}deployments
COPY src ${IEM_HOME}src
COPY main.py ${IEM_HOME}main.py
COPY logging.ini ${IEM_HOME}logging.ini
ENTRYPOINT ["/usr/bin/env"]
WORKDIR ${IEM_HOME}
CMD /usr/bin/uvicorn main:app --host 0.0.0.0
CMD /usr/bin/uvicorn main:app --host 0.0.0.0 --log-level info
EXPOSE 8000
Host *
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
\ No newline at end of file
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA1FrTNE42EgZr9WJNMtvpKFHYhPUJ4lzEp83EM0jYY3TyjmIe
ThMuqMLAHCk22fl4a8PttucggJ5ZWKhcJh623/y8AybJcmqZgq9a41Q609dmirf0
7frCl+6zL8Mqy2Le2BD4eRADcq11s8r8Ys6J+EBPHQgEnK9CeZLSc/WFRlVr4bOD
s0bEouDxjTAMYjYcpsCwqYgGdIXI9WWsnt3RvcEe8CaiTqoyDN8ZtgkG6MweSrTQ
js8ySHO6o25cOoF7aT9Ihhf32I+KUanNIOvk3RAw2z1FK5xkFbbqMggZqz7rJn3M
sn2dDiCQi2CWox2OYXV/jJKLC3UFuOX64fS9cwIDAQABAoIBAQCs69Tm1/Vx0ibh
aA4DJ06C1bsh8cP9v5soJgfp1xzWSGooBcA1xasOI6B6jhkrgNlNr/uIIEe4VLne
1yJKrGIwnUagrloGQMYGxDKXwYQx80p+FXRuwe7p96eUcjIL8tQSUCd1tdOI87VQ
FjBVaWiybfO+aUQQLytLgoK7iKfhb7vO+9F+ZK1iDjBDNxFuiOM5zoeWOI7boYkD
2yXIkwoBePS2rosbPLa649sVakKex2WhQdUFst4Zba2RhnWQBXUY44LvEK5TzScF
FyYphPOUSplbzzM2+fuOna91NIWmJyHmf15lj7X9kC66XFIZMlvapksB8stEpDiA
4al3IdBJAoGBAPPuM3xkr/kQYYn7E42fgpmINZ78V48gMLhpyUOabZtF8inMyMPB
q7kfHns8Vx0ET8grSNr3qwDDV82lwvGqRCFChASMdQRR9LanydkDSeqpuZyQtVlt
A/65YUdcNY7Vy+M+fRh5Srh/6qcO3beLeLWXbJ4RHBP/OEmHuF4mLfgVAoGBAN7c
qdxTOhXPvOU69Bs5rJdfo6qBI1Yg8MCGctsUwPFpw1kW773ROOPa6XI6D74Dsdg8
ypZ+IC3pRVtx61Xi3NOwxWNTTG+dyUgTSFz+WKjywXZXeHIbWngiFqk8JFYQWPzk
6YaJk4tZhk2YuNNaCCYRgQqyWv8coEurRlMXZHlnAoGBALcJwdaQ0z8oXJimL4jw
7ZX5kIrpPWanuAdZUe4Jfj+qX8mf4fKKbCowQLYmlBOw/ZDtcfDlMYsUCdnFjZ+7
rP3sJJYpM1F3khJRm3PdNOUCUMY8C+i7lejZADcE6SdyJFkztbjcowYI7nJHBHZL
ENvqcVW27wPOWlVKozz6lzn1AoGALVwmaoS6DtRwcwuzwZLUkR7TNhIAujgMKHN1
DyhDOR+4tfpYI39hH+dfmnM83wTrfsKozUawkAepqToflySMo72X/2Zl6VXpMPVT
xjGyo/h87fRRvI/asxblG9702luLcTW6XjrEQBmhn0uVWtc5T15CsIWqxb/y1FPx
BVp+hcMCgYAlJXbjzjbbDoIOCsXPSPe9voBL8zVwp0aNuvQcuB/vCt1n1c1DWuPr
AGMy/fRwY0Znag+ODMuulm7RgXUQy6ifJHiz9cKVGg/mGifaJSjgC+1AI9HFlij3
asM5CueU0gK974rDxQkwmIWpRH57+kf6s8tGDrPPvqX9S4p3oxFlTw==
-----END RSA PRIVATE KEY-----
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUWtM0TjYSBmv1Yk0y2+koUdiE9QniXMSnzcQzSNhjdPKOYh5OEy6owsAcKTbZ+Xhrw+225yCAnllYqFwmHrbf/LwDJslyapmCr1rjVDrT12aKt/Tt+sKX7rMvwyrLYt7YEPh5EANyrXWzyvxizon4QE8dCAScr0J5ktJz9YVGVWvhs4OzRsSi4PGNMAxiNhymwLCpiAZ0hcj1Zaye3dG9wR7wJqJOqjIM3xm2CQbozB5KtNCOzzJIc7qjblw6gXtpP0iGF/fYj4pRqc0g6+TdEDDbPUUrnGQVtuoyCBmrPusmfcyyfZ0OIJCLYJajHY5hdX+MkosLdQW45frh9L1z josu@WKM0092A
iem.db
[loggers]
keys=root,src,uvicorn
[handlers]
keys=stream_handler
[formatters]
keys=formatter
[logger_root]
level=INFO
handlers=stream_handler
[logger_src]
level=INFO
handlers=stream_handler
qualname=src
propagate=0
[logger_uvicorn]
level=INFO
handlers=stream_handler
qualname=uvicorn
propagate=0
[handler_stream_handler]
class=StreamHandler
formatter=formatter
[formatter_formatter]
format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s
#!/usr/bin/env python3
import json
import logging
import os
from typing import List
from fastapi import FastAPI, BackgroundTasks, status, Security, Depends, HTTPException
import uvicorn
from fastapi import BackgroundTasks, Depends, FastAPI, HTTPException, Security, status
from fastapi.openapi.utils import get_openapi
from fastapi.security.api_key import APIKeyHeader, APIKey
from typing import List
from fastapi.security.api_key import APIKey, APIKeyHeader
from src.core.iem import Iem
from src.core.persistence import Sqlite
from src.core.persistence import Persistence
from src.core.utils import (
BaseResponse,
DeploymentResponse,
DeploymentRequest,
DeleteDeploymentRequest,
DeploymentRequest,
DeploymentResponse,
SelfHealingRequest,
)
LOGGER = logging.getLogger("iem")
api_key_header = APIKeyHeader(name="x-api-key", auto_error=False)
app = FastAPI(
title="IaC Execution Manager", version="0.1.15", description="IaC Execution Manager"
title="IaC Execution Manager", version="1.0.0", description="IaC Execution Manager"
)
logging.config.fileConfig("logging.ini")
async def get_api_key(api_key_query: str = Security(api_key_header)):
if Sqlite().valid_api_key(api_key_query=api_key_query):
if Persistence().valid_api_key(api_key_query=api_key_query):
return api_key_query
else:
raise HTTPException(
......@@ -37,7 +40,7 @@ async def get_api_key(api_key_query: str = Security(api_key_header)):
@app.get("/", tags=["greeting"])
async def read_root(api_key: APIKey = Depends(get_api_key)):
async def read_root(_: APIKey = Depends(get_api_key)):
return {
"message": "Hello from the IaC Execution Manager!",
"version": app.version,
......@@ -48,11 +51,7 @@ async def read_root(api_key: APIKey = Depends(get_api_key)):
@app.get("/deployments/", response_model=List[DeploymentResponse], tags=["deployments"])
async def read_status(
start: int = 0,
count: int = 25,
start_date: str = "1970-01-01",
end_date: str = "2100-01-01",
api_key: APIKey = Depends(get_api_key),
_: APIKey = Depends(get_api_key),
):
all_deployments = Iem(credentials=None).get_all_deployments()
return list(all_deployments)
......@@ -65,9 +64,7 @@ async def read_status(
)
async def read_status_deployment(
deployment_id: str,
start: int = 0,
count: int = 1,
api_key: APIKey = Depends(get_api_key),
_: APIKey = Depends(get_api_key),
):
deployment = Iem().get_deployment(deployment_id=deployment_id)
return list(deployment)
......@@ -82,11 +79,10 @@ async def read_status_deployment(
async def deploy(
d: DeploymentRequest,
background_tasks: BackgroundTasks,
api_key: APIKey = Depends(get_api_key),
_: APIKey = Depends(get_api_key),
):
logging.warning(d)
i = Iem(credentials=d.credentials)
background_tasks.add_task(i.deploy, d.deployment_id, d.repository, d.commit)
background_tasks.add_task(i.deploy, d.deployment_id, d.bundle.base64)
return BaseResponse(message="Deployment Request Created")
......@@ -99,15 +95,29 @@ async def deploy(
async def undeploy(
d: DeleteDeploymentRequest,
background_tasks: BackgroundTasks,
api_key: APIKey = Depends(get_api_key),
_: APIKey = Depends(get_api_key),
):
logging.warning(d)
i = Iem(credentials=d.credentials)
background_tasks.add_task(i.destroy, d.deployment_id)
return BaseResponse(message="Undeployment Request Created")
if os.getenv("STAGE") == "dev":
@app.post(
"/self-healing/{strategy}",
status_code=status.HTTP_201_CREATED,
response_model=BaseResponse,
tags=["deployments"],
)
async def deploy(
d: SelfHealingRequest,
background_tasks: BackgroundTasks,
_: APIKey = Depends(get_api_key),
):
return BaseResponse(message="Deployment Request Created")
if __name__ == "__main__":
uvicorn.run("main:app", host="127.0.0.1", port=8000, log_level="info")
with open("../openapi.json", "w") as f:
json.dump(
get_openapi(
......
import logging
import os
import subprocess
import time
from abc import ABC, abstractmethod
from jinja2 import Template
from subprocess import CalledProcessError
LOGGER = logging.getLogger("iem")
from jinja2 import Template
LOGGER = logging.getLogger(__name__)
class Factory:
......@@ -58,15 +59,16 @@ class Terraform(Engine):
)
output = subprocess.run(
["terraform", "apply", "-auto-approve"],
check=True,
cwd=self._repo_path,
env=self._env,
# capture_output=True,
capture_output=True,
)
LOGGER.info(output.stdout.decode("utf-8"))
output.check_returncode()
return "CREATED", output.stdout, output.stderr
except CalledProcessError as e:
LOGGER.exception(e)
return "ERROR", None, None
raise e
def destroy(self):
try:
......@@ -75,12 +77,14 @@ class Terraform(Engine):
check=True,
cwd=self._repo_path,
env=self._env,
# capture_output=True,
capture_output=True,
)
LOGGER.info(output.stdout.decode("utf-8"))
output.check_returncode()
return "DESTROYED", output.stdout, output.stderr
except CalledProcessError as e:
LOGGER.exception(e)
return "ERROR", None, None
raise e
def output(self):
try:
......@@ -120,6 +124,7 @@ class Ansible(Engine):
def apply(self):
LOGGER.info("About to apply ansible")
for i in range(2):
try:
output = subprocess.run(
["ansible", "all", "-i", "inventory", "-m", "wait_for_connection"],
......@@ -136,10 +141,13 @@ class Ansible(Engine):
env=self._env,
capture_output=True,
)
LOGGER.info(output.stdout.decode("utf-8"))
return "CREATED", output.stdout, output.stderr
except CalledProcessError as e:
LOGGER.exception(e.output)
if i == 1:
raise e
time.sleep(10)
def destroy(self):
LOGGER.info("Nothing to be seen here.")
......
import git
import base64
import binascii
import json
import logging
import os
import subprocess
import shutil
from io import BytesIO
from subprocess import CalledProcessError
from zipfile import BadZipFile, ZipFile
from git import GitCommandError, InvalidGitRepositoryError
from omegaconf import OmegaConf
from subprocess import CalledProcessError
from src.core.engine import Factory
from src.core.persistence import Sqlite
from src.core.utils import DeploymentResponse, Credentials
from src.core.persistence import Persistence
from src.core.utils import Credentials, DeploymentResponse
LOGGER = logging.getLogger("iem")
LOGGER = logging.getLogger(__name__)
class Iem:
def __init__(self, credentials: Credentials = None):
logging.basicConfig(
level=logging.INFO, format="%(asctime)s %(levelname)-8s %(message)s"
)
self._credentials = credentials
# if credentials.aws:
# self._aws_access_key_id = credentials.aws.access_key_id
# self._aws_secret_access_key = credentials.aws.secret_access_key
# if credentials.openstack:
# self._os_username = credentials.openstack.user_name
# self._os_password = credentials.openstack.password
# self._os_auth_url = credentials.openstack.auth_url
# self._os_project_name = credentials.openstack.project_name
# Check IEM_HOME variable
if os.getenv("IEM_HOME") is None:
LOGGER.error("Please define IEM_HOME environment variable.")
exit(-1)
self._iem_home = os.getenv("IEM_HOME")
self._path_deployments = f"{os.environ['IEM_HOME']}deployments/"
self._persistence = Sqlite()
self._persistence = Persistence()
def get_all_deployments(self):
rows = self._persistence.get_all_deployments()
for r in rows:
d = DeploymentResponse(
status_time=r[0],
deployment_id=r[1],
status=r[2],
stdout=r[3],
stderr=r[4],
status_time=r.status_time,
deployment_id=r.deployment_id,
status=r.status,
stdout=r.stdout,
stderr=r.stderr,
)
yield d
......@@ -56,45 +41,47 @@ class Iem:
row = self._persistence.get_deployment(deployment_id=deployment_id)
if row:
d = DeploymentResponse(
status_time=row[0],
deployment_id=row[1],
status=row[2],
stdout=row[3],
stderr=row[4],
status_time=row.status_time,
deployment_id=row.deployment_id,
status=row.status,
stdout=row.stdout,
stderr=row.stderr,
)
yield d
def deploy(self, deployment_id: str, repository: str, commit: str):
function_name = "deploy"
LOGGER.info(f"Running {function_name} method")
self._persistence.insert_deployment(
deployment_id=deployment_id, status="STARTED", stdout=None, stderr=None
)
try:
repo_path = f"{self._iem_home}{deployment_id}"
self.get_repo(repo_path=repo_path, repository=repository, commit=commit)
LOGGER.info(f"About to deploy project {repo_path}")
def _get_env(self, deployment_id: str, credentials: Credentials) -> dict:
my_env = os.environ.copy()
if self._credentials.aws:
my_env["AWS_ACCESS_KEY_ID"] = self._credentials.aws.access_key_id
if credentials.aws:
my_env["AWS_ACCESS_KEY_ID"] = credentials.aws.access_key_id
my_env["AWS_SECRET_ACCESS_KEY"] = credentials.aws.secret_access_key
if credentials.openstack:
my_env["OS_USERNAME"] = credentials.openstack.user_name
my_env["OS_PASSWORD"] = credentials.openstack.password
my_env["OS_AUTH_URL"] = credentials.openstack.auth_url
my_env["OS_PROJECT_NAME"] = credentials.openstack.project_name
if credentials.azure:
my_env["ARM_CLIENT_ID"] = credentials.azure.arm_client_id
my_env["ARM_CLIENT_SECRET"] = credentials.azure.arm_client_secret
my_env["ARM_SUBSCRIPTION_ID"] = credentials.azure.arm_subscription_id
my_env["ARM_TENANT_ID"] = credentials.azure.arm_tenant_id
if credentials.vmware:
my_env["VSPHERE_USER"] = credentials.vmware.user_name
my_env["VSPHERE_PASSWORD"] = credentials.vmware.password
my_env["VSPHERE_SERVER"] = credentials.vmware.server
my_env[
"AWS_SECRET_ACCESS_KEY"
] = self._credentials.aws.secret_access_key
if self._credentials.openstack:
my_env["OS_USERNAME"] = self._credentials.openstack.user_name
my_env["OS_PASSWORD"] = self._credentials.openstack.password
my_env["OS_AUTH_URL"] = self._credentials.openstack.auth_url
my_env["OS_PROJECT_NAME"] = self._credentials.openstack.project_name
"VSPHERE_ALLOW_UNVERIFIED_SSL"
] = credentials.vmware.allow_unverified_ssl
project_conf = OmegaConf.load(f"{repo_path}/config.yaml")
for stage in project_conf.iac:
my_env["DEPLOYMENT_ID"] = deployment_id
return my_env
def _apply_stage(self, my_env: dict, repo_path: str, stage: str):
conf = OmegaConf.load(f"{repo_path}/{stage}/config.yaml")
self.validate(env=my_env, io=conf.input)
LOGGER.info(f"About to run stage: {stage}")
my_eng = Factory().get_engine(conf.engine)(
repo_path=f"{repo_path}/{stage}", my_env=my_env
)
......@@ -105,18 +92,51 @@ class Iem:
self.update_env(output=output, env=my_env, io=conf.output)
self.validate(env=my_env, io=conf.output)
return status, stdout, stderr
def deploy(self, deployment_id: str, bundle: str):
function_name = "deploy"
LOGGER.info(f"Running {function_name} method.")
self._persistence.insert_deployment(
deployment_id=deployment_id, status="STARTED", stdout=None, stderr=None
)
repo_path = f"{self._path_deployments}{deployment_id}"
if not os.path.exists(repo_path):
os.makedirs(repo_path)
try:
LOGGER.info(f"Decompressing base64 bundle.")
bundle_decode = base64.b64decode(bundle)
ZipFile(BytesIO(bundle_decode)).extractall(repo_path)
LOGGER.info(f"Reading credentials.")
my_env = self._get_env(
deployment_id=deployment_id, credentials=self._credentials
)
LOGGER.info(f"About to deploy project {repo_path}.")
project_conf = OmegaConf.load(f"{repo_path}/config.yaml")
for stage in project_conf.iac:
status, stdout, stderr = self._apply_stage(
my_env=my_env, repo_path=repo_path, stage=stage
)
self._persistence.insert_deployment(
deployment_id=deployment_id,
status=status,
stdout=stdout,
stderr=stderr,
)
LOGGER.info(f"Deployment completed for project {repo_path}")
except (
binascii.Error,
BadZipFile,
CalledProcessError,
GitCommandError,
FileNotFoundError,
InvalidGitRepositoryError,
NameError,
KeyError,
) as e:
LOGGER.exception(e)
self._persistence.insert_deployment(
......@@ -130,17 +150,11 @@ class Iem:
function_name = "destroy"
LOGGER.info(f"Running {function_name} method")
repo_path = f"{self._iem_home}{deployment_id}"
repo_path = f"{self._path_deployments}{deployment_id}"
my_env = os.environ.copy()
if self._credentials.aws:
my_env["AWS_ACCESS_KEY_ID"] = self._credentials.aws.access_key_id
my_env["AWS_SECRET_ACCESS_KEY"] = self._credentials.aws.secret_access_key
if self._credentials.openstack:
my_env["OS_USERNAME"] = self._credentials.openstack.user_name
my_env["OS_PASSWORD"] = self._credentials.openstack.password
my_env["OS_AUTH_URL"] = self._credentials.openstack.auth_url
my_env["OS_PROJECT_NAME"] = self._credentials.openstack.project_name
my_env = self._get_env(
deployment_id=deployment_id, credentials=self._credentials
)
LOGGER.info(f"About to destroy project {repo_path}")
project_conf = OmegaConf.load(f"{repo_path}/config.yaml")
......@@ -153,6 +167,11 @@ class Iem:
)
status, stdout, stderr = my_eng.destroy()
if "/home" in repo_path:
LOGGER.exception(f"Cannot delete {repo_path}")
elif os.getenv("DOCKERIZED") == "true":
shutil.rmtree(repo_path)
self._persistence.insert_deployment(
deployment_id=deployment_id,
status=status,
......@@ -173,21 +192,3 @@ class Iem:
if variable not in env:
LOGGER.error(f"Variable {variable} not found in environment.")
raise NameError
def get_repo(self, repo_path: str, repository: str, commit: str):
LOGGER.info(
f"About to download the project {repo_path} with repository {repository}"
)
if not os.path.isdir(repo_path):
os.makedirs(repo_path)
repo = git.Repo.clone_from(
url=repository, to_path=repo_path, no_checkout=True
)
else:
repo = git.Repo(repo_path)
repo.git.checkout(commit)
for submodule in repo.submodules:
submodule.update(init=True)
submodule.module().git.checkout()
import logging
import os
import sqlite3
# from dataclasses import dataclass
from datetime import datetime
from ratelimiter import RateLimiter
from sqlalchemy import Column, DateTime, Integer, String, create_engine, desc, select
from sqlalchemy.orm import Session, declarative_base
from sqlalchemy import create_engine
from sqlalchemy import Column
from sqlalchemy import DateTime, Integer, String
from sqlalchemy import select, desc
from sqlalchemy.orm import declarative_base, Session
LOGGER = logging.getLogger(__name__)
Base = declarative_base()
class Sqlite:
def __init__(self):
self._db_name = "iem.db"
# create database if it does not exist
if not os.path.isfile(self._db_name):
self.__create_database()
def __create_database(self):
conn = sqlite3.connect(self._db_name)
with conn:
sql = """CREATE TABLE deployments (id INTEGER PRIMARY KEY AUTOINCREMENT,
status_time DATETIME DEFAULT CURRENT_TIMESTAMP,
deployment_id TEXT NOT NULL, status TEXT NOT NULL, stdout TEXT, stderr TEXT);"""
conn.execute(sql)
def insert_deployment(
self, deployment_id: str, status: str, stdout: str, stderr: str
):
conn = sqlite3.connect(self._db_name)
with conn:
sql = """INSERT INTO deployments (deployment_id, status, stdout, stderr) VALUES (?,?,?,?)"""
cursor = conn.cursor()
cursor.execute(
sql,
(
deployment_id,
status,
stdout,
stderr,
),
)
conn.commit()
def get_deployment(self, deployment_id: str):
conn = sqlite3.connect(self._db_name)
with conn:
sql = """SELECT status_time, deployment_id, status, stdout, stderr FROM deployments
WHERE deployment_id=? ORDER BY id DESC LIMIT 1"""
cursor = conn.cursor()
cursor.execute(sql, (deployment_id,))
row = cursor.fetchone()
return row
def get_all_deployments(self):
conn = sqlite3.connect(self._db_name)
with conn:
sql = """SELECT status_time, deployment_id, status, stdout, stderr
FROM deployments ORDER BY id DESC LIMIT 25 OFFSET 0"""
cursor = conn.cursor()
cursor.execute(sql)
rows = cursor.fetchall()
return rows
@RateLimiter(max_calls=10, period=1)
def valid_api_key(self, api_key_query: str):
if api_key_query == os.getenv("API_KEY"):
return True
else:
return False
class Deployment(Base):
__tablename__ = "deployments"
......@@ -96,8 +26,8 @@ class Deployment(Base):
class Persistence:
def __init__(self):
self._engine = create_engine("sqlite:///:memory:", future=True)
def __init__(self, engine_url="sqlite:///db/iem.db"):
self._engine = create_engine(url=engine_url, future=True)
Base.metadata.create_all(self._engine)
def insert_deployment(
......
import logging
from datetime import datetime
from pydantic import BaseModel
from typing import Dict, Optional
LOGGER = logging.getLogger("iem")
from pydantic import BaseModel
class BaseResponse(BaseModel):
......@@ -42,16 +39,39 @@ class Openstack(BaseModel):
user_domain_name: Optional[str]
class Docker(BaseModel):
server: str
user_name: str
password: str
class Vmware(BaseModel):
user_name: str
password: str
server: str
allow_unverified_ssl: Optional[str]
class Credentials(BaseModel):
aws: Optional[Aws] = None
azure: Optional[Azure] = None
openstack: Optional[Openstack] = None
vmware: Optional[Vmware] = None
docker: Optional[Docker] = None
class Bundle(BaseModel):
base64: str
class DeploymentRequest(BaseModel):
deployment_id: str
repository: str
commit: str
credentials: Credentials
bundle: Bundle
class SelfHealingRequest(BaseModel):
deployment_id: str
credentials: Credentials
......
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDV3VeYPD1WKQpq2PztNUQ0IAnm4JCmCPJpCLcem9kO3DvNbVBN5Q0JF0nfqgc8b1wP7uBH1b3G8jaX7Zsq6CpNu4OvXKw/EBxO3pdiAx6v0mRZMLBx2qcBd1TB90sxQ+juY6//06c52OgSjQ3Cey8a8/GKdtTMxRKh+rAuAch2WjcZBmTZPe+9E3fOhibHg5UA3sLhFcAPuEuEQRbTDBSsCqdCqHXfIe4NiLqJYVLOHkHuHfvTRaLROh7zmf20FmIP7s1gYU3GpDKRgZeuo2ZM9791N98B0JgSnepbx2/MDuG2WvAFwHIK7WSNVxGuxdvXspUWfDGam/G4ZGuxzaxVHtwYgSyxNoAUXcv82GS/MNLXqpfapvPR/LGcWAEcg1FgzjkC8y4MBZ6tQDowAYr/BEnUI7xmtIm0ixBWdd2zGtyMoSbvqHN0DSsRM+YDkD4XMcfd9Kp9kiIWHl1N9RSeV3D1JNfDGNGAE1qym25Ni0zWNbSyEUxpLkXj4T2wEDM=
import base64
import logging
import os
import unittest
import uuid
from src.core.iem import Iem
from src.core.utils import Aws, Credentials, Openstack
LOGGER = logging.getLogger(__name__)
class TestIem(unittest.TestCase):
def __init__(self, *args, **kwargs):
super(TestIem, self).__init__(*args, **kwargs)
# Check IEM_HOME variable
self._iem_home = os.environ["IEM_HOME"]
@unittest.skipUnless(os.getenv("AWS"), "Define AWS variable to execute")
def test_deploy_destroy_aws(self):
deployment_id = str(uuid.uuid4())
a = Iem(
Credentials(
aws=Aws(
access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"],
)
)
)
with open("tests/resources/aws.zip", "rb") as binary_file:
bundle = base64.b64encode(binary_file.read())
a.deploy(deployment_id=deployment_id, bundle=bundle)
a.destroy(deployment_id=deployment_id)
@unittest.skipUnless(
os.getenv("INTEGRATION"), "Define INTEGRATION variable to execute"
)
def test_deploy_destroy_openstack(self):
deployment_id = str(uuid.uuid4())
a = Iem(
Credentials(
openstack=Openstack(
user_name=os.environ["OS_USERNAME"],
password=os.environ["OS_PASSWORD"],
auth_url=os.environ["OS_AUTH_URL"],
project_name=os.environ["OS_PROJECT_NAME"],
)
)
)
with open("tests/resources/openstack.zip", "rb") as binary_file:
bundle = base64.b64encode(binary_file.read())
a.deploy(deployment_id=deployment_id, bundle=bundle)
a.destroy(deployment_id=deployment_id)
@unittest.skipUnless(
os.getenv("INTEGRATION"), "Define INTEGRATION variable to execute"
)
def test_deploy_destroy_docker(self):
deployment_id = str(uuid.uuid4())
a = Iem(
Credentials(
openstack=Openstack(
user_name=os.environ["OS_USERNAME"],
password=os.environ["OS_PASSWORD"],
auth_url=os.environ["OS_AUTH_URL"],
project_name=os.environ["OS_PROJECT_NAME"],
)
)
)
with open("tests/resources/docker.zip", "rb") as binary_file:
bundle = base64.b64encode(binary_file.read())
a.deploy(deployment_id=deployment_id, bundle=bundle)
a.destroy(deployment_id=deployment_id)
File added
File added
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment