Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ROX-26516: Collector reads runtime config from configmap #1878

Merged
merged 16 commits into from
Oct 9, 2024

Conversation

JoukoVirtanen
Copy link
Contributor

@JoukoVirtanen JoukoVirtanen commented Oct 5, 2024

Description

Makes it so that the runtime config can be read from a ConfigMap. The ConfigMap is added to collector here stackrox/stackrox#12910. The ConfigMap is optional and is not needed in order for collector to run. For now the runtime config only enables or disables the external IPs feature. If the ConfigMap is not used the external IPs feature will be controlled by an environment variable.

Json is used for the configuration. This is convenient, because there is a method for converting Json strings to protobuf objects. YAML was considered, but having the ConfigMap use Json makes it easy to copy the ConfigMap into the API, and use it there. Also using a library for YAML, proved to be a pain.

Checklist

  • Investigated and inspected CI test results
  • Updated documentation accordingly

Automated testing

  • Added unit tests
  • Added integration tests
  • Added regression tests

If any of these don't apply, please comment below.

Testing Performed

Testing was performed using stackrox/stackrox#12910 which adds the ConfigMap to collector.

Created the following yaml file for a ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: collector-config
  namespace: stackrox
data:
  runtime_config.yaml: |
    networkConnectionConfig:
        enableExternalIps: true

Saved the contents in config-map.yml.

Ran

kubectl create -f config-map.yml

Deployed ACS on a GKE infra cluster using deploy/deploy-local.sh.

Set the collector image to one from this PR using ks edit ds collector.

The collector logs were checked and the following was found

[INFO    2024/10/08 20:46:11] Runtime configuration: network_connection_config {
  enable_external_ips: true
}

enableExternalIps false

The configmap was changed to

apiVersion: v1
kind: ConfigMap
metadata:
  name: collector-config
  namespace: stackrox
data:
  runtime_config.yaml: |
    networkConnectionConfig:
        enableExternalIps: false

Collector pods were deleted and allowed to come back up

ks delete pod -l app=collector
[INFO    2024/10/08 20:52:24] Runtime configuration: network_connection_config {
}

Invalid config

The configmap was changed to the following

apiVersion: v1
data:
  runtime_config.yaml: |
    networkConnectionConfig:
        enableExternalIps: asdf
kind: ConfigMap
metadata:
  creationTimestamp: "2024-10-08T20:51:09Z"
  name: collector-config
  namespace: stackrox
  resourceVersion: "1587598"
  uid: 7594e306-7334-42b5-b439-ed04ae88ffed

The collector log had the following

[INFO    2024/10/08 20:52:24] Runtime configuration: network_connection_config {
}

This is the expected result.

No config map

The configmap was deleted and collector was restarted. The following was found in the collector log.

There was nothing in the collector logs.

Different config path

The configmap was changed to the following

apiVersion: v1
data:
  collector.yaml: |
    networkConnectionConfig:
        enableExternalIps: true
kind: ConfigMap
metadata:
  creationTimestamp: "2024-10-08T21:00:49Z"
  name: collector-config
  namespace: stackrox
  resourceVersion: "1593991"
  uid: 829de9f9-0f19-4457-927d-b3ea33b8f38f

The following were added to the env section of collector

        - name: ROX_COLLECTOR_CONFIG_PATH
          value: /etc/stackrox/collector.yaml

The following was in the collector log

[INFO    2024/10/08 21:05:08] Runtime configuration: network_connection_config {
  enable_external_ips: true
}

@JoukoVirtanen JoukoVirtanen marked this pull request as ready for review October 5, 2024 23:16
@JoukoVirtanen JoukoVirtanen requested a review from a team as a code owner October 5, 2024 23:16
@JoukoVirtanen JoukoVirtanen changed the title Jv read config map ROX-26516: Collector reads runtime config from configmap Oct 5, 2024
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@Molter73 Molter73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, but I still have some comments before I'm ready to approve.

collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
collector/lib/CollectorConfig.h Outdated Show resolved Hide resolved
collector/test/CollectorConfigTest.cpp Outdated Show resolved Hide resolved
Comment on lines 154 to 203
TEST(CollectorConfigTest, TestConfigMapTrue) {
std::string jsonStr = R"({
"networkConnectionConfig": {
"enableExternalIps": true
}
})";

MockCollectorConfig config;
config.MockHandleConfigMapString(jsonStr);

EXPECT_TRUE(config.EnableExternalIPs());
}

TEST(CollectorConfigTest, TestConfigMapFalse) {
std::string jsonStr = R"({
"networkConnectionConfig": {
"enableExternalIps": false
}
})";

MockCollectorConfig config;
config.MockHandleConfigMapString(jsonStr);

EXPECT_FALSE(config.EnableExternalIPs());
}

TEST(CollectorConfigTest, TestConfigMapEmpty) {
std::string jsonStr = R"({
"networkConnectionConfig": {
}
})";

MockCollectorConfig config;
config.MockHandleConfigMapString(jsonStr);

EXPECT_FALSE(config.EnableExternalIPs());
}

TEST(CollectorConfigTest, TestConfigMapInvalid) {
std::string jsonStr = R"({
"networkConnectionConfig": {
}
)";

MockCollectorConfig config;
config.MockHandleConfigMapString(jsonStr);

EXPECT_FALSE(config.EnableExternalIPs());
}

Copy link
Collaborator

@Molter73 Molter73 Oct 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably rewrite all of these as a single test with something like:

TEST(CollectorConfigTest, TestConfigurationFile) {
  std::vector<std::pair<std::string, bool>> tests = {
    { R"({
       "networkConnectionConfig": {
         "enableExternalIps": true
       }
     })", true },
    { R"({
           "networkConnectionConfig": {
             "enableExternalIps": false
           }
         })", false },
    // ...
  };
  
  for (const auto& [input, expected] : tests) {
    CollectorConfig config;
    config.HandleConfigMapString(input);
    EXPECT_EQUAL(config.EnableExternalIPs(), expected);
  }
}

Since the test is concise (literally 3 lines in a loop), the result should overall have less bloat and make it easier to understand what is being tested.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are also missing a test for an empty string as input.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 156 to 157
"networkConnectionConfig": {
"enableExternalIps": true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also now realize the only place I can actually check what the configuration is going to look like is these tests, which is not great, we need a way to have a formal specification of the configuration that we can properly review, but for now I guess it's fine 🤷🏻‍♂️ .

I do have some objections though:

  • networkConnectionConfig is redundant, we know this is a configuration parameter, so it should be networkConnection.
  • enableExternalIps is not extensible.

I would prefer the configuration to look something closer to this:

networkConnection:
  externalIPs:
    enable: true

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to change these, we need to change the protobuf definitions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not? Is not like the feature is GA.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't say that we couldn't change the protobuf definitions.

JoukoVirtanen and others added 4 commits October 7, 2024 08:26
Co-authored-by: Mauro Ezequiel Moltrasio <mmoltras@redhat.com>
Co-authored-by: Mauro Ezequiel Moltrasio <mmoltras@redhat.com>
Co-authored-by: Simon Bäumer <baeumer@pm.me>
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
collector/test/CollectorConfigTest.cpp Show resolved Hide resolved
collector/test/CollectorConfigTest.cpp Outdated Show resolved Hide resolved
collector/test/CollectorConfigTest.cpp Show resolved Hide resolved
collector/test/CollectorConfigTest.cpp Outdated Show resolved Hide resolved
collector/lib/CollectorConfig.cpp Outdated Show resolved Hide resolved
Molter73 and others added 3 commits October 8, 2024 17:15
Co-authored-by: Olivier Valentin <ovalenti@redhat.com>
Co-authored-by: Mauro Ezequiel Moltrasio <mmoltras@redhat.com>
Copy link
Contributor

@ovalenti ovalenti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The multi-threaded angle.

collector/lib/CollectorConfig.cpp Show resolved Hide resolved
Copy link
Collaborator

@Molter73 Molter73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

collector/test/CollectorConfigTest.cpp Show resolved Hide resolved
Comment on lines 185 to 187
EXPECT_TRUE(runtime_config.has_value());

if (runtime_config.has_value()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need the if, you already expected runtime_config.has_value() to be true.

Suggested change
EXPECT_TRUE(runtime_config.has_value());
if (runtime_config.has_value()) {
EXPECT_TRUE(runtime_config.has_value());

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -104,6 +106,35 @@ seconds. The default value is 30 seconds.

* `logLevel`: Sets logging level. The default is INFO.

### File mount or ConfigMap
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to document it!

@JoukoVirtanen JoukoVirtanen merged commit d108359 into master Oct 9, 2024
69 of 70 checks passed
@JoukoVirtanen JoukoVirtanen deleted the jv-read-config-map branch October 9, 2024 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants