From 1f97713a914a0cf32ad0ebf1aec55a45e602f834 Mon Sep 17 00:00:00 2001 From: qiaofeng1227 <76487013@qq.com> Date: Mon, 11 Sep 2023 16:51:48 +0800 Subject: [PATCH] portainer --- docker/w9portainer/Dockerfile | 11 ++- docker/w9portainer/docker-compose.yml | 7 +- docker/w9portainer/init_endpoint.go | 130 ++++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 docker/w9portainer/init_endpoint.go diff --git a/docker/w9portainer/Dockerfile b/docker/w9portainer/Dockerfile index 4730c7cd..0069701c 100644 --- a/docker/w9portainer/Dockerfile +++ b/docker/w9portainer/Dockerfile @@ -1,10 +1,13 @@ # step1: build entrypoint execute program init_portainer by golang FROM golang:latest AS builder WORKDIR / -COPY init_portainer.go /init_portainer.go -RUN go build -o init_portainer init_portainer.go -RUN chmod +x ./init_portainer +COPY init_portainer.go / +COPY init_endpoint.go / +RUN go build -o init_portainer /init_portainer.go +RUN go build -o init_endpoint /init_endpoint.go +RUN chmod +x /init_portainer /init_endpoint # step2: copy build go program to portainer FROM portainer/portainer-ce:2.19.0 -COPY --from=builder /init_portainer / \ No newline at end of file +COPY --from=builder /init_portainer / +COPY --from=builder /init_endpoint / \ No newline at end of file diff --git a/docker/w9portainer/docker-compose.yml b/docker/w9portainer/docker-compose.yml index 3be63e2b..15a78abc 100644 --- a/docker/w9portainer/docker-compose.yml +++ b/docker/w9portainer/docker-compose.yml @@ -10,7 +10,12 @@ services: context: . dockerfile: Dockerfile entrypoint: ["/init_portainer"] - restart: unless-stopped + restart: unless-stopped + healthcheck: + test: ["CMD", "/init_endpoint"] + interval: 5s + timeout: 5s + retries: 3 volumes: - portainer:/data - /var/run/docker.sock:/var/run/docker.sock diff --git a/docker/w9portainer/init_endpoint.go b/docker/w9portainer/init_endpoint.go new file mode 100644 index 00000000..d096c2ef --- /dev/null +++ b/docker/w9portainer/init_endpoint.go @@ -0,0 +1,130 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + +type AuthResponse struct { + JWT string `json:"jwt"` +} + +type EndpointResponse struct { + // ... +} + +func main() { + // Read the /portainer_password file + password, err := ioutil.ReadFile("/portainer_password") + if err != nil { + fmt.Println("Failed to read password file:", err) + return + } + + // Trim whitespace and newlines from the password + password = []byte(strings.TrimSpace(string(password))) + + // Build the request body for the /auth API + authRequestBody := fmt.Sprintf(`{"password": "%s", "username": "admin"}`, password) + + // Perform authentication by calling the /auth API + authURL := "http://localhost:9000/api/auth" + resp, err := http.Post(authURL, "application/json", strings.NewReader(authRequestBody)) + if err != nil { + fmt.Println("Failed to perform authentication:", err) + return + } + defer resp.Body.Close() + + // Check the authentication response + if resp.StatusCode != http.StatusOK { + fmt.Println("Authentication failed:", resp.Status) + return + } + + fmt.Println("Authentication successful!") + + // Read the authentication response + authResponse, err := ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Println("Failed to read authentication response:", err) + return + } + + // Parse the authentication response JSON + var authResponseJSON AuthResponse + if err := json.Unmarshal(authResponse, &authResponseJSON); err != nil { + fmt.Println("Failed to parse authentication response:", err) + return + } + + // Extract the access token from the authentication response + accessToken := authResponseJSON.JWT + + // Call the /endpoints API with GET method to check if data exists + endpointsURL := "http://localhost:9000/api/endpoints" + req, err := http.NewRequest("GET", endpointsURL, nil) + if err != nil { + fmt.Println("Failed to create request:", err) + return + } + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken)) + + client := &http.Client{} + resp, err = client.Do(req) + if err != nil { + fmt.Println("Failed to check endpoint data:", err) + return + } + defer resp.Body.Close() + + // Read the endpoint data response + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Println("Failed to read endpoint data response:", err) + return + } + + // Check if data exists + if len(body) > 0 { + // Data exists, perform further operations or return + fmt.Println("Data exists:", string(body)) + return + } + + // Data does not exist, call the /endpoints API to get the endpoint information + fmt.Println("Data is notexists, need to create endpoint") + req, err = http.NewRequest("POST", endpointsURL, nil) + if err != nil { + fmt.Println("Failed to create request:", err) + return + } + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken)) + + // Add form data parameters + data := url.Values{} + data.Set("Name", "local") + data.Set("EndpointCreationType", "1") + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Body = ioutil.NopCloser(strings.NewReader(data.Encode())) + + resp, err = client.Do(req) + if err != nil { + fmt.Println("Failed to get endpoint information:", err) + return + } + defer resp.Body.Close() + + // Read the endpoint information response + body, err = ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Println("Failed to read endpoint information response:", err) + return + } + + fmt.Println("Endpoint information:", string(body)) +} \ No newline at end of file