Skip to content

Commit

Permalink
major: remove AWS lightsail since there are lots of service quota issues
Browse files Browse the repository at this point in the history
feat: add hetzner as lightsail replacement for chisel nodes
feat: enable chisel nodes to show up in swagger
feat: use secrets library in python instead of random to generate chisel auth token
  • Loading branch information
venkatamutyala committed Jan 5, 2025
1 parent bec0948 commit ea22eaf
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 175 deletions.
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ fastapi = {extras = ["standard"], version = "*"}
glueops-helpers = {file = "https://github.com/GlueOps/python-glueops-helpers-library/archive/refs/tags/v0.6.0.zip"}
minio = "*"
boto3 = "*"
hcloud = "*"

[dev-packages]

Expand Down
11 changes: 10 additions & 1 deletion Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from pydantic import BaseModel, Field
from contextlib import asynccontextmanager
import os, glueops.setup_logging, traceback, base64, yaml, tempfile, json
from schemas.schemas import Message, CreateLightsailRequest, AwsCredentialsRequest, DeleteLightsailRequest, StorageBucketsRequest, AwsNukeAccountRequest, CaptainDomainNukeDataAndBackupsRequest
from util import storage, aws_lightsail, aws_setup_test_account_credentials, github
from schemas.schemas import Message, AwsCredentialsRequest, StorageBucketsRequest, AwsNukeAccountRequest, CaptainDomainNukeDataAndBackupsRequest, ChiselNodesRequest
from util import storage, aws_setup_test_account_credentials, github, hetzner
from fastapi.responses import RedirectResponse


Expand Down Expand Up @@ -78,23 +78,23 @@ async def nuke_captain_domain_data(request: CaptainDomainNukeDataAndBackupsReque
"""
return github.nuke_captain_domain_data_and_backups(request.captain_domain)

@app.post("/v1/chisel", response_class=PlainTextResponse, include_in_schema=False)
async def create_chisel_nodes(request: CreateLightsailRequest):
@app.post("/v1/chisel", response_class=PlainTextResponse)
async def create_chisel_nodes(request: ChiselNodesRequest):
"""
If you are testing within k3ds you will need chisel to provide you with load balancers.
For a provided captain_domain this will delete any existing chisel nodes and provision new ones.
Note: this will generally result in new IPs being provisioned.
"""
return aws_lightsail.create_lightsail_instances(request)
return hetzner.create_instances(request)


@app.delete("/v1/chisel", include_in_schema=False)
async def delete_chisel_nodes(request: DeleteLightsailRequest):
@app.delete("/v1/chisel")
async def delete_chisel_nodes(request: ChiselNodesRequest):
"""
When you are done testing with k3ds this will delete your chisel nodes and save on costs.
"""
response = aws_lightsail.create_lightsail_instances(request)
return JSONResponse(status_code=200, content={"message": response})
response = hetzner.delete_existing_servers(request)
return JSONResponse(status_code=200, content={"message": "Successfully deleted chisel nodes."})


@app.get("/health", include_in_schema=False)
Expand Down
8 changes: 1 addition & 7 deletions app/schemas/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,8 @@
class Message(BaseModel):
message: str = Field(...,example = 'Success')


class CreateLightsailRequest(BaseModel):
captain_domain: str = Field(...,example = 'glueops-captain-foobar')
region: str = Field(...,example = 'us-west-2')

class DeleteLightsailRequest(BaseModel):
class ChiselNodesRequest(BaseModel):
captain_domain: str = Field(...,example = 'nonprod.foobar.onglueops.rocks')
region: str = Field(...,example = 'us-west-2')

class StorageBucketsRequest(BaseModel):
captain_domain: str = Field(...,example = 'nonprod.foobar.onglueops.rocks')
Expand Down
Empty file added app/util/__init__.py
Empty file.
158 changes: 0 additions & 158 deletions app/util/aws_lightsail.py

This file was deleted.

47 changes: 47 additions & 0 deletions app/util/chisel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import secrets
import string

def generate_credentials():
character_pool = string.ascii_letters + string.digits
return (
"".join(secrets.choice(character_pool) for _ in range(15)) # Generate 15 secure characters
+ ":"
+ "".join(secrets.choice(character_pool) for _ in range(15)) # Generate another 15 secure characters
)

def get_suffixes():
return ["exit1", "exit2"]


def create_chisel_yaml(captain_domain, credentials_for_chisel, ip_addresses, suffixes):
manifest = f"""
kubectl apply -k https://github.com/FyraLabs/chisel-operator?ref=v0.4.1
kubectl apply -f - <<YAML
apiVersion: v1
kind: Secret
metadata:
name: selfhosted
namespace: chisel-operator-system
type: Opaque
stringData:
auth: "{credentials_for_chisel}"
---
"""
for suffix in suffixes:
manifest += f"""
apiVersion: chisel-operator.io/v1
kind: ExitNode
metadata:
name: {suffix}
namespace: chisel-operator-system
spec:
host: "{ip_addresses[f'{captain_domain}-{suffix}']}"
port: 9090
auth: selfhosted
---
"""

return manifest


91 changes: 91 additions & 0 deletions app/util/hetzner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import os
from fastapi import FastAPI, Security, HTTPException, Depends, status, requests, Request
import time
import util.chisel
from hcloud import Client
from hcloud.images import Image
from hcloud.server_types import ServerType
from hcloud.images.domain import Image
from hcloud.locations.domain import Location
from hcloud.servers.domain import ServerCreatePublicNetwork


client = Client(token=os.getenv("HCLOUD_TOKEN"))

def multiline_to_singleline(input_text: str) -> str:
"""
Converts a multi-line string to a single-line string with `\\n` replacing newlines.
Args:
input_text (str): The multi-line input string.
Returns:
str: Single-line string with `\\n` replacing newlines.
"""
return input_text.replace("\n", "\\n")


def create_instances(request):
captain_domain = request.captain_domain.strip()
credentials_for_chisel = util.chisel.generate_credentials()

# Define user data
user_data_readable = f"""
#cloud-config
package_update: true
runcmd:
- curl -fsSL https://get.docker.com -o get-docker.sh && sudo sh get-docker.sh && sudo apt install tmux -y
- sudo docker run -d --restart always -p 9090:9090 -p 443:443 -p 80:80 -it jpillora/chisel:v1.10.1 server --reverse --port=9090 --auth='{credentials_for_chisel}'
"""

user_data = multiline_to_singleline(user_data_readable)

suffixes = util.chisel.get_suffixes()

instance_names = [f"{captain_domain}-{suffix}" for suffix in suffixes]
ip_addresses = {}

try:
delete_existing_servers(request)

for instance_name in instance_names:
ip_addresses[instance_name] = create_server(instance_name, captain_domain, user_data)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error creating instances: {str(e)}")

return util.chisel.create_chisel_yaml(captain_domain, credentials_for_chisel, ip_addresses, suffixes)


def create_server(server_name, captain_domain, user_data_one_line_format):
server_type = ServerType(name="cx22")
image = Image(name="debian-12")
ssh_keys = client.ssh_keys.get_all(name="glueops-default-ssh-key")
location = Location(name="hel1")
server_response = client.servers.create(
server_name,
server_type=server_type,
image=image,
ssh_keys=ssh_keys,
location=location,
user_data=user_data_one_line_format,
labels={"captain_domain": captain_domain},
public_net=ServerCreatePublicNetwork(
enable_ipv4=True,
enable_ipv6=False
)
)

server = server_response.server
#server_response.action.wait_until_finished()
return(server.public_net.ipv4.ip)


def delete_existing_servers(request):
captain_domain = request.captain_domain.strip()
servers = client.servers.get_all(label_selector="captain_domain")
for server in servers:
if server.labels["captain_domain"] == captain_domain:
server.delete()
return True


0 comments on commit ea22eaf

Please sign in to comment.