1// Copyright 2016 Circonus, Inc. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Rule Set API support - Fetch, Create, Update, Delete, and Search 6// See: https://login.circonus.com/resources/api/calls/rule_set 7 8package api 9 10import ( 11 "encoding/json" 12 "fmt" 13 "net/url" 14 "regexp" 15 16 "github.com/circonus-labs/circonus-gometrics/api/config" 17) 18 19// RuleSetRule defines a ruleset rule 20type RuleSetRule struct { 21 Criteria string `json:"criteria"` // string 22 Severity uint `json:"severity"` // uint 23 Value interface{} `json:"value"` // BUG doc: string, api: actual type returned switches based on Criteria 24 Wait uint `json:"wait"` // uint 25 WindowingDuration uint `json:"windowing_duration,omitempty"` // uint 26 WindowingFunction *string `json:"windowing_function,omitempty"` // string or null 27} 28 29// RuleSet defines a ruleset. See https://login.circonus.com/resources/api/calls/rule_set for more information. 30type RuleSet struct { 31 CheckCID string `json:"check"` // string 32 CID string `json:"_cid,omitempty"` // string 33 ContactGroups map[uint8][]string `json:"contact_groups"` // [] len 5 34 Derive *string `json:"derive,omitempty"` // string or null 35 Link *string `json:"link"` // string or null 36 MetricName string `json:"metric_name"` // string 37 MetricTags []string `json:"metric_tags"` // [] len >= 0 38 MetricType string `json:"metric_type"` // string 39 Notes *string `json:"notes"` // string or null 40 Parent *string `json:"parent,omitempty"` // string or null 41 Rules []RuleSetRule `json:"rules"` // [] len >= 1 42 Tags []string `json:"tags"` // [] len >= 0 43} 44 45// NewRuleSet returns a new RuleSet (with defaults if applicable) 46func NewRuleSet() *RuleSet { 47 return &RuleSet{} 48} 49 50// FetchRuleSet retrieves rule set with passed cid. 51func (a *API) FetchRuleSet(cid CIDType) (*RuleSet, error) { 52 if cid == nil || *cid == "" { 53 return nil, fmt.Errorf("Invalid rule set CID [none]") 54 } 55 56 rulesetCID := string(*cid) 57 58 matched, err := regexp.MatchString(config.RuleSetCIDRegex, rulesetCID) 59 if err != nil { 60 return nil, err 61 } 62 if !matched { 63 return nil, fmt.Errorf("Invalid rule set CID [%s]", rulesetCID) 64 } 65 66 result, err := a.Get(rulesetCID) 67 if err != nil { 68 return nil, err 69 } 70 71 if a.Debug { 72 a.Log.Printf("[DEBUG] fetch rule set, received JSON: %s", string(result)) 73 } 74 75 ruleset := &RuleSet{} 76 if err := json.Unmarshal(result, ruleset); err != nil { 77 return nil, err 78 } 79 80 return ruleset, nil 81} 82 83// FetchRuleSets retrieves all rule sets available to API Token. 84func (a *API) FetchRuleSets() (*[]RuleSet, error) { 85 result, err := a.Get(config.RuleSetPrefix) 86 if err != nil { 87 return nil, err 88 } 89 90 var rulesets []RuleSet 91 if err := json.Unmarshal(result, &rulesets); err != nil { 92 return nil, err 93 } 94 95 return &rulesets, nil 96} 97 98// UpdateRuleSet updates passed rule set. 99func (a *API) UpdateRuleSet(cfg *RuleSet) (*RuleSet, error) { 100 if cfg == nil { 101 return nil, fmt.Errorf("Invalid rule set config [nil]") 102 } 103 104 rulesetCID := string(cfg.CID) 105 106 matched, err := regexp.MatchString(config.RuleSetCIDRegex, rulesetCID) 107 if err != nil { 108 return nil, err 109 } 110 if !matched { 111 return nil, fmt.Errorf("Invalid rule set CID [%s]", rulesetCID) 112 } 113 114 jsonCfg, err := json.Marshal(cfg) 115 if err != nil { 116 return nil, err 117 } 118 119 if a.Debug { 120 a.Log.Printf("[DEBUG] update rule set, sending JSON: %s", string(jsonCfg)) 121 } 122 123 result, err := a.Put(rulesetCID, jsonCfg) 124 if err != nil { 125 return nil, err 126 } 127 128 ruleset := &RuleSet{} 129 if err := json.Unmarshal(result, ruleset); err != nil { 130 return nil, err 131 } 132 133 return ruleset, nil 134} 135 136// CreateRuleSet creates a new rule set. 137func (a *API) CreateRuleSet(cfg *RuleSet) (*RuleSet, error) { 138 if cfg == nil { 139 return nil, fmt.Errorf("Invalid rule set config [nil]") 140 } 141 142 jsonCfg, err := json.Marshal(cfg) 143 if err != nil { 144 return nil, err 145 } 146 147 if a.Debug { 148 a.Log.Printf("[DEBUG] create rule set, sending JSON: %s", string(jsonCfg)) 149 } 150 151 resp, err := a.Post(config.RuleSetPrefix, jsonCfg) 152 if err != nil { 153 return nil, err 154 } 155 156 ruleset := &RuleSet{} 157 if err := json.Unmarshal(resp, ruleset); err != nil { 158 return nil, err 159 } 160 161 return ruleset, nil 162} 163 164// DeleteRuleSet deletes passed rule set. 165func (a *API) DeleteRuleSet(cfg *RuleSet) (bool, error) { 166 if cfg == nil { 167 return false, fmt.Errorf("Invalid rule set config [nil]") 168 } 169 return a.DeleteRuleSetByCID(CIDType(&cfg.CID)) 170} 171 172// DeleteRuleSetByCID deletes rule set with passed cid. 173func (a *API) DeleteRuleSetByCID(cid CIDType) (bool, error) { 174 if cid == nil || *cid == "" { 175 return false, fmt.Errorf("Invalid rule set CID [none]") 176 } 177 178 rulesetCID := string(*cid) 179 180 matched, err := regexp.MatchString(config.RuleSetCIDRegex, rulesetCID) 181 if err != nil { 182 return false, err 183 } 184 if !matched { 185 return false, fmt.Errorf("Invalid rule set CID [%s]", rulesetCID) 186 } 187 188 _, err = a.Delete(rulesetCID) 189 if err != nil { 190 return false, err 191 } 192 193 return true, nil 194} 195 196// SearchRuleSets returns rule sets matching the specified search 197// query and/or filter. If nil is passed for both parameters all 198// rule sets will be returned. 199func (a *API) SearchRuleSets(searchCriteria *SearchQueryType, filterCriteria *SearchFilterType) (*[]RuleSet, error) { 200 q := url.Values{} 201 202 if searchCriteria != nil && *searchCriteria != "" { 203 q.Set("search", string(*searchCriteria)) 204 } 205 206 if filterCriteria != nil && len(*filterCriteria) > 0 { 207 for filter, criteria := range *filterCriteria { 208 for _, val := range criteria { 209 q.Add(filter, val) 210 } 211 } 212 } 213 214 if q.Encode() == "" { 215 return a.FetchRuleSets() 216 } 217 218 reqURL := url.URL{ 219 Path: config.RuleSetPrefix, 220 RawQuery: q.Encode(), 221 } 222 223 result, err := a.Get(reqURL.String()) 224 if err != nil { 225 return nil, fmt.Errorf("[ERROR] API call error %+v", err) 226 } 227 228 var rulesets []RuleSet 229 if err := json.Unmarshal(result, &rulesets); err != nil { 230 return nil, err 231 } 232 233 return &rulesets, nil 234} 235