github.com/newrelic/newrelic-client-go@v1.1.0/pkg/entities/tags.go (about) 1 package entities 2 3 import ( 4 "context" 5 "errors" 6 "strings" 7 8 "github.com/newrelic/newrelic-client-go/pkg/common" 9 ) 10 11 // Tag represents a New Relic One entity tag. 12 // 13 // Deprecated: Use EntityTag instead. 14 type Tag struct { 15 Key string 16 Values []string 17 } 18 19 // TagValue represents a New Relic One entity tag and value pair. 20 // 21 // Deprecated: Use TaggingTagValueInput instead. 22 type TagValue struct { 23 Key string 24 Value string 25 } 26 27 // GetTagsForEntity returns a collection of all tags (mutable and not) for a given 28 // entity by entity GUID. 29 func (e *Entities) GetTagsForEntity(guid common.EntityGUID) ([]*EntityTag, error) { 30 return e.GetTagsForEntityWithContext(context.Background(), guid) 31 } 32 33 // GetTagsForEntityMutable returns a collection of all tags (mutable only) for a given 34 // entity by entity GUID. 35 func (e *Entities) GetTagsForEntityMutable(guid common.EntityGUID) ([]*EntityTag, error) { 36 return e.GetTagsForEntityWithContextMutable(context.Background(), guid) 37 } 38 39 // GetTagsForEntityWithContext returns a collection of all tags (mutable and not) for a given 40 // entity by entity GUID. 41 func (e *Entities) GetTagsForEntityWithContext(ctx context.Context, guid common.EntityGUID) ([]*EntityTag, error) { 42 resp := getTagsResponse{} 43 vars := map[string]interface{}{ 44 "guid": guid, 45 } 46 47 if err := e.client.NerdGraphQueryWithContext(ctx, listTagsQuery, vars, &resp); err != nil { 48 return nil, err 49 } 50 51 return resp.Actor.Entity.Tags, nil 52 } 53 54 // GetTagsForEntityWithContextMutable returns a collection of all tags (mutable only) for a given 55 // entity by entity GUID. 56 func (e *Entities) GetTagsForEntityWithContextMutable(ctx context.Context, guid common.EntityGUID) ([]*EntityTag, error) { 57 resp := getTagsResponse{} 58 vars := map[string]interface{}{ 59 "guid": guid, 60 } 61 62 if err := e.client.NerdGraphQueryWithContext(ctx, listTagsQuery, vars, &resp); err != nil { 63 return nil, err 64 } 65 66 return filterEntityTagMutable(resp) 67 } 68 69 // filterMutable removes tag values that are read-only from the received response. 70 func filterEntityTagMutable(resp getTagsResponse) ([]*EntityTag, error) { 71 var tags []*EntityTag 72 73 for _, responseTag := range resp.Actor.Entity.TagsWithMetadata { 74 if responseTag != nil { 75 tag := EntityTag{ 76 Key: responseTag.Key, 77 } 78 79 mutable := 0 80 for _, responseTagValue := range responseTag.Values { 81 if responseTagValue.Mutable { 82 mutable++ 83 tag.Values = append(tag.Values, responseTagValue.Value) 84 } 85 } 86 87 // All values were mutable 88 if len(responseTag.Values) == mutable { 89 tags = append(tags, &tag) 90 } 91 92 } 93 } 94 95 return tags, nil 96 } 97 98 // ListTags returns a collection of mutable tags for a given entity by entity GUID. 99 // 100 // Deprecated: Use GetTagsForEntity instead. 101 func (e *Entities) ListTags(guid common.EntityGUID) ([]*Tag, error) { 102 return e.ListTagsWithContext(context.Background(), guid) 103 } 104 105 // ListTagsWithContext returns a collection of mutable tags for a given entity by entity GUID. 106 // 107 // Deprecated: Use GetTagsForEntityWithContext instead. 108 func (e *Entities) ListTagsWithContext(ctx context.Context, guid common.EntityGUID) ([]*Tag, error) { 109 resp := listTagsResponse{} 110 vars := map[string]interface{}{ 111 "guid": guid, 112 } 113 114 if err := e.client.NerdGraphQueryWithContext(ctx, listTagsQuery, vars, &resp); err != nil { 115 return nil, err 116 } 117 118 return filterMutable(resp) 119 } 120 121 // ListAllTags returns a collection of all tags (mutable and not) for a given 122 // entity by entity GUID. 123 // 124 // Deprecated: Use GetTagsForEntity instead. 125 func (e *Entities) ListAllTags(guid common.EntityGUID) ([]*Tag, error) { 126 return e.ListAllTagsWithContext(context.Background(), guid) 127 } 128 129 // ListAllTagsWithContext returns a collection of all tags (mutable and not) for a given 130 // entity by entity GUID. 131 // 132 // Deprecated: Use GetTagsForEntityWithContext instead. 133 func (e *Entities) ListAllTagsWithContext(ctx context.Context, guid common.EntityGUID) ([]*Tag, error) { 134 resp := listTagsResponse{} 135 vars := map[string]interface{}{ 136 "guid": guid, 137 } 138 139 if err := e.client.NerdGraphQueryWithContext(ctx, listTagsQuery, vars, &resp); err != nil { 140 return nil, err 141 } 142 143 return resp.Actor.Entity.Tags, nil 144 } 145 146 // filterMutable removes tag values that are read-only from the received response. 147 func filterMutable(resp listTagsResponse) ([]*Tag, error) { 148 var tags []*Tag 149 150 for _, responseTag := range resp.Actor.Entity.TagsWithMetadata { 151 if responseTag != nil { 152 tag := Tag{ 153 Key: responseTag.Key, 154 } 155 156 mutable := 0 157 for _, responseTagValue := range responseTag.Values { 158 if responseTagValue.Mutable { 159 mutable++ 160 tag.Values = append(tag.Values, responseTagValue.Value) 161 } 162 } 163 164 // All values were mutable 165 if len(responseTag.Values) == mutable { 166 tags = append(tags, &tag) 167 } 168 169 } 170 } 171 172 return tags, nil 173 } 174 175 // AddTags writes tags to the entity specified by the provided entity GUID. 176 // 177 // Deprecated: Use TaggingAddTagsToEntity instead. 178 func (e *Entities) AddTags(guid common.EntityGUID, tags []Tag) error { 179 return e.AddTagsWithContext(context.Background(), guid, tags) 180 } 181 182 // AddTagsWithContext writes tags to the entity specified by the provided entity GUID. 183 // 184 // Deprecated: Use TaggingAddTagsToEntityWithContext instead. 185 func (e *Entities) AddTagsWithContext(ctx context.Context, guid common.EntityGUID, tags []Tag) error { 186 resp := addTagsResponse{} 187 vars := map[string]interface{}{ 188 "guid": guid, 189 "tags": tags, 190 } 191 192 if err := e.client.NerdGraphQueryWithContext(ctx, addTagsMutation, vars, &resp); err != nil { 193 return err 194 } 195 196 if len(resp.TaggingAddTagsToEntity.Errors) > 0 { 197 return errors.New(parseTagMutationErrors(resp.TaggingAddTagsToEntity.Errors)) 198 } 199 200 return nil 201 } 202 203 // ReplaceTags replaces the entity's entire set of tags with the provided tag set. 204 // 205 // Deprecated: Use TaggingReplaceTagsOnEntity instead. 206 func (e *Entities) ReplaceTags(guid common.EntityGUID, tags []Tag) error { 207 return e.ReplaceTagsWithContext(context.Background(), guid, tags) 208 } 209 210 // ReplaceTagsWithContext replaces the entity's entire set of tags with the provided tag set. 211 // 212 // Deprecated: Use TaggingReplaceTagsOnEntityWithContext instead. 213 func (e *Entities) ReplaceTagsWithContext(ctx context.Context, guid common.EntityGUID, tags []Tag) error { 214 resp := replaceTagsResponse{} 215 vars := map[string]interface{}{ 216 "guid": guid, 217 "tags": tags, 218 } 219 220 if err := e.client.NerdGraphQueryWithContext(ctx, replaceTagsMutation, vars, &resp); err != nil { 221 return err 222 } 223 224 if len(resp.TaggingReplaceTagsOnEntity.Errors) > 0 { 225 return errors.New(parseTagMutationErrors(resp.TaggingReplaceTagsOnEntity.Errors)) 226 } 227 228 return nil 229 } 230 231 // DeleteTags deletes specific tag keys from the entity. 232 // 233 // Deprecated: Use TaggingDeleteTagFromEntity instead. 234 func (e *Entities) DeleteTags(guid common.EntityGUID, tagKeys []string) error { 235 return e.DeleteTagsWithContext(context.Background(), guid, tagKeys) 236 } 237 238 // DeleteTagsWithContext deletes specific tag keys from the entity. 239 // 240 // Deprecated: Use TaggingDeleteTagFromEntityWithContext instead. 241 func (e *Entities) DeleteTagsWithContext(ctx context.Context, guid common.EntityGUID, tagKeys []string) error { 242 resp := deleteTagsResponse{} 243 vars := map[string]interface{}{ 244 "guid": guid, 245 "tagKeys": tagKeys, 246 } 247 248 if err := e.client.NerdGraphQueryWithContext(ctx, deleteTagsMutation, vars, &resp); err != nil { 249 return err 250 } 251 252 if len(resp.TaggingDeleteTagFromEntity.Errors) > 0 { 253 return errors.New(parseTagMutationErrors(resp.TaggingDeleteTagFromEntity.Errors)) 254 } 255 256 return nil 257 } 258 259 // DeleteTagValues deletes specific tag key and value pairs from the entity. 260 // 261 // Deprecated: Use TaggingDeleteTagValuesFromEntity instead. 262 func (e *Entities) DeleteTagValues(guid common.EntityGUID, tagValues []TagValue) error { 263 return e.DeleteTagValuesWithContext(context.Background(), guid, tagValues) 264 } 265 266 // DeleteTagValuesWithContext deletes specific tag key and value pairs from the entity. 267 // 268 // Deprecated: Use TaggingDeleteTagValuesFromEntityWithContext instead. 269 func (e *Entities) DeleteTagValuesWithContext(ctx context.Context, guid common.EntityGUID, tagValues []TagValue) error { 270 resp := deleteTagValuesResponse{} 271 vars := map[string]interface{}{ 272 "guid": guid, 273 "tagValues": tagValues, 274 } 275 276 if err := e.client.NerdGraphQueryWithContext(ctx, deleteTagValuesMutation, vars, &resp); err != nil { 277 return err 278 } 279 280 if len(resp.TaggingDeleteTagValuesFromEntity.Errors) > 0 { 281 return errors.New(parseTagMutationErrors(resp.TaggingDeleteTagValuesFromEntity.Errors)) 282 } 283 284 return nil 285 } 286 287 type tagMutationError struct { 288 Type string 289 Message string 290 } 291 292 func parseTagMutationErrors(errors []tagMutationError) string { 293 messages := []string{} 294 for _, e := range errors { 295 messages = append(messages, e.Message) 296 } 297 298 return strings.Join(messages, ", ") 299 } 300 301 var listTagsQuery = ` 302 query($guid:EntityGuid!) { actor { entity(guid: $guid) { 303 tagsWithMetadata { key values { mutable value } } 304 tags { key values } 305 } } }` 306 307 type listTagsResponse struct { 308 Actor struct { 309 Entity struct { 310 Tags []*Tag 311 TagsWithMetadata []*EntityTagWithMetadata 312 } 313 } 314 } 315 316 type getTagsResponse struct { 317 Actor struct { 318 Entity struct { 319 Tags []*EntityTag 320 TagsWithMetadata []*EntityTagWithMetadata 321 } 322 } 323 } 324 325 var addTagsMutation = ` 326 mutation($guid: EntityGuid!, $tags: [TaggingTagInput!]!) { 327 taggingAddTagsToEntity(guid: $guid, tags: $tags) { 328 errors { 329 type 330 message 331 } 332 } 333 } 334 ` 335 336 type addTagsResponse struct { 337 TaggingAddTagsToEntity struct { 338 Errors []tagMutationError 339 } 340 } 341 342 var replaceTagsMutation = ` 343 mutation($guid: EntityGuid!, $tags: [TaggingTagInput!]!) { 344 taggingReplaceTagsOnEntity(guid: $guid, tags: $tags) { 345 errors { 346 type 347 message 348 } 349 } 350 } 351 ` 352 353 type replaceTagsResponse struct { 354 TaggingReplaceTagsOnEntity struct { 355 Errors []tagMutationError 356 } 357 } 358 359 var deleteTagsMutation = ` 360 mutation($guid: EntityGuid!, $tagKeys: [String!]!) { 361 taggingDeleteTagFromEntity(guid: $guid, tagKeys: $tagKeys) { 362 errors { 363 type 364 message 365 } 366 } 367 } 368 ` 369 370 type deleteTagsResponse struct { 371 TaggingDeleteTagFromEntity struct { 372 Errors []tagMutationError 373 } 374 } 375 376 var deleteTagValuesMutation = ` 377 mutation($guid: EntityGuid!, $tagValues: [TaggingTagValueInput!]!) { 378 taggingDeleteTagValuesFromEntity(guid: $guid, tagValues: $tagValues) { 379 errors { 380 type 381 message 382 } 383 } 384 } 385 ` 386 387 type deleteTagValuesResponse struct { 388 TaggingDeleteTagValuesFromEntity struct { 389 Errors []tagMutationError 390 } 391 }