package jenkins import ( "bytes" "encoding/json" "fmt" "io" "net/http" "time" "freeleaps.com/gitea-webhook-ambassador/internal/logger" ) // Client represents a Jenkins API client type Client struct { url string username string token string client *http.Client } // Config represents Jenkins client configuration type Config struct { URL string Username string Token string Timeout time.Duration } // JobParameters represents parameters to pass to a Jenkins job type JobParameters map[string]string // New creates a new Jenkins client func New(config Config) *Client { return &Client{ url: config.URL, username: config.Username, token: config.Token, client: &http.Client{ Timeout: config.Timeout, }, } } // TriggerJob triggers a Jenkins job with the given parameters func (c *Client) TriggerJob(jobName string, parameters map[string]string) error { // Build request URL url := fmt.Sprintf("%s/job/%s/buildWithParameters", c.url, jobName) // Create request body body, err := json.Marshal(parameters) if err != nil { return fmt.Errorf("failed to marshal parameters: %v", err) } // Create request req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(body)) if err != nil { return fmt.Errorf("failed to create request: %v", err) } // Set headers req.Header.Set("Content-Type", "application/json") req.SetBasicAuth(c.username, c.token) // Send request resp, err := c.client.Do(req) if err != nil { return fmt.Errorf("failed to send request: %v", err) } defer resp.Body.Close() // Check response status if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { body, _ := io.ReadAll(resp.Body) return fmt.Errorf("unexpected status code: %d, body: %s", resp.StatusCode, string(body)) } return nil } // IsConnected checks if Jenkins is accessible func (c *Client) IsConnected() bool { // Try to access Jenkins API url := fmt.Sprintf("%s/api/json", c.url) req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { logger.Error("Failed to create Jenkins request: %v", err) return false } req.SetBasicAuth(c.username, c.token) resp, err := c.client.Do(req) if err != nil { logger.Error("Failed to connect to Jenkins: %v", err) return false } defer resp.Body.Close() return resp.StatusCode == http.StatusOK }