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// Worksheet API support - Fetch, Create, Update, Delete, and Search 6// See: https://login.circonus.com/resources/api/calls/worksheet 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// WorksheetGraph defines a worksheet cid to be include in the worksheet 20type WorksheetGraph struct { 21 GraphCID string `json:"graph"` // string 22} 23 24// WorksheetSmartQuery defines a query to include multiple worksheets 25type WorksheetSmartQuery struct { 26 Name string `json:"name"` 27 Order []string `json:"order"` 28 Query string `json:"query"` 29} 30 31// Worksheet defines a worksheet. See https://login.circonus.com/resources/api/calls/worksheet for more information. 32type Worksheet struct { 33 CID string `json:"_cid,omitempty"` // string 34 Description *string `json:"description"` // string or null 35 Favorite bool `json:"favorite"` // boolean 36 Graphs []WorksheetGraph `json:"graphs"` // [] len >= 0 37 Notes *string `json:"notes"` // string or null 38 SmartQueries []WorksheetSmartQuery `json:"smart_queries,omitempty"` // [] len >= 0 39 Tags []string `json:"tags"` // [] len >= 0 40 Title string `json:"title"` // string 41} 42 43// NewWorksheet returns a new Worksheet (with defaults, if applicable) 44func NewWorksheet() *Worksheet { 45 return &Worksheet{ 46 Graphs: []WorksheetGraph{}, // graphs is a required attribute and cannot be null 47 } 48} 49 50// FetchWorksheet retrieves worksheet with passed cid. 51func (a *API) FetchWorksheet(cid CIDType) (*Worksheet, error) { 52 if cid == nil || *cid == "" { 53 return nil, fmt.Errorf("Invalid worksheet CID [none]") 54 } 55 56 worksheetCID := string(*cid) 57 58 matched, err := regexp.MatchString(config.WorksheetCIDRegex, worksheetCID) 59 if err != nil { 60 return nil, err 61 } 62 if !matched { 63 return nil, fmt.Errorf("Invalid worksheet CID [%s]", worksheetCID) 64 } 65 66 result, err := a.Get(string(*cid)) 67 if err != nil { 68 return nil, err 69 } 70 71 if a.Debug { 72 a.Log.Printf("[DEBUG] fetch worksheet, received JSON: %s", string(result)) 73 } 74 75 worksheet := new(Worksheet) 76 if err := json.Unmarshal(result, worksheet); err != nil { 77 return nil, err 78 } 79 80 return worksheet, nil 81} 82 83// FetchWorksheets retrieves all worksheets available to API Token. 84func (a *API) FetchWorksheets() (*[]Worksheet, error) { 85 result, err := a.Get(config.WorksheetPrefix) 86 if err != nil { 87 return nil, err 88 } 89 90 var worksheets []Worksheet 91 if err := json.Unmarshal(result, &worksheets); err != nil { 92 return nil, err 93 } 94 95 return &worksheets, nil 96} 97 98// UpdateWorksheet updates passed worksheet. 99func (a *API) UpdateWorksheet(cfg *Worksheet) (*Worksheet, error) { 100 if cfg == nil { 101 return nil, fmt.Errorf("Invalid worksheet config [nil]") 102 } 103 104 worksheetCID := string(cfg.CID) 105 106 matched, err := regexp.MatchString(config.WorksheetCIDRegex, worksheetCID) 107 if err != nil { 108 return nil, err 109 } 110 if !matched { 111 return nil, fmt.Errorf("Invalid worksheet CID [%s]", worksheetCID) 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 worksheet, sending JSON: %s", string(jsonCfg)) 121 } 122 123 result, err := a.Put(worksheetCID, jsonCfg) 124 if err != nil { 125 return nil, err 126 } 127 128 worksheet := &Worksheet{} 129 if err := json.Unmarshal(result, worksheet); err != nil { 130 return nil, err 131 } 132 133 return worksheet, nil 134} 135 136// CreateWorksheet creates a new worksheet. 137func (a *API) CreateWorksheet(cfg *Worksheet) (*Worksheet, error) { 138 if cfg == nil { 139 return nil, fmt.Errorf("Invalid worksheet 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 annotation, sending JSON: %s", string(jsonCfg)) 149 } 150 151 result, err := a.Post(config.WorksheetPrefix, jsonCfg) 152 if err != nil { 153 return nil, err 154 } 155 156 worksheet := &Worksheet{} 157 if err := json.Unmarshal(result, worksheet); err != nil { 158 return nil, err 159 } 160 161 return worksheet, nil 162} 163 164// DeleteWorksheet deletes passed worksheet. 165func (a *API) DeleteWorksheet(cfg *Worksheet) (bool, error) { 166 if cfg == nil { 167 return false, fmt.Errorf("Invalid worksheet config [nil]") 168 } 169 return a.DeleteWorksheetByCID(CIDType(&cfg.CID)) 170} 171 172// DeleteWorksheetByCID deletes worksheet with passed cid. 173func (a *API) DeleteWorksheetByCID(cid CIDType) (bool, error) { 174 if cid == nil || *cid == "" { 175 return false, fmt.Errorf("Invalid worksheet CID [none]") 176 } 177 178 worksheetCID := string(*cid) 179 180 matched, err := regexp.MatchString(config.WorksheetCIDRegex, worksheetCID) 181 if err != nil { 182 return false, err 183 } 184 if !matched { 185 return false, fmt.Errorf("Invalid worksheet CID [%s]", worksheetCID) 186 } 187 188 _, err = a.Delete(worksheetCID) 189 if err != nil { 190 return false, err 191 } 192 193 return true, nil 194} 195 196// SearchWorksheets returns worksheets matching the specified search 197// query and/or filter. If nil is passed for both parameters all 198// worksheets will be returned. 199func (a *API) SearchWorksheets(searchCriteria *SearchQueryType, filterCriteria *SearchFilterType) (*[]Worksheet, 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.FetchWorksheets() 216 } 217 218 reqURL := url.URL{ 219 Path: config.WorksheetPrefix, 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 worksheets []Worksheet 229 if err := json.Unmarshal(result, &worksheets); err != nil { 230 return nil, err 231 } 232 233 return &worksheets, nil 234} 235