package statuscake import ( "encoding/json" "fmt" "net/url" "strings" "strconv" "github.com/google/go-querystring/query" ) //Ssl represent the data received by the API with GET type Ssl struct { ID string `json:"id" url:"id,omitempty"` Domain string `json:"domain" url:"domain,omitempty"` Checkrate int `json:"checkrate" url:"checkrate,omitempty"` ContactGroupsC string ` url:"contact_groups,omitempty"` AlertAt string `json:"alert_at" url:"alert_at,omitempty"` AlertReminder bool `json:"alert_reminder" url:"alert_expiry,omitempty"` AlertExpiry bool `json:"alert_expiry" url:"alert_reminder,omitempty"` AlertBroken bool `json:"alert_broken" url:"alert_broken,omitempty"` AlertMixed bool `json:"alert_mixed" url:"alert_mixed,omitempty"` Paused bool `json:"paused"` IssuerCn string `json:"issuer_cn"` CertScore string `json:"cert_score"` CipherScore string `json:"cipher_score"` CertStatus string `json:"cert_status"` Cipher string `json:"cipher"` ValidFromUtc string `json:"valid_from_utc"` ValidUntilUtc string `json:"valid_until_utc"` MixedContent []map[string]string `json:"mixed_content"` Flags map[string]bool `json:"flags"` ContactGroups []string `json:"contact_groups"` LastReminder int `json:"last_reminder"` LastUpdatedUtc string `json:"last_updated_utc"` } //PartialSsl represent a ssl test creation or modification type PartialSsl struct { ID int Domain string Checkrate string ContactGroupsC string AlertAt string AlertExpiry bool AlertReminder bool AlertBroken bool AlertMixed bool } type createSsl struct { ID int `url:"id,omitempty"` Domain string `url:"domain" json:"domain"` Checkrate string `url:"checkrate" json:"checkrate"` ContactGroupsC string `url:"contact_groups" json:"contact_groups"` AlertAt string `url:"alert_at" json:"alert_at"` AlertExpiry bool `url:"alert_expiry" json:"alert_expiry"` AlertReminder bool `url:"alert_reminder" json:"alert_reminder"` AlertBroken bool `url:"alert_broken" json:"alert_broken"` AlertMixed bool `url:"alert_mixed" json:"alert_mixed"` } type updateSsl struct { ID int `url:"id"` Domain string `url:"domain" json:"domain"` Checkrate string `url:"checkrate" json:"checkrate"` ContactGroupsC string `url:"contact_groups" json:"contact_groups"` AlertAt string `url:"alert_at" json:"alert_at"` AlertExpiry bool `url:"alert_expiry" json:"alert_expiry"` AlertReminder bool `url:"alert_reminder" json:"alert_reminder"` AlertBroken bool `url:"alert_broken" json:"alert_broken"` AlertMixed bool `url:"alert_mixed" json:"alert_mixed"` } type sslUpdateResponse struct { Success bool `json:"Success"` Message interface{} `json:"Message"` } type sslCreateResponse struct { Success bool `json:"Success"` Message interface{} `json:"Message"` Input createSsl `json:"Input"` } //Ssls represent the actions done wit the API type Ssls interface { All() ([]*Ssl, error) completeSsl(*PartialSsl) (*Ssl, error) Detail(string) (*Ssl, error) Update(*PartialSsl) (*Ssl, error) UpdatePartial(*PartialSsl) (*PartialSsl, error) Delete(ID string) error CreatePartial(*PartialSsl) (*PartialSsl, error) Create(*PartialSsl) (*Ssl, error) } func consolidateSsl(s *Ssl) { (*s).ContactGroupsC = strings.Trim(strings.Join(strings.Fields(fmt.Sprint((*s).ContactGroups)), ","), "[]") } func findSsl(responses []*Ssl, id string) (*Ssl, error) { var response *Ssl for _, elem := range responses { if (*elem).ID == id { return elem, nil } } return response, fmt.Errorf("%s Not found", id) } func (tt *ssls) completeSsl(s *PartialSsl) (*Ssl, error) { full, err := tt.Detail(strconv.Itoa((*s).ID)) if err != nil { return nil, err } (*full).ContactGroups = strings.Split((*s).ContactGroupsC,",") return full, nil } //Partial return a PartialSsl corresponding to the Ssl func Partial(s *Ssl) (*PartialSsl,error) { if s==nil { return nil,fmt.Errorf("s is nil") } id,err:=strconv.Atoi(s.ID) if(err!=nil){ return nil,err } return &PartialSsl{ ID: id, Domain: s.Domain, Checkrate: strconv.Itoa(s.Checkrate), ContactGroupsC: s.ContactGroupsC, AlertReminder: s.AlertReminder, AlertExpiry: s.AlertExpiry, AlertBroken: s.AlertBroken, AlertMixed: s.AlertMixed, AlertAt: s.AlertAt, },nil } type ssls struct { client apiClient } //NewSsls return a new ssls func NewSsls(c apiClient) Ssls { return &ssls{ client: c, } } //All return a list of all the ssl from the API func (tt *ssls) All() ([]*Ssl, error) { rawResponse, err := tt.client.get("/SSL", nil) if err != nil { return nil, fmt.Errorf("Error getting StatusCake Ssl: %s", err.Error()) } var getResponse []*Ssl err = json.NewDecoder(rawResponse.Body).Decode(&getResponse) if err != nil { return nil, err } for ssl := range getResponse { consolidateSsl(getResponse[ssl]) } return getResponse, err } //Detail return the ssl corresponding to the id func (tt *ssls) Detail(id string) (*Ssl, error) { responses, err := tt.All() if err != nil { return nil, err } mySsl, errF := findSsl(responses, id) if errF != nil { return nil, errF } return mySsl, nil } //Update update the API with s and create one if s.ID=0 then return the corresponding Ssl func (tt *ssls) Update(s *PartialSsl) (*Ssl, error) { var err error s, err = tt.UpdatePartial(s) if err!= nil { return nil, err } return tt.completeSsl(s) } //UpdatePartial update the API with s and create one if s.ID=0 then return the corresponding PartialSsl func (tt *ssls) UpdatePartial(s *PartialSsl) (*PartialSsl, error) { if((*s).ID == 0){ return tt.CreatePartial(s) } var v url.Values v, _ = query.Values(updateSsl(*s)) rawResponse, err := tt.client.put("/SSL/Update", v) if err != nil { return nil, fmt.Errorf("Error creating StatusCake Ssl: %s", err.Error()) } var updateResponse sslUpdateResponse err = json.NewDecoder(rawResponse.Body).Decode(&updateResponse) if err != nil { return nil, err } if !updateResponse.Success { return nil, fmt.Errorf("%s", updateResponse.Message.(string)) } return s, nil } //Delete delete the ssl which ID is id func (tt *ssls) Delete(id string) error { _, err := tt.client.delete("/SSL/Update", url.Values{"id": {fmt.Sprint(id)}}) if err != nil { return err } return nil } //Create create the ssl whith the data in s and return the Ssl created func (tt *ssls) Create(s *PartialSsl) (*Ssl, error) { var err error s, err = tt.CreatePartial(s) if err!= nil { return nil, err } return tt.completeSsl(s) } //CreatePartial create the ssl whith the data in s and return the PartialSsl created func (tt *ssls) CreatePartial(s *PartialSsl) (*PartialSsl, error) { (*s).ID=0 var v url.Values v, _ = query.Values(createSsl(*s)) rawResponse, err := tt.client.put("/SSL/Update", v) if err != nil { return nil, fmt.Errorf("Error creating StatusCake Ssl: %s", err.Error()) } var createResponse sslCreateResponse err = json.NewDecoder(rawResponse.Body).Decode(&createResponse) if err != nil { return nil, err } if !createResponse.Success { return nil, fmt.Errorf("%s", createResponse.Message.(string)) } *s = PartialSsl(createResponse.Input) (*s).ID = int(createResponse.Message.(float64)) return s,nil }