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  }