Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions src/core/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ func GetConfig(clientId string) (*Config, error) {
Nginx: getNginx(),
Dataplane: getDataplane(),
AgentMetrics: getMetrics(),
Features: Viper.GetStringSlice(FeaturesKey),
Tags: Viper.GetStringSlice(TagsKey),
Updated: filePathUTime(Viper.GetString(DynamicConfigPathKey)),
AllowedDirectoriesMap: map[string]struct{}{},
Expand All @@ -185,30 +186,47 @@ func GetConfig(clientId string) (*Config, error) {
return config, nil
}

// UpdateAgentConfig updates the Agent config on disk with the tags that are
// UpdateAgentConfig updates the Agent config on disk with the tags and features that are
// passed into it. A bool is returned indicating if the Agent config was
// overwritten or not.
func UpdateAgentConfig(systemId string, updateTags []string) (bool, error) {
func UpdateAgentConfig(systemId string, updateTags []string, updateFeatures []string) (bool, error) {
// Get current config on disk
config, err := GetConfig(systemId)
if err != nil {
log.Errorf("Failed to register config: %v", err)
return false, err
}

// Update nil valued updateTags to empty slice for comparison
if updateTags == nil {
updateTags = []string{}
}

if updateFeatures == nil {
updateFeatures = []string{}
}

// Sort tags and compare them
sort.Strings(updateTags)
sort.Strings(config.Tags)
synchronizedTags := reflect.DeepEqual(updateTags, config.Tags)
// If the tags are already synchronized there is no need to overwrite
if synchronizedTags {
log.Debug("Manager tags and local tags are already synced")
return false, nil
}

Viper.Set(TagsKey, updateTags)
config.Tags = Viper.GetStringSlice(TagsKey)

sort.Strings(updateFeatures)
sort.Strings(config.Features)
synchronizedFeatures := reflect.DeepEqual(updateFeatures, config.Features)

Viper.Set(FeaturesKey, updateFeatures)
config.Features = Viper.GetStringSlice(FeaturesKey)

// If the features are already synchronized there is no need to overwrite
if synchronizedTags && synchronizedFeatures {
log.Debug("Manager and Local tags and features are already synchronized")
return false, nil
}

// Get the dynamic config path and use default dynamic config path if it's not
// already set.
dynamicCfgPath := Viper.GetString(DynamicConfigPathKey)
Expand Down
65 changes: 47 additions & 18 deletions src/core/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,37 +376,61 @@ func TestUpdateAgentConfig(t *testing.T) {
}

testCases := []struct {
testName string
updatedConfTags []string
expConfTags []string
updatedTags bool
testName string
updatedConfTags []string
updatedConfFeatures []string
expConfTags []string
expConfFeatures []string
updatedConf bool
}{
{
testName: "NoTagsToUpdate",
updatedConfTags: curConf.Tags,
expConfTags: curConf.Tags,
updatedTags: false,
testName: "NoFieldsInConfToUpdate",
updatedConfTags: curConf.Tags,
updatedConfFeatures: curConf.Features,
expConfTags: curConf.Tags,
expConfFeatures: curConf.Features,
updatedConf: false,
},
{
testName: "UpdatedTags",
updatedConfTags: []string{"new-tag1:One", "new-tag2:Two"},
expConfTags: []string{"new-tag1:One", "new-tag2:Two"},
updatedTags: true,
testName: "UpdatedTags",
updatedConfTags: []string{"new-tag1:One", "new-tag2:Two"},
updatedConfFeatures: curConf.Features,
expConfTags: []string{"new-tag1:One", "new-tag2:Two"},
expConfFeatures: curConf.Features,
updatedConf: true,
},
{
testName: "RemoveAllTags",
updatedConfTags: []string{},
expConfTags: []string{},
updatedTags: true,
testName: "RemoveAllTags",
updatedConfTags: []string{},
updatedConfFeatures: curConf.Features,
expConfTags: []string{},
expConfFeatures: curConf.Features,
updatedConf: true,
},
{
testName: "UpdateFeatures",
updatedConfTags: curConf.Tags,
updatedConfFeatures: []string{"registration", "nginx-config", "metrics"},
expConfTags: curConf.Tags,
expConfFeatures: []string{"registration", "nginx-config", "metrics"},
updatedConf: true,
},
{
testName: "RemoveAllFeatures",
updatedConfTags: curConf.Tags,
updatedConfFeatures: []string{},
expConfTags: curConf.Tags,
expConfFeatures: []string{},
updatedConf: true,
},
}

for _, tc := range testCases {
t.Run(tc.testName, func(t *testing.T) {
// Attempt update & check results
updated, err := UpdateAgentConfig("12345", tc.updatedConfTags)
updated, err := UpdateAgentConfig("12345", tc.updatedConfTags, tc.updatedConfFeatures)
assert.NoError(t, err)
assert.Equal(t, updated, tc.updatedTags)
assert.Equal(t, updated, tc.updatedConf)

// Get potentially updated config
updatedConf, err := GetConfig("12345")
Expand All @@ -421,6 +445,11 @@ func TestUpdateAgentConfig(t *testing.T) {
equalTags := reflect.DeepEqual(tc.expConfTags, updatedConf.Tags)

assert.Equal(t, equalTags, true)
// Sort features before asserting
sort.Strings(tc.expConfFeatures)
sort.Strings(updatedConf.Features)
equalFeatures := reflect.DeepEqual(tc.expConfFeatures, updatedConf.Features)
assert.Equal(t, equalFeatures, true)
})
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/core/config/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const (
InstanceGroupKey = "instance_group"
ConfigDirsKey = "config_dirs"
TagsKey = "tags"
FeaturesKey = "features"

// viper keys used in config
LogKey = "log"
Expand Down Expand Up @@ -221,6 +222,10 @@ var (
Name: TagsKey,
Usage: "A comma-separated list of tags to add to the current instance or machine, to be used for inventory purposes.",
},
&StringSliceFlag{
Name: FeaturesKey,
Usage: "A comma-separated list of features enabled for the agent.",
},
// NGINX Config
&StringFlag{
Name: NginxExcludeLogs,
Expand Down
1 change: 1 addition & 0 deletions src/core/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Config struct {
Dataplane Dataplane `mapstructure:"dataplane" yaml:"-"`
AgentMetrics AgentMetrics `mapstructure:"metrics" yaml:"-"`
Tags []string `mapstructure:"tags" yaml:"tags,omitempty"`
Features []string `mapstructure:"features" yaml:"features,omitempty"`
Updated time.Time `yaml:"-"` // update time of the config file
AllowedDirectoriesMap map[string]struct{} `yaml:"-"`
DisplayName string `mapstructure:"display_name" yaml:"display_name,omitempty"`
Expand Down
25 changes: 19 additions & 6 deletions src/core/nginx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"

Expand Down Expand Up @@ -69,8 +70,7 @@ func TestGetNginxInfoFromBuffer(t *testing.T) {
built by clang 12.0.0 (clang-1200.0.32.29)
built with OpenSSL 1.1.1k 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/nginx/1.19.10 --modules-path=/usr/sbin/nginx/modules --sbin-path=/usr/local/Cellar/nginx/1.19.10/bin/nginx --with-cc-opt='-I/usr/local/opt/pcre/include -I/usr/local/opt/openssl@1.1/include' --with-ld-opt='-L/usr/local/opt/pcre/lib -L/usr/local/opt/openssl@1.1/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-body-temp-path=/usr/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/usr/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/usr/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/usr/local/var/run/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/var/run/nginx/scgi_temp --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log --with-compat --with-debug --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-ipv6 --with-mail --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module`,
expectedNginxInfo: &nginxInfo{
configure arguments: --prefix=/usr/local/Cellar/nginx/1.19.10 --modules-path=/tmp/modules --sbin-path=/usr/local/Cellar/nginx/1.19.10/bin/nginx --with-cc-opt='-I/usr/local/opt/pcre/include -I/usr/local/opt/openssl@1.1/include' --with-ld-opt='-L/usr/local/opt/pcre/lib -L/usr/local/opt/openssl@1.1/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-body-temp-path=/usr/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/usr/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/usr/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/usr/local/var/run/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/var/run/nginx/scgi_temp --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log --with-compat --with-debug --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-ipv6 --with-mail --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module`, expectedNginxInfo: &nginxInfo{
prefix: "/usr/local/Cellar/nginx/1.19.10",
confPath: "/usr/local/etc/nginx/nginx.conf",
logPath: "/usr/local/var/log/nginx/access.log",
Expand All @@ -86,7 +86,7 @@ func TestGetNginxInfoFromBuffer(t *testing.T) {
cfgf: map[string]interface{}{
"conf-path": "/usr/local/etc/nginx/nginx.conf",
"error-log-path": "/usr/local/var/log/nginx/error.log",
"modules-path": "/usr/sbin/nginx/modules",
"modules-path": "/tmp/modules",
"http-client-body-temp-path": "/usr/local/var/run/nginx/client_body_temp",
"http-fastcgi-temp-path": "/usr/local/var/run/nginx/fastcgi_temp",
"http-log-path": "/usr/local/var/log/nginx/access.log",
Expand Down Expand Up @@ -130,7 +130,7 @@ func TestGetNginxInfoFromBuffer(t *testing.T) {
configureArgs: []string{
"",
"prefix=/usr/local/Cellar/nginx/1.19.10",
"modules-path=/usr/sbin/nginx/modules",
"modules-path=/tmp/modules",
"sbin-path=/usr/local/Cellar/nginx/1.19.10/bin/nginx",
"with-cc-opt='-I/usr/local/opt/pcre/include -I/usr/local/opt/openssl@1.1/include'",
"with-ld-opt='-L/usr/local/opt/pcre/lib -L/usr/local/opt/openssl@1.1/lib'",
Expand Down Expand Up @@ -173,7 +173,7 @@ func TestGetNginxInfoFromBuffer(t *testing.T) {
"with-stream_ssl_preread_module",
},
loadableModules: nil,
modulesPath: "/usr/sbin/nginx/modules",
modulesPath: "/tmp/modules",
},
},
{
Expand Down Expand Up @@ -204,6 +204,19 @@ func TestGetNginxInfoFromBuffer(t *testing.T) {
},
}

err := os.Mkdir("/tmp/modules", 0700)
assert.NoError(t, err)

tempDir := t.TempDir()
mockNginx, err := ioutil.TempFile(tempDir, "mock_nginx_executable")
assert.NoError(t, err)

defer func() {
_ = mockNginx.Close()
_ = os.RemoveAll(mockNginx.Name())
_ = os.RemoveAll("/tmp/modules")
}()

for _, test := range tests {
t.Run(test.name, func(tt *testing.T) {
binary := NginxBinaryType{
Expand All @@ -212,7 +225,7 @@ func TestGetNginxInfoFromBuffer(t *testing.T) {

var buffer bytes.Buffer
buffer.WriteString(test.input)
nginxInfo := binary.getNginxInfoFromBuffer("/usr/sbin/nginx", &buffer)
nginxInfo := binary.getNginxInfoFromBuffer(filepath.Join(tempDir, mockNginx.Name()), &buffer)

assert.Equal(t, test.expectedNginxInfo.cfgf, nginxInfo.cfgf)
assert.Equal(t, test.expectedNginxInfo.confPath, nginxInfo.confPath)
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/commander.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ func (c *Commander) agentRegistered(cmd *proto.Command) {
if agtCfg := commandData.AgentConnectResponse.AgentConfig; agtCfg != nil &&
agtCfg.Configs != nil && len(agtCfg.Configs.Configs) > 0 {

// Update config tags if they were out of sync between Manager and Agent
if agtCfg.Details != nil && len(agtCfg.Details.Tags) > 0 {
configUpdated, err := config.UpdateAgentConfig(c.config.ClientID, agtCfg.Details.Tags)
// Update config tags and features if they were out of sync between Manager and Agent
if agtCfg.Details != nil && (len(agtCfg.Details.Tags) > 0 || len(agtCfg.Details.Features) > 0) {
configUpdated, err := config.UpdateAgentConfig(c.config.ClientID, agtCfg.Details.Tags, agtCfg.Details.Features)
if err != nil {
log.Errorf("Failed updating Agent config - %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/config_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (r *ConfigReader) Subscriptions() []string {
func (r *ConfigReader) updateAgentConfig(cmd *proto.Command) {
switch commandData := cmd.Data.(type) {
case *proto.Command_AgentConfig:
configUpdated, err := config.UpdateAgentConfig(r.config.ClientID, commandData.AgentConfig.Details.Tags)
configUpdated, err := config.UpdateAgentConfig(r.config.ClientID, commandData.AgentConfig.Details.Tags, commandData.AgentConfig.Details.Features)
if err != nil {
log.Errorf("Failed updating Agent config - %v", err)
}
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/config_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ func TestUpdateAgentConfig(t *testing.T) {
Data: &proto.Command_AgentConfig{
AgentConfig: &proto.AgentConfig{
Details: &proto.AgentDetails{
Tags: curConf.Tags,
Tags: curConf.Tags,
Features: curConf.Features,
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/dataplane_status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func TestDPSSyncAgentConfigChange(t *testing.T) {
assert.Equal(t, tc.config.Tags, *dataPlaneStatus.tags)

// Attempt update & check results
updated, err := config.UpdateAgentConfig("12345", tc.expUpdatedConfig.Tags)
updated, err := config.UpdateAgentConfig("12345", tc.expUpdatedConfig.Tags, tc.expUpdatedConfig.Features)
assert.Nil(t, err)
assert.Equal(t, updated, tc.updatedTags)

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func TestMetrics_Process_AgentConfigChanged(t *testing.T) {
assert.Equal(t, tutils.InitialConfTags, metricsPlugin.conf.Tags)

// Attempt update & check results
updated, err := config.UpdateAgentConfig("12345", tc.expUpdatedConfig.Tags)
updated, err := config.UpdateAgentConfig("12345", tc.expUpdatedConfig.Tags, tc.expUpdatedConfig.Features)
assert.Nil(t, err)
assert.Equal(t, updated, tc.updatedTags)

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading