224 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package main
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"log"
 | |
| 	"net"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	"encoding/json"
 | |
| 	"net/http"
 | |
| 
 | |
| 	"tplink/internal/tplink"
 | |
| )
 | |
| 
 | |
| func tmpltError(w http.ResponseWriter, s int, m string) {
 | |
| 	var (
 | |
| 		output []byte
 | |
| 		o      = struct {
 | |
| 			Error    bool   `json:"error" yaml:"error"`
 | |
| 			ErrorMsg string `json:"errorMessage" yaml:"errorMessage"`
 | |
| 		}{
 | |
| 			Error:    true,
 | |
| 			ErrorMsg: m,
 | |
| 		}
 | |
| 		err error
 | |
| 	)
 | |
| 
 | |
| 	w.Header().Add("Content-Type", "application/json")
 | |
| 
 | |
| 	output, err = json.MarshalIndent(o, "", "  ")
 | |
| 	if err != nil {
 | |
| 		log.Printf("[TRACE] Unable to marshal error message: %v.", err)
 | |
| 	}
 | |
| 	w.WriteHeader(s)
 | |
| 	w.Write(output) //nolint:errcheck
 | |
| }
 | |
| 
 | |
| func tmpltWebRoot(w http.ResponseWriter) {
 | |
| 	o := struct {
 | |
| 		Application string `json:"application" yaml:"application"`
 | |
| 		Description string `json:"description" yaml:"description"`
 | |
| 		Version     string `json:"version" yaml:"version"`
 | |
| 	}{
 | |
| 		Application: "TP-Link Web API",
 | |
| 		Description: "API for automated calls to TP-Link devices",
 | |
| 		Version:     "v1.0.0",
 | |
| 	}
 | |
| 	w.Header().Add("Content-Type", "application/json")
 | |
| 
 | |
| 	output, err := json.MarshalIndent(o, "", "  ")
 | |
| 	if err != nil {
 | |
| 		log.Printf("[TRACE] Unable to marshal error message: %v.", err)
 | |
| 	}
 | |
| 	w.Write(output) //nolint:errcheck
 | |
| }
 | |
| 
 | |
| func tmpltHealthCheck(w http.ResponseWriter) {
 | |
| 	o := struct {
 | |
| 		WebServer bool   `json:"webServerActive" yaml:"webServerActive"`
 | |
| 		Status    string `json:"status" yaml:"status"`
 | |
| 	}{
 | |
| 		WebServer: true,
 | |
| 		Status:    "healthy",
 | |
| 	}
 | |
| 
 | |
| 	output, err := json.MarshalIndent(o, "", "  ")
 | |
| 	if err != nil {
 | |
| 		log.Printf("[TRACE] Unable to marshal status message: %v.", err)
 | |
| 	}
 | |
| 
 | |
| 	w.Header().Add("Content-Type", "application/json")
 | |
| 	w.Write(output) //nolint:errcheck
 | |
| }
 | |
| 
 | |
| func tmpltTPlinkGet(w http.ResponseWriter, r *http.Request) {
 | |
| 	keys := r.URL.Query()
 | |
| 	if len(keys) == 0 {
 | |
| 		log.Printf("[INFO] Required parameters missing: no host, state, or deviceid was provided.\n")
 | |
| 		tmpltError(w, http.StatusBadRequest, "Required parameters missing: no parameter for host, state, or deviceid was provided.")
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	var (
 | |
| 		host     string
 | |
| 		hostSet  bool
 | |
| 		state    bool
 | |
| 		stateSet bool
 | |
| 		id       int
 | |
| 	)
 | |
| 
 | |
| 	for k, v := range keys {
 | |
| 		switch strings.ToLower(k) {
 | |
| 		case "host":
 | |
| 			if len(v) != 1 {
 | |
| 				log.Printf("[INFO] Host was defined multiple times.\n")
 | |
| 				tmpltError(w, http.StatusBadRequest, "Required parameter host was defined multiple times.")
 | |
| 				return
 | |
| 			}
 | |
| 			_, err := net.LookupHost(v[0])
 | |
| 			if err != nil {
 | |
| 				log.Printf("[INFO] Unable to resolve provided hostname: %s\n", v[0])
 | |
| 				tmpltError(w, http.StatusBadRequest, "Unable to resolve provided hostname.")
 | |
| 				return
 | |
| 			}
 | |
| 			hostSet = true
 | |
| 			host = v[0]
 | |
| 
 | |
| 		case "state":
 | |
| 			if len(v) != 1 {
 | |
| 				log.Printf("[INFO] State was defined multiple times.\n")
 | |
| 				tmpltError(w, http.StatusBadRequest, "Required parameter state was defined multiple times.")
 | |
| 				return
 | |
| 			}
 | |
| 			s, err := strconv.ParseBool(v[0])
 | |
| 			if err != nil {
 | |
| 				log.Printf("[INFO] State is not boolean: %s\n", v[0])
 | |
| 				tmpltError(w, http.StatusBadRequest, "Required parameter state is not boolean.")
 | |
| 				return
 | |
| 			}
 | |
| 			stateSet = true
 | |
| 			state = s
 | |
| 
 | |
| 		case "deviceid":
 | |
| 			if len(v) != 1 {
 | |
| 				log.Printf("[INFO] Deviceid was defined multiple times.\n")
 | |
| 				tmpltError(w, http.StatusBadRequest, "Required parameter device was defined multiple times.")
 | |
| 				return
 | |
| 			}
 | |
| 			d, err := strconv.Atoi(v[0])
 | |
| 			if err != nil {
 | |
| 				log.Printf("[INFO] Deviceid is not an integer: %s\n", v[0])
 | |
| 				tmpltError(w, http.StatusBadRequest, "Required parameter deviceid is not an integer.")
 | |
| 				return
 | |
| 			}
 | |
| 			id = d
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if !hostSet {
 | |
| 		log.Printf("[INFO] Required parameter missing: no host was provided.\n")
 | |
| 		tmpltError(w, http.StatusBadRequest, "Required parameters missing: no parameter for host provided.")
 | |
| 		return
 | |
| 	}
 | |
| 	if !stateSet {
 | |
| 		log.Printf("[INFO] Required parameter missing: no state was provided.\n")
 | |
| 		tmpltError(w, http.StatusBadRequest, "Required parameters missing: no parameter for state provided.")
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	t := tplink.Tplink{
 | |
| 		Host:     host,
 | |
| 		SwitchID: id,
 | |
| 	}
 | |
| 	if err := t.ChangeStateMultiSwitch(state); err != nil {
 | |
| 		log.Printf("[INFO] Unable to change device state: %v\n", err)
 | |
| 		tmpltError(w, http.StatusInternalServerError, fmt.Sprintf("Unable to change device state: %v\n", err))
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	sysInfo, err := t.SystemInfo()
 | |
| 	if err != nil {
 | |
| 		log.Printf("[INFO] Unable to get info from target device: %v\n", err)
 | |
| 		tmpltError(w, http.StatusInternalServerError, fmt.Sprintf("Unable to read info from device: %v\n", err))
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	var ds int
 | |
| 	if len(sysInfo.System.GetSysinfo.Children) == 0 {
 | |
| 		ds = sysInfo.System.GetSysinfo.RelayState
 | |
| 	} else {
 | |
| 		ds = sysInfo.System.GetSysinfo.Children[id].State
 | |
| 	}
 | |
| 
 | |
| 	var fs string
 | |
| 	if ds == 0 {
 | |
| 		fs = "OFF"
 | |
| 	} else {
 | |
| 		fs = "ON"
 | |
| 	}
 | |
| 
 | |
| 	o := struct {
 | |
| 		Status   string `json:"status" yaml:"status"`
 | |
| 		Host     string `json:"host" yaml:"host"`
 | |
| 		DeviceID int    `json:"device_id" yaml:"deviceID"`
 | |
| 	}{
 | |
| 		Status:   fs,
 | |
| 		Host:     host,
 | |
| 		DeviceID: id,
 | |
| 	}
 | |
| 	w.Header().Add("Content-Type", "application/json")
 | |
| 
 | |
| 	output, err := json.MarshalIndent(o, "", "  ")
 | |
| 	if err != nil {
 | |
| 		log.Printf("[TRACE] Unable to marshal error message: %v.", err)
 | |
| 	}
 | |
| 	w.Write(output) //nolint:errcheck
 | |
| }
 | |
| 
 | |
| func tmpltTPlinkPost(w http.ResponseWriter, r *http.Request) {
 | |
| 	var payload alertmanagerStruct
 | |
| 
 | |
| 	// read body
 | |
| 	defer r.Body.Close()
 | |
| 	b, err := io.ReadAll(r.Body)
 | |
| 	if err != nil {
 | |
| 		log.Printf("[DEBUG] Unable to read post body from request: %v\n", err)
 | |
| 		tmpltError(w, http.StatusInternalServerError, fmt.Sprintf("Unable to read post body from request: %v", err))
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	// unmarshal body
 | |
| 	err = json.Unmarshal(b, &payload)
 | |
| 	if err != nil {
 | |
| 		log.Printf("[TRACE] Data received:\n--START--\n%s\n--END--\n", string(b))
 | |
| 		log.Printf("[INFO] Unable to parse payload from API call: %v\n", err)
 | |
| 		tmpltError(w, http.StatusInternalServerError, fmt.Sprintf("Unable to read info from device: %v\n", err))
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	log.Printf("[TRACE] Data received: %#v\n", payload)
 | |
| }
 |