def resolve_rename_container(*_, id, name): try: docker_client.api.rename(id, name=name) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_tag_image(*_, id, repository, tag=None): try: docker_client.images.get(id).tag(repository, tag) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_form_create_container(*_, input): try: resolve_create_container(**input) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_remove_network(*_, id): try: docker_client.api.remove_network(id) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_remove_volume(*_, name, force): try: docker_client.api.remove_volume(name, force=force) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_create_network(*_, input): name = input.get("name") labels = kv_to_dict(input.get("labels")) internal = input.get("internal") pool_configs = [] ipams = input.get("ipams", []) ipam = None if ipams: pool_configs = [] for entry in ipams: pool_configs.append( IPAMPool( entry.get("subnet", None), entry.get("ipRange", None), entry.get("gateway", None), )) ipam = IPAMConfig(pool_configs) try: docker_client.networks.create( name, check_duplicate=True, labels=labels, driver="bridge", internal=internal, ipam=ipam, ) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_remove_image(*_, id, force, pruneParents): try: docker_client.api.remove_image(id, force=force, noprune=not pruneParents) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_remove_container(*_, id, force, pruneVolumes): try: docker_client.api.remove_container(id, v=pruneVolumes, force=force) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def basic_docker_operation(name, id): op = getattr(docker_client.api, name) try: op(id) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def mutation_delete_network(*_, id): try: network = docker_client.networks.get(id) network.remove() except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_create_volume(*_, input): try: docker_client.volumes.create(input.get("name"), labels=dict(input["labels"])) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
async def resolve_initialize_auth(*_, password, otp): if not db.is_first_run: raise PMException("PwnMachine is already setup.") if not db.verify_otp(otp): raise PMException("Invalid OTP.") return await db.register(password)
async def mutation_pull_image(*_, name): name = name if ":" in name else f"{name}:latest" try: stream = docker_client.api.pull(name, stream=True, decode=True) return StreamFollower.create(stream, {"name": name, "type": "PULL"}) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_tag_image(*_, id, tag, force): raise NotImplementedError() # need fix try: docker_client.api.tag(id, **tag, force=force) return docker_client.images.get(id) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_connect_container(*_, input): network = docker_client.networks.get(input["networkId"]) container = docker_client.containers.get(input["containerId"]) aliases = input.get("aliases") or [] try: network.connect(container, aliases=aliases) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def resolve_disconnect_container(*_, input): try: docker_client.api.disconnect_container_from_network( input["containerId"], input["networkId"], ) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
def build_docker_image(*_, input): url = input["url"] tag = input["tag"] try: stream = docker_client.api.build(url, tag, decode=True, rm=True, forcerm=True) return StreamFollower.create(stream, {"name": tag, "type": "BUILD"}) except APIError as e: raise PMException(e.explanation) except Exception as e: raise PMException(str(e))
async def create_udp_weighted(*_, input): try: await traefik_redis().create_service( input["name"], "udp", "weighted", input["weighted"] ) except Exception as e: raise PMException(str(e))
async def update_dns_zone_mutation(*_, nodeId, patch): ttl = patch["ttl"] records = patch["records"] try: await dns_http().update_rule(nodeId, ttl, records) except Exception as e: raise PMException(str(e))
async def create_http_mirroring(*_, input): try: await traefik_redis().create_service( input["name"], "http", "mirroring", input["mirroring"] ) except Exception as e: raise PMException(str(e))
async def create_udp_loadbalancer(*_, input): try: await traefik_redis().create_service( input["name"], "udp", "loadBalancer", input["loadBalancer"] ) except Exception as e: raise PMException(str(e))
async def resolve_create_mutation(*_, input): middleware_name = input["name"] try: await traefik_redis().create_middleware(middleware_name, type_name, input[type_name]) except Exception as e: raise PMException(str(e))
async def delete_service(self, nodeId): protocol, name = validate_node_id(nodeId, "TRAEFIK_SERVICE") service = await self.http_api.get_service(protocol, name) if service["provider"] != "redis": raise PMException("You can't delete this service") redis_name = name.split("@")[0] if "@" in name else name await self.delete_pattern(f"{self.root}/{protocol}/services/{redis_name}/*") await asyncio.sleep(1)
async def delete_middleware(self, nodeId): (name,) = validate_node_id(nodeId, "TRAEFIK_MW") middleware = await self.http_api.get_middleware(name) if middleware["provider"] != "redis": raise PMException("You can't delete this middleware") redis_name = name.split("@")[0] if "@" in name else name await self.delete_pattern(f"{self.root}/http/middlewares/{redis_name}/*") await asyncio.sleep(1)
def resolve_create_token(*_, input): # always do both operation to avoid timming attack password_ok = db.verify_password(input["password"]) otp_ok = db.verify_otp(input["otp"]) if password_ok and otp_ok: return db.make_jwt_token(input.get("durationDays", 1)) raise PMException("Invalid credentials.")
async def delete_router(self, nodeId): protocol, name = validate_node_id(nodeId, "TRAEFIK_ROUTER") router = await self.http_api.get_router(protocol, name) if router["provider"] != "redis": raise PMException("You can't delete this router") redis_name = name.split("@")[0] await self.delete_pattern(f"{self.root}/{protocol}/routers/{redis_name}/*") await asyncio.sleep(1)
async def create_dns_rule_mutation(*_, input): records = input["records"] zone = input["zone"] name = input["name"] ttl = input["ttl"] type = input["type"] if len(records) < 1: raise PMException("At least one record required") if input["isLua"]: record = input["records"][0] escaped_content = escape_lua(record["content"]) formated = f'{type} "{escaped_content}"' records = [{"content": formated, "enabled": record["enabled"]}] type = "LUA" try: await dns_http().create_rule(zone, name, type, ttl, records) except Exception as e: raise PMException(str(e))
async def update_middleware(self, nodeId, type_name, patch): (name, ) = validate_node_id(nodeId, "TRAEFIK_MW") middleware = await self.http_api.get_middleware(name) if middleware["provider"] != "redis": raise PMException("You can't edit this middleware") prefix = f"{self.root}/http/middlewares/{middleware['name'].split('@')[0]}/{type_name}" for key, option in patch.items(): await self.delete_pattern(f"{prefix}/{key}/*") await self.create_from_object({key: option}, prefix) await asyncio.sleep(1)
async def update_router(self, nodeId, patch): protocol, name = validate_node_id(nodeId, "TRAEFIK_ROUTER") router = await self.http_api.get_router(protocol, name) if router["provider"] != "redis": raise PMException("You can't edit this router") prefix = ( f"{self.root}/{router['protocol']}/routers/{router['name'].split('@')[0]}" ) for key, option in patch.items(): await self.delete_pattern(f"{prefix}/{key}/*") await self.create_from_object({key: option}, prefix) await asyncio.sleep(1)
def resolve_delete_file(*_, input): volume = docker_client.volumes.get(input.get("volumeName")) asked_path = input.get("path", "/") root_path = volume.attrs["Mountpoint"] full_path = safe_path(root_path, asked_path, follow_link=False) try: if os.path.islink(full_path): os.unlink(full_path) elif os.path.isdir(full_path): shutil.rmtree(full_path) else: os.remove(full_path) except Exception as e: raise PMException(e)