Skip to content

Commit

Permalink
Add space name/id and org name/id as tags on CF (#6249)
Browse files Browse the repository at this point in the history
  • Loading branch information
Slavek Kabrda authored Aug 20, 2020
1 parent 5061529 commit 951a737
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 34 deletions.
5 changes: 1 addition & 4 deletions pkg/autodiscovery/listeners/cloudfoundry.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,7 @@ func (l *CloudFoundryListener) createService(adID cloudfoundry.ADIdentifier, fir
containerIPs: map[string]string{},
containerPorts: []ContainerPort{},
creationTime: crTime,
tags: []string{
fmt.Sprintf("%s:%s", cloudfoundry.AppNameTagKey, dLRP.AppName),
fmt.Sprintf("%s:%s", cloudfoundry.AppGUIDTagKey, dLRP.AppGUID),
},
tags: dLRP.GetTagsFromDLRP(),
}
} else {
if aLRP.State != cloudfoundry.ActualLrpStateRunning {
Expand Down
20 changes: 14 additions & 6 deletions pkg/autodiscovery/listeners/cloudfoundry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func TestCloudFoundryListener(t *testing.T) {
containerIPs: map[string]string{},
containerPorts: []ContainerPort{},
creationTime: integration.After,
tags: []string{"app_name:myappname1", "app_guid:myappguid1"},
tags: []string{"app_guid:myappguid1", "app_id:myappguid1", "app_name:myappname1"},
},
},
expDel: map[string]Service{},
Expand Down Expand Up @@ -302,7 +302,11 @@ func TestCloudFoundryListener(t *testing.T) {
"instances": json.RawMessage(`[{"name": "My Nginx", "url": "http://%%host%%:%%port_p8080%%", "timeout": 1}]`),
},
},
EnvVcapServices: map[string][]byte{"my-postgres": []byte(`{"credentials":{"host":"a.b.c","Username":"me","Password":"secret","database_name":"mydb"}}`)},
EnvVcapServices: map[string][]byte{"my-postgres": []byte(`{"credentials":{"host":"a.b.c","Username":"me","Password":"secret","database_name":"mydb"}}`)},
OrganizationGUID: "orgguid1",
OrganizationName: "orgname1",
SpaceGUID: "spaceguid1",
SpaceName: "spacename1",
},
"processguid2": {
AppGUID: "appguid2",
Expand All @@ -321,7 +325,11 @@ func TestCloudFoundryListener(t *testing.T) {
"instances": json.RawMessage(`[{"name": "My Nginx", "url": "http://%%host%%:%%port_p8080%%", "timeout": 1}]`),
},
},
EnvVcapServices: map[string][]byte{"my-postgres": []byte(`{"credentials":{"host":"a.b.c","Username":"me","Password":"secret","database_name":"mydb"}}`)},
EnvVcapServices: map[string][]byte{"my-postgres": []byte(`{"credentials":{"host":"a.b.c","Username":"me","Password":"secret","database_name":"mydb"}}`)},
OrganizationGUID: "orgguid2",
OrganizationName: "orgname2",
SpaceGUID: "spaceguid2",
SpaceName: "spacename2",
},
"processguid3": {
AppGUID: "appguid3",
Expand All @@ -348,7 +356,7 @@ func TestCloudFoundryListener(t *testing.T) {
containerIPs: map[string]string{},
containerPorts: []ContainerPort{},
creationTime: integration.After,
tags: []string{"app_name:myappname1", "app_guid:myappguid1"},
tags: []string{"app_guid:myappguid1", "app_id:myappguid1", "app_name:myappname1"},
},
},
expNew: map[string]Service{
Expand Down Expand Up @@ -386,7 +394,7 @@ func TestCloudFoundryListener(t *testing.T) {
containerIPs: map[string]string{},
containerPorts: []ContainerPort{},
creationTime: integration.After,
tags: []string{"app_name:appname1", "app_guid:appguid1"},
tags: []string{"app_guid:appguid1", "app_id:appguid1", "app_name:appname1", "org_id:orgguid1", "org_name:orgname1", "space_id:spaceguid1", "space_name:spacename1"},
},
"processguid2/flask-app/0": &CloudFoundryService{
containerIPs: map[string]string{CfServiceContainerIP: "1.2.3.7"},
Expand Down Expand Up @@ -422,7 +430,7 @@ func TestCloudFoundryListener(t *testing.T) {
containerIPs: map[string]string{},
containerPorts: []ContainerPort{},
creationTime: integration.After,
tags: []string{"app_name:appname2", "app_guid:appguid2"},
tags: []string{"app_guid:appguid2", "app_id:appguid2", "app_name:appname2", "org_id:orgguid2", "org_name:orgname2", "space_id:spaceguid2", "space_name:spacename2"},
},
},
},
Expand Down
7 changes: 3 additions & 4 deletions pkg/util/cloudfoundry/bbscache.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,18 +284,17 @@ func (bc *BBSCache) extractNodeTags(nodeActualLRPs []*ActualLRP, desiredLRPsByPr
continue
}
vcApp := dlrp.EnvVcapApplication
appName, ok := vcApp[ApplicationNameKey]
_, ok = vcApp[ApplicationNameKey]
if !ok {
log.Debugf("Could not find application_name of app %s", dlrp.AppGUID)
continue
}
tags[alrp.InstanceGUID] = []string{
fmt.Sprintf("%s:%s_%d", ContainerNameTagKey, appName, alrp.Index),
fmt.Sprintf("%s:%s", AppNameTagKey, appName),
fmt.Sprintf("%s:%s", AppGUIDTagKey, dlrp.AppGUID),
fmt.Sprintf("%s:%s_%d", ContainerNameTagKey, dlrp.AppName, alrp.Index),
fmt.Sprintf("%s:%d", AppInstanceIndexTagKey, alrp.Index),
fmt.Sprintf("%s:%s", AppInstanceGUIDTagKey, alrp.InstanceGUID),
}
tags[alrp.InstanceGUID] = append(tags[alrp.InstanceGUID], dlrp.GetTagsFromDLRP()...)
}
return tags
}
18 changes: 14 additions & 4 deletions pkg/util/cloudfoundry/bbscache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,15 @@ func TestBBSCache_GetTagsForNode(t *testing.T) {
expectedTags := map[string][]string{
"0123456789012345678": {
"container_name:name_of_the_app_4",
"app_name:name_of_the_app",
"app_guid:random_app_guid",
"app_instance_index:4",
"app_instance_guid:0123456789012345678",
"app_guid:random_app_guid",
"app_id:random_app_guid",
"app_name:name_of_the_app",
"org_id:random_org_guid",
"org_name:name_of_the_org",
"space_id:random_space_guid",
"space_name:name_of_the_space",
},
}
tags, err := c.GetTagsForNode("cell123")
Expand All @@ -78,10 +83,15 @@ func TestBBSCache_GetTagsForNode(t *testing.T) {
expectedTags = map[string][]string{
"0123456789012345679": {
"container_name:name_of_the_app_3",
"app_name:name_of_the_app",
"app_guid:random_app_guid",
"app_instance_index:3",
"app_instance_guid:0123456789012345679",
"app_guid:random_app_guid",
"app_id:random_app_guid",
"app_name:name_of_the_app",
"org_id:random_org_guid",
"org_name:name_of_the_org",
"space_id:random_space_guid",
"space_name:name_of_the_space",
},
}
tags, err = c.GetTagsForNode("cell1234")
Expand Down
15 changes: 15 additions & 0 deletions pkg/util/cloudfoundry/garden.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@ const (
AppInstanceIndexTagKey = "app_instance_index"
// AppGUIDTagKey tag key for container tags
AppGUIDTagKey = "app_guid"
// AppIDTagKey tag key for container tags. We carry both app_guid and app_id; this is because
// we added app_guid initially here, but then we added space_id and org_id that have just "_id"
// to be consistent with https://github.com/DataDog/datadog-firehose-nozzle; therefore we now
// also include "app_id" to have a consistent set of tags that end with "_id".
AppIDTagKey = "app_id"
// OrgIDTagKey tag key for container tags
// NOTE: we use "org_*" instead of "organization_* to have the tags consistent with
// tags attached by https://github.com/DataDog/datadog-firehose-nozzle
OrgIDTagKey = "org_id"
// OrgNameTagKey tag key for container tags
OrgNameTagKey = "org_name"
// SpaceIDTagKey tag key for container tags
SpaceIDTagKey = "space_id"
// SpaceNameTagKey tag key for container tags
SpaceNameTagKey = "space_name"
)

var (
Expand Down
65 changes: 56 additions & 9 deletions pkg/util/cloudfoundry/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package cloudfoundry
import (
"encoding/json"
"fmt"
"sort"

"github.com/DataDog/datadog-agent/pkg/util/log"

Expand All @@ -29,10 +30,20 @@ const (
ApplicationNameKey = "application_name"
// ApplicationIDKey is the name of the key containing the app GUID in the env var VCAP_APPLICATION
ApplicationIDKey = "application_id"
// SpaceNameKey is the name of the key containing the space name in the env var VCAP_APPLICATION
SpaceNameKey = "space_name"
// SpaceIDKey is the name of the key containing the space GUID in the env var VCAP_APPLICATION
SpaceIDKey = "space_id"
// OrganizationNameKey is the name of the key containing the organization name in the env var VCAP_APPLICATION
OrganizationNameKey = "organization_name"
// OrganizationIDKey is the name of the key containing the organization GUID in the env var VCAP_APPLICATION
OrganizationIDKey = "organization_id"
)

var (
envVcapApplicationKeys = []string{ApplicationNameKey, ApplicationIDKey}
envVcapApplicationKeys = []string{
ApplicationNameKey, ApplicationIDKey, OrganizationNameKey, OrganizationIDKey, SpaceNameKey, SpaceIDKey,
}
)

// ADConfig represents the structure of ADConfig in AD_DATADOGHQ_COM environment variable
Expand Down Expand Up @@ -102,7 +113,11 @@ type DesiredLRP struct {
EnvAD ADConfig
EnvVcapServices map[string][]byte
EnvVcapApplication map[string]string
OrganizationGUID string
OrganizationName string
ProcessGUID string
SpaceGUID string
SpaceName string
}

// ActualLRPFromBBSModel creates a new ActualLRP from BBS's ActualLRP model
Expand Down Expand Up @@ -182,25 +197,57 @@ func DesiredLRPFromBBSModel(bbsLRP *models.DesiredLRP) DesiredLRP {
break
}
}
appGUID, ok := envVA[ApplicationIDKey]
if !ok || appGUID == "" {
log.Errorf("Couldn't extract app GUID from LRP %s", bbsLRP.ProcessGuid)
extractVA := map[string]string{
ApplicationIDKey: "",
ApplicationNameKey: "",
OrganizationIDKey: "",
OrganizationNameKey: "",
SpaceIDKey: "",
SpaceNameKey: "",
}
appName, ok := envVA[ApplicationNameKey]
if !ok || appName == "" {
log.Errorf("Couldn't extract app name from LRP %s", bbsLRP.ProcessGuid)
for key := range extractVA {
ok := false
extractVA[key], ok = envVA[key]
if !ok || extractVA[key] == "" {
log.Errorf("Couldn't extract %s from LRP %s", key, bbsLRP.ProcessGuid)
}
}
d := DesiredLRP{
AppGUID: appGUID,
AppName: appName,
AppGUID: extractVA[ApplicationIDKey],
AppName: extractVA[ApplicationNameKey],
EnvAD: envAD,
EnvVcapServices: envVS,
EnvVcapApplication: envVA,
OrganizationGUID: extractVA[OrganizationIDKey],
OrganizationName: extractVA[OrganizationNameKey],
ProcessGUID: bbsLRP.ProcessGuid,
SpaceGUID: extractVA[SpaceIDKey],
SpaceName: extractVA[SpaceNameKey],
}
return d
}

// GetTagsFromDLRP returns a set of tags extracted from DLRP - names and guids for app, space and org
func (dlrp *DesiredLRP) GetTagsFromDLRP() []string {
tagsToValues := map[string]string{
AppNameTagKey: dlrp.AppName,
AppIDTagKey: dlrp.AppGUID,
AppGUIDTagKey: dlrp.AppGUID,
OrgNameTagKey: dlrp.OrganizationName,
OrgIDTagKey: dlrp.OrganizationGUID,
SpaceNameKey: dlrp.SpaceName,
SpaceIDTagKey: dlrp.SpaceGUID,
}
tags := []string{}
for k, v := range tagsToValues {
if v != "" {
tags = append(tags, fmt.Sprintf("%s:%s", k, v))
}
}
sort.Strings(tags)
return tags
}

func getVcapServicesMap(vcap, processGUID string) (map[string][]byte, error) {
// VCAP_SERVICES maps broker names to lists of service instances
// e.g. {"broker": [{"name": "my-service-1", ...}, ...], ...}
Expand Down
25 changes: 18 additions & 7 deletions pkg/util/cloudfoundry/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ var BBSModelD1 = models.DesiredLRP{
},
{
Name: "VCAP_APPLICATION",
Value: "{\"application_name\": \"name_of_the_app\", \"application_id\": \"random_app_guid\"}",
Value: "{\"application_name\": \"name_of_the_app\", \"application_id\": \"random_app_guid\", \"space_name\": \"name_of_the_space\", \"space_id\": \"random_space_guid\", \"organization_name\": \"name_of_the_org\", \"organization_id\": \"random_org_guid\"}",
},
},
},
Expand All @@ -117,12 +117,23 @@ var BBSModelD1 = models.DesiredLRP{
}

var ExpectedD1 = DesiredLRP{
AppGUID: "random_app_guid",
AppName: "name_of_the_app",
EnvAD: ADConfig{"xxx": {}},
EnvVcapServices: map[string][]byte{"xxx": []byte("{\"name\":\"xxx\"}")},
EnvVcapApplication: map[string]string{"application_name": "name_of_the_app", "application_id": "random_app_guid"},
ProcessGUID: "0123456789012345678901234567890123456789",
AppGUID: "random_app_guid",
AppName: "name_of_the_app",
EnvAD: ADConfig{"xxx": {}},
EnvVcapServices: map[string][]byte{"xxx": []byte("{\"name\":\"xxx\"}")},
EnvVcapApplication: map[string]string{
"application_name": "name_of_the_app",
"application_id": "random_app_guid",
"organization_name": "name_of_the_org",
"organization_id": "random_org_guid",
"space_name": "name_of_the_space",
"space_id": "random_space_guid",
},
OrganizationGUID: "random_org_guid",
OrganizationName: "name_of_the_org",
ProcessGUID: "0123456789012345678901234567890123456789",
SpaceGUID: "random_space_guid",
SpaceName: "name_of_the_space",
}

func TestADIdentifier(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
enhancements:
- |
Add `space_id`, `space_name`, `org_id` and `org_name` as tags to both autodiscovered containers as well as checks found through autodiscovery on Cloud Foundry/Tanzu.

0 comments on commit 951a737

Please sign in to comment.