Tmp
import os
import uvicorn
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse, JSONResponse

# 1. Gather Domino environment variables
DOMINO_RUN_ID = os.environ.get("DOMINO_RUN_ID")
DOMINO_PROJECT_OWNER = os.environ.get("DOMINO_PROJECT_OWNER")
DOMINO_PROJECT_NAME = os.environ.get("DOMINO_PROJECT_NAME")
PORT = 8888  

# 2. Build the proxy prefix required by Domino's Jupyter Server Proxy
PROXY_PATH = f"/{DOMINO_PROJECT_OWNER}/{DOMINO_PROJECT_NAME}/notebookSession/{DOMINO_RUN_ID}/proxy/{PORT}"

# 3. Initialize FastAPI with root_path so documentation and routes auto-align
app = FastAPI(root_path=PROXY_PATH)

# --- Connection Manager for Chat ---
class ConnectionManager:
    def __init__(self):
        self.active_connections: list[WebSocket] = []

    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.append(websocket)

    def disconnect(self, websocket: WebSocket):
        self.active_connections.remove(websocket)

    async def broadcast(self, message: str):
        for connection in self.active_connections:
            await connection.send_text(message)

manager = ConnectionManager()

# --- Frontend HTML UI ---
HTML_TEMPLATE = """
<!DOCTYPE html>
<html>
    <head>
        <title>Domino WebSocket Chat</title>
        <style>
            body { font-family: sans-serif; margin: 20px; }
            #messages { border: 1px solid #ccc; height: 200px; overflow-y: scroll; padding: 10px; margin-bottom: 10px; }
        </style>
    </head>
    <body>
        <h2>Domino Workspace Chat</h2>
        <div id="messages"></div>
        <input type="text" id="messageText" autocomplete="off" placeholder="Type a message..."/>
        <button onclick="sendMessage()">Send</button>

        <script>
            const loc = window.location;
            const wsProtocol = loc.protocol === "https:" ? "wss:" : "ws:";

            // Because we use root_path, the browser URL already contains the PROXY_PATH.
            // We just append /ws to the current window location path.
            const wsUrl = `${wsProtocol}//${loc.host}${loc.pathname.replace(/\/$/, '')}/ws`;

            const ws = new WebSocket(wsUrl);

            ws.onmessage = function(event) {
                const messages = document.getElementById('messages');
                const message = document.createElement('div');
                message.textContent = event.data;
                messages.appendChild(message);
                messages.scrollTop = messages.scrollHeight;
            };

            function sendMessage() {
                const input = document.getElementById("messageText");
                if (input.value.trim() !== "") {
                    ws.send(input.value);
                    input.value = '';
                }
            }
        </script>
    </body>
</html>
"""

# NEW: Root endpoint (Accessible internally via http://localhost:8888/)
@app.get("/")
async def read_root():
    return JSONResponse(content={"message": "hello"})

# Chat UI Endpoint (Accessible via the Domino Proxy URL)
# Note: Since root_path is set to PROXY_PATH, mapping this to "/" 
# means it serves the UI at the end of the proxy string.
@app.get("/")
async def get_ui():
    return HTMLResponse(HTML_TEMPLATE)

# WebSocket Endpoint 
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await manager.connect(websocket)
    try:
        while True:
            data = await websocket.receive_text()
            await manager.broadcast(f"User: {data}")
    except WebSocketDisconnect:
        manager.disconnect(websocket)
        await manager.broadcast("A user left the chat")

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=PORT)

## 2. How to Launch It
Open a terminal inside your active Jupyter or VS Code workspace session in Domino and run:

pip install fastapi uvicorn
python app.py

## 3. How to Access the App
Once Uvicorn starts, do not click standard localhost links. Instead, construct your access URL using your browser's current address bar as a guide.
Replace everything after your Domino domain with your project details and port 8888:
https://<your-domino-domain>/<project-owner>/<project-name>/notebookSession/<your-run-id>/proxy/8888/
(Note: The trailing slash at the end of the URL is mandatory for FastAPI routing to match correctly).
Would you like to know how to bundle this script into a Domino App so users can launch it with a single click without opening a workspace?

[[/code]]

Show me the curl requests to request ssl certificates to an hashicorp vault pki, and then configure an openshift route with them using reencrypt

GPT-5 mini:
Below are concise curl examples showing (A) requesting an X.509 certificate from a HashiCorp Vault PKI role and (B) retrieving the issued cert, private key, and CA chain, and (C) creating an OpenShift Route in reencrypt termination mode using those artifacts. Assumptions made (reasonable defaults):

- Vault address: https://vault.example.com
- Vault token: VAULT_TOKEN (replace)
- PKI mount path: pki (so endpoints under /v1/pki)
- PKI role name: my-role
- Certificate common name: app.example.com
- OpenShift API server: https://openshift.example.com:6443
- OpenShift token: OC_TOKEN (replace)
- OpenShift project/namespace: myproject
- Route name: my-route
- You have jq and base64 available locally for minor processing.

1) Request certificate from Vault (generate private key + CSR server-side using role)
- This requests a certificate for CN=app.example.com valid 90 days:
curl -sSK -H "X-Vault-Token: $VAULT_TOKEN" -X POST https://vault.example.com/v1/pki/issue/my-role -d '{ "common_name": "app.example.com", "ttl": "2160h" }' | jq .

Response fields of interest in JSON: data.certificate, data.issuing_ca (or data.ca_chain[]), data.private_key

2) Extract certificate, private key, and CA chain to files (pipe from prior command)
curl -sSK -H "X-Vault-Token: $VAULT_TOKEN" -X POST https://vault.example.com/v1/pki/issue/my-role -d '{ "common_name": "app.example.com", "ttl": "2160h" }' | jq -r '.data.certificate' > cert.pem

curl -sSK -H "X-Vault-Token: $VAULT_TOKEN" -X POST https://vault.example.com/v1/pki/issue/my-role -d '{ "common_name": "app.example.com", "ttl": "2160h" }' | jq -r '.data.private_key' > key.pem

  1. If CA chain is returned as array, prefer ca_chain[0] or issuing_ca

curl -sSK -H "X-Vault-Token: $VAULT_TOKEN" -X POST https://vault.example.com/v1/pki/issue/my-role -d '{ "common_name": "app.example.com", "ttl": "2160h" }' | jq -r '.data.ca_chain[0] // .data.issuing_ca' > ca.pem

(Option: do the Vault request once and split outputs; above shows separate calls for clarity. To do it once:)
resp=$(curl -sSK -H "X-Vault-Token: $VAULT_TOKEN" -X POST https://vault.example.com/v1/pki/issue/my-role -d '{"common_name":"app.example.com","ttl":"2160h"}')
echo "$resp" | jq -r '.data.certificate' > cert.pem
echo "$resp" | jq -r '.data.private_key' > key.pem
echo "$resp" | jq -r '.data.ca_chain[0] // .data.issuing_ca' > ca.pem

3) Create an OpenShift TLS secret containing cert+key+ca
OpenShift requires a TLS secret with tls.crt (certificate + chain) and tls.key (private key). Combine cert + CA chain into tls.crt:

cat cert.pem ca.pem > tls.crt
cat key.pem > tls.key

Encode and create via oc (preferred) or curl to the API. Using curl to Kubernetes API:

  1. base64-encode

CRT_B64=$(base64 -w0 < tls.crt)
KEY_B64=$(base64 -w0 < tls.key)

  1. Secret manifest (JSON)

read -r -d '' SECRET_JSON «EOF
{
"apiVersion": "v1",
"kind": "Secret",
"metadata": { "name": "my-route-tls", "namespace": "myproject" },
"type": "kubernetes.io/tls",
"data": {
"tls.crt": "$CRT_B64",
"tls.key": "$KEY_B64"
}
}
EOF

curl -sSK -H "Authorization: Bearer $OC_TOKEN" -H "Content-Type: application/json" -X POST https://openshift.example.com:6443/api/v1/namespaces/myproject/secrets -d "$SECRET_JSON" | jq .

(If secret exists, use PUT to replace: …/secrets/my-route-tls)

4) Create OpenShift Route with reencrypt termination pointing to that secret
The Route must reference the secret name in tls.secretName and use termination: Reencrypt. Example manifest (use API route.openshift.io/v1):

read -r -d '' ROUTE_JSON «EOF
{
"apiVersion": "route.openshift.io/v1",
"kind": "Route",
"metadata": { "name": "my-route", "namespace": "myproject" },
"spec": {
"host": "app.example.com",
"to": { "kind": "Service", "name": "my-backend-svc", "weight": 100 },
"port": { "targetPort": "https" },
"tls": {
"termination": "reencrypt",
"insecureEdgeTerminationPolicy": "Redirect",
"certificate": "$(awk 'BEGIN{RS=\"\"} {print}' tls.crt | sed 's/$/\\n/' | sed -e ':a;N;$!ba;s/\"/\\\\"/g')",
"key": "$(awk 'BEGIN{RS=\"\"} {print}' tls.key | sed 's/$/\\n/' | sed -e ':a;N;$!ba;s/\"/\\\\"/g')",
"caCertificate": "$(awk 'BEGIN{RS=\"\"} {print}' ca.pem | sed 's/$/\\n/' | sed -e ':a;N;$!ba;s/\"/\\\\"/g')",
"destinationCACertificate": "$(awk 'BEGIN{RS=\"\"} {print}' ca.pem | sed 's/$/\\n/' | sed -e ':a;N;$!ba;s/\"/\\\\"/g')"
}
}
}
EOF

curl -sSK -H "Authorization: Bearer $OC_TOKEN" -H "Content-Type: application/json" -X POST https://openshift.example.com:6443/apis/route.openshift.io/v1/namespaces/myproject/routes -d "$ROUTE_JSON" | jq .

Notes on fields:
- termination: "reencrypt" tells the router to use TLS to the backend.
- certificate/key/caCertificate in the Route tls block populate edge cert presented to clients by the router (optional if you want router to present your cert).
- destinationCACertificate (or service CA) is used by the router to validate the backend service certificate. Provide the CA that issued the backend cert.
- If you instead stored the secret and want the router to use the secret automatically, OpenShift routers typically use tls.secretName on the route (older behavior); if your cluster supports that, set "tls": {"termination":"reencrypt","certificate":…, …} as above or reference the secret depending on platform/version.

Alternative simpler flow (common):
- Create TLS secret as step 3.
- Create route that references the secret name (some OpenShift versions support tls.secretName):
read -r -d '' ROUTE_JSON2 «EOF
{
"apiVersion": "route.openshift.io/v1",
"kind": "Route",
"metadata": { "name": "my-route", "namespace": "myproject" },
"spec": {
"host": "app.example.com",
"to": { "kind": "Service", "name": "my-backend-svc" },
"tls": {
"termination": "reencrypt",
"insecureEdgeTerminationPolicy": "Redirect",
"certificate": "",
"key": "",
"caCertificate": "",
"destinationCACertificate": ""
}
}
}
EOF

  1. If your OpenShift supports referencing the secret by name, set tls.secretName: "my-route-tls" in spec.tls.

Practical tips:
- Ensure backend service serves HTTPS and its cert is signed by the CA you provided as destinationCACertificate.
- Use oc create secret tls and oc create route if you have oc client (much simpler).
- Replace tokens/hosts/paths with real values and secure tokens.

If you want, I can produce a ready-to-run script that performs the full flow (one Vault request, creates secret, creates route) for your exact Vault/OpenShift endpoints and role—provide the values and whether you prefer oc vs curl.