package main import ( "bytes" "encoding/base64" "encoding/json" "flag" "fmt" "io" "log" "net/http" "net/url" "os" "runtime" "time" ) type Incident struct { AppID string `json:"app_id"` Resource string `json:"resource"` Node string `json:"node"` ShortDescription string `json:"short_description"` MetricName string `json:"metric_name"` MessageKey string `json:"message_key"` MetricValue string `json:"metric_value"` Source string `json:"source"` Description string `json:"description"` EventClass string `json:"event_class"` Severity int `json:"severity"` Type string `json:"type"` AssignmentGroup string `json:"assignment_group"` Environment string `json:"environment"` } // ValidAuthMethods defines the allowed authentication methods. //var ValidAuthMethods = []string{"no-auth", "basic", "ntlm"} var ( sha1ver string // sha1 revision used to build the program buildTime string // when the executable was built ) /* // ValidateAuthMethod checks if the provided auth method is valid. func ValidateAuthMethod(authMethod string) error { for _, validMethod := range ValidAuthMethods { if authMethod == validMethod { return nil } } return errors.New("invalid authentication method: " + authMethod) } */ func prettyPrint(args ...interface{}) { var caller string timeNow := time.Now().Format("01-02-2006 15:04:05") prefix := fmt.Sprintf("[%s] %s -- ", "PrettyPrint", timeNow) _, fileName, fileLine, ok := runtime.Caller(1) if ok { caller = fmt.Sprintf("%s:%d", fileName, fileLine) } else { caller = "" } log.Printf("\n%s%s\n", prefix, caller) if len(args) == 2 { label := args[0] value := args[1] s, _ := json.MarshalIndent(value, "", "\t") fmt.Printf("%s%s: %s\n", prefix, label, string(s)) } else { s, _ := json.MarshalIndent(args, "", "\t") log.Printf("%s%s\n", prefix, string(s)) } } func main() { // Command line flags for the vCenter connection snowURL := flag.String("url", "https://server.domain.example/api/global/em/inbound_event", "The URL of the SNOW endpoint") snowUser := flag.String("user", "username", "The username to use when authenticating to SNOW") snowPass := flag.String("password", "password", "The password to use when authenticating to SNOW") proxyURL := flag.String("p-url", "", "The URL of the SNOW endpoint, including protocol and port. Eg http://proxy.domain.example:8080") // proxyUser := flag.String("p-user", "", "The username to use when authenticating to the proxy") // proxyPass := flag.String("p-pass", "", "The password to use when authenticating to the proxy") // proxyDomain := flag.String("p-domain", "", "The domain to use when authenticating to the proxy with NTLM authentication") payload := flag.String("payload", "{}", "The JSON formatted payload to send to SNOW") flag.Parse() // Print logs to file f, err := os.OpenFile("log.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { log.Fatalf("error opening file: %v", err) } defer f.Close() log.SetOutput(f) //log.Printf("Starting execution. Built on %s from sha1 %s\n", buildTime, sha1ver) /* if err := ValidateAuthMethod(*proxyType); err != nil { log.Fatalf("error validating auth method '%s': %s\n", *proxyType, err) } else { fmt.Println("Valid auth method:", *proxyType) } */ // Validate the incoming payload var incident Incident if err := json.Unmarshal([]byte(*payload), &incident); err != nil { fmt.Printf("Error unmarshaling JSON: %s\n", err) os.Exit(1) } else { prettyPrint(incident) } // Configure proxy transport var transport http.RoundTripper = http.DefaultTransport if *proxyURL != "" { proxy, err := url.Parse(*proxyURL) if err != nil { fmt.Println("Invalid proxy URL:", err) return } // Base transport with proxy // baseTransport := &http.Transport{Proxy: http.ProxyURL(proxy)} transport = &http.Transport{Proxy: http.ProxyURL(proxy)} /* // If NTLM credentials are provided, wrap the transport if *proxyUser != "" && *proxyPass != "" { // create a dialer dialer := &net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, } // wrap dial context with NTLM ntlmDialContext := ntlm.NewNTLMProxyDialContext(dialer, *proxy, *proxyUser, *proxyPass, *proxyDomain, nil) transport = &http.Transport{ Proxy: nil, // !!! IMPORTANT, do not set proxy here !!! DialContext: ntlmDialContext, } } else { transport = baseTransport } */ } // Create HTTP client with custom transport client := &http.Client{ Transport: transport, } // Create the request req, err := http.NewRequest("POST", *snowURL, bytes.NewBuffer([]byte(*payload))) if err != nil { log.Println("Error creating request:", err) return } // Set headers req.Header.Set("Content-Type", "application/json") // Add Basic Authentication for target URL if *snowUser != "" && *snowPass != "" { basicAuth := base64.StdEncoding.EncodeToString([]byte(*snowUser + ":" + *snowPass)) req.Header.Set("Authorization", "Basic "+basicAuth) } // Send the request resp, err := client.Do(req) if err != nil { log.Println("Error sending request:", err) return } defer resp.Body.Close() // Read response body, err := io.ReadAll(resp.Body) if err != nil { log.Println("Error reading response:", err) return } // Print response log.Println("Response Status:", resp.Status) fmt.Println(string(body)) }