diff --git a/agent-control/agent-type-registry/newrelic/com.newrelic.opentelemetry.collector-0.1.0.yaml b/agent-control/agent-type-registry/newrelic/com.newrelic.opentelemetry.collector-0.1.0.yaml new file mode 100644 index 0000000000..d4fa1694ce --- /dev/null +++ b/agent-control/agent-type-registry/newrelic/com.newrelic.opentelemetry.collector-0.1.0.yaml @@ -0,0 +1,177 @@ +namespace: newrelic +name: com.newrelic.opentelemetry.collector +version: 0.1.0 +variables: + on_host: + config: + description: "Newrelic otel collector configuration" + type: yaml + required: false + default: {} + backoff_delay: + description: "seconds until next retry if agent fails to start" + type: string + required: false + default: 20s + health_check: + # Note the configs added here must align with the health check extension being used on the collector config variable. + # See https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/extension/healthcheckv2extension/README.md#configuration + # For more details + path: + description: "path to health check endpoint" + type: string + required: false + default: "/health/status" # Taken from example at: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/extension/healthcheckv2extension/README.md#configuration + port: + description: "port to health check endpoint" + type: number + required: false + default: 13133 + k8s: + chart_values: + nr-k8s-otel-collector: + description: "Newrelic otel collector chart values" + type: yaml + required: false + default: {} + global: + description: "Global values for the chart" + type: yaml + required: false + default: {} + chart_version: + description: "Newrelic otel collector chart version" + type: string + required: true + chart_name: + description: "nr-k8s-otel-collector chart name" + type: string + required: false + default: "nr-k8s-otel-collector" + chart_repository: + url: + description: "chart repository url" + type: string + required: false + default: "https://helm-charts.newrelic.com" + variants: + ac_config_field: "chart_repository_urls" + values: ["https://helm-charts.newrelic.com"] + secret_reference: + description: "HelmRepository secret reference (secretRef)" + type: yaml + required: false + default: null + certificate_secret_reference: + description: "HelmRepository certificate secret reference (certSecretRef)" + type: yaml + required: false + default: null +deployment: + on_host: + health: + interval: 5s + initial_delay: 5s + timeout: 5s + http: + path: "${nr-var:health_check.path}" + port: ${nr-var:health_check.port} + version: + path: /usr/bin/nrdot-collector-host + args: -v + regex: \d+\.\d+\.\d+ + filesystem: + otel-config: + config.yaml: | + ${nr-var:config} + executables: + - # Important to note the binary name is nrdot-collector-host matching the new nrdot binary + id: nrdot-collector-host + path: /usr/bin/nrdot-collector-host + args: >- + --config=${nr-sub:autogenerated_agent_dir}/otel-config/config.yaml + --feature-gates=-pkg.translator.prometheus.NormalizeName + env: + # sets the otel-collector "env" source resource detector + OTEL_RESOURCE_ATTRIBUTES: "host.id=${nr-ac:host_id}" + restart_policy: + backoff_strategy: + type: fixed + backoff_delay: ${nr-var:backoff_delay} + # See com.newrelic.infrastructure Agent type for description of fields. + k8s: + health: + interval: 30s + initial_delay: 30s + objects: + repository: + apiVersion: source.toolkit.fluxcd.io/v1 + kind: HelmRepository + metadata: + name: ${nr-sub:agent_id} + namespace: ${nr-ac:namespace} + spec: + interval: 30m + provider: generic + url: ${nr-var:chart_repository.url} + secretRef: ${nr-var:chart_repository.secret_reference} + certSecretRef: ${nr-var:chart_repository.certificate_secret_reference} + values: + apiVersion: v1 + kind: Secret + metadata: + name: values-${nr-sub:agent_id} + namespace: ${nr-ac:namespace} + stringData: + default.yaml: | + global: + licenseKey: ${nr-env:NR_LICENSE_KEY} + cluster: ${nr-env:NR_CLUSTER_NAME} + nrStaging: ${nr-env:NR_STAGING} + lowDataMode: ${nr-env:NR_LOW_DATA_MODE} + verboseLog: ${nr-env:NR_VERBOSE_LOG} + values.yaml: | + ${nr-var:chart_values.nr-k8s-otel-collector} + global.yaml: | + global: + ${nr-var:chart_values.global | indent 2} + release: + apiVersion: helm.toolkit.fluxcd.io/v2 + kind: HelmRelease + metadata: + name: ${nr-sub:agent_id} + namespace: ${nr-ac:namespace} + spec: + targetNamespace: ${nr-ac:namespace_agents} + releaseName: ${nr-sub:agent_id} + interval: 30s + chart: + spec: + chart: ${nr-var:chart_name} + version: ${nr-var:chart_version} + reconcileStrategy: ChartVersion + sourceRef: + kind: HelmRepository + name: ${nr-sub:agent_id} + namespace: ${nr-ac:namespace} + interval: 3m + install: + disableWait: true + disableWaitForJobs: true + disableTakeOwnership: true + createNamespace: true + upgrade: + disableWait: true + disableWaitForJobs: true + disableTakeOwnership: true + cleanupOnFail: true + valuesFrom: + - kind: Secret + name: values-${nr-sub:agent_id} + valuesKey: default.yaml + - kind: Secret + name: values-${nr-sub:agent_id} + valuesKey: values.yaml + - kind: Secret + name: values-${nr-sub:agent_id} + valuesKey: global.yaml diff --git a/agent-control/agent-type-registry/newrelic/io.opentelemetry.collector-0.1.0.yaml b/agent-control/agent-type-registry/newrelic/io.opentelemetry.collector-0.1.0.yaml index d763dd13bc..db04166e07 100644 --- a/agent-control/agent-type-registry/newrelic/io.opentelemetry.collector-0.1.0.yaml +++ b/agent-control/agent-type-registry/newrelic/io.opentelemetry.collector-0.1.0.yaml @@ -1,3 +1,6 @@ +# This is the same agent type as `com.newrelic.opentelemetry.collector`, kept in the repository +# for compatibility with existing deployments and Fleet Control support. +# It should not drift from the `com.newrelic.opentelemetry.collector` definition! namespace: newrelic name: io.opentelemetry.collector version: 0.1.0 diff --git a/agent-control/src/agent_control/config.rs b/agent-control/src/agent_control/config.rs index 28b66507e8..5ec4144670 100644 --- a/agent-control/src/agent_control/config.rs +++ b/agent-control/src/agent_control/config.rs @@ -679,13 +679,17 @@ k8s: AgentTypeID::try_from("newrelic/com.newrelic.infrastructure:0.0.1").unwrap(), }, ))); - assert!(diff.contains(&( - &AgentID::try_from("nrdot").unwrap(), - &SubAgentConfig { - agent_type: - AgentTypeID::try_from("newrelic/io.opentelemetry.collector:0.0.1").unwrap(), - }, - ))); + assert!( + diff.contains(&( + &AgentID::try_from("nrdot").unwrap(), + &SubAgentConfig { + agent_type: AgentTypeID::try_from( + "newrelic/com.newrelic.opentelemetry.collector:0.0.1" + ) + .unwrap(), + }, + )) + ); } #[test] @@ -723,7 +727,7 @@ k8s: pub fn nrdot_identity() -> AgentIdentity { let id = AgentID::try_from("nrdot").unwrap(); let agent_type_id = - AgentTypeID::try_from("newrelic/io.opentelemetry.collector:0.0.1").unwrap(); + AgentTypeID::try_from("newrelic/com.newrelic.opentelemetry.collector:0.0.1").unwrap(); AgentIdentity { id, agent_type_id } } diff --git a/agent-control/src/agent_control/defaults.rs b/agent-control/src/agent_control/defaults.rs index 6a27152d12..d96e6c4f0b 100644 --- a/agent-control/src/agent_control/defaults.rs +++ b/agent-control/src/agent_control/defaults.rs @@ -85,7 +85,7 @@ pub(crate) fn get_custom_capabilities(agent_type_id: &AgentTypeID) -> Option = }); static AGENT_TYPE_OTEL_COLLECTOR: LazyLock = + LazyLock::new(|| AgentTypeValuesTestCase { + agent_type: "newrelic/com.newrelic.opentelemetry.collector:0.1.0", + values_k8s: AgentTypeValues { + cases: HashMap::from([ + ("mandatory fields only", r#"chart_version: "some-version""#), + ( + "check all value types are correct", + r#" + chart_version: "some-version" + chart_values.nr-k8s-otel-collector: + yaml: object + chart_values.global: + yaml: object + "#, + ), + ]), + additional_env: HashMap::from([ + ( + Namespace::EnvironmentVariable.namespaced_name("NR_LICENSE_KEY"), + Variable::new_final_string_variable("abcd1234".to_string()), + ), + ( + Namespace::EnvironmentVariable.namespaced_name("NR_CLUSTER_NAME"), + Variable::new_final_string_variable("my-test-cluster".to_string()), + ), + ( + Namespace::EnvironmentVariable.namespaced_name("NR_STAGING"), + Variable::new_final_string_variable("true".to_string()), + ), + ( + Namespace::EnvironmentVariable.namespaced_name("NR_LOW_DATA_MODE"), + Variable::new_final_string_variable("true".to_string()), + ), + ( + Namespace::EnvironmentVariable.namespaced_name("NR_VERBOSE_LOG"), + Variable::new_final_string_variable("true".to_string()), + ), + ]), + } + .into(), + values_onhost: AgentTypeValues { + cases: HashMap::from([ + ("mandatory fields only", ""), + ( + "check all value types are correct", + r#" + config: "some file contents" + backoff_delay: "10s" + health_check.path: "/health" + health_check.port: 12345 + "#, + ), + ]), + ..Default::default() + } + .into(), + }); + +static AGENT_TYPE_OTEL_COLLECTOR_OLD: LazyLock = LazyLock::new(|| AgentTypeValuesTestCase { agent_type: "newrelic/io.opentelemetry.collector:0.1.0", values_k8s: AgentTypeValues { @@ -507,6 +566,7 @@ fn get_agent_type_test_cases() -> impl Iterator(agents_cfg).unwrap(), diff --git a/build/examples/agent-control-config-all-agents.yaml b/build/examples/agent-control-config-all-agents.yaml index ac699766e7..9e5ee966e3 100644 --- a/build/examples/agent-control-config-all-agents.yaml +++ b/build/examples/agent-control-config-all-agents.yaml @@ -11,8 +11,6 @@ # provider: PLACEHOLDER # private_key_path: PLACEHOLDER - - server: enabled: true @@ -20,4 +18,4 @@ agents: nr-infra: agent_type: "newrelic/com.newrelic.infrastructure:0.1.0" nrdot: - agent_type: "newrelic/io.opentelemetry.collector:0.1.0" + agent_type: "newrelic/com.newrelic.opentelemetry.collector:0.1.0" diff --git a/build/examples/agent-control-config-nr-otel-collector.yaml b/build/examples/agent-control-config-nr-otel-collector.yaml index 70f2cdddc0..3359b01c17 100644 --- a/build/examples/agent-control-config-nr-otel-collector.yaml +++ b/build/examples/agent-control-config-nr-otel-collector.yaml @@ -16,4 +16,4 @@ server: agents: nrdot: - agent_type: "newrelic/io.opentelemetry.collector:0.1.0" + agent_type: "newrelic/com.newrelic.opentelemetry.collector:0.1.0" diff --git a/docs/CONFIG.md b/docs/CONFIG.md index c42a702fc8..0db355fde3 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -21,7 +21,7 @@ Example: ```yaml agents: - nrdot: "newrelic/io.opentelemetry.collector:0.1.0" + nrdot: "newrelic/com.newrelic.opentelemetry.collector:0.1.0" ``` ### logs @@ -83,7 +83,6 @@ proxy: Configuring a proxy in Agent Control does not automatically configure the same proxy settings for the agents it manages. Each agent has its own proxy configuration that must be set separately according to that agent's specific configuration format and requirements. - ### server Agent Control status server allows consulting the status of Agent Control and any controlled agent. It can be configured as follows: diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 7465c92513..3a8413291e 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -37,7 +37,7 @@ To compile and run locally: api-key: YOUR_INGEST_KEY agents: nr-otel-collector: - agent_type: "newrelic/io.opentelemetry.collector:0.1.0" + agent_type: "newrelic/com.newrelic.opentelemetry.collector:0.1.0" ``` 7. Place values files in the folder `/etc/newrelic-agent-control/fleet/agents.d/{AGENT-ID}/` where `AGENT-ID` is a key in the @@ -194,7 +194,7 @@ There is a service that ultimately exposes a `/status` endpoint for Agent Contro "sub_agents": { "nr-otel-collector": { "agent_id": "nr-otel-collector", - "agent_type": "newrelic/io.opentelemetry.collector:0.1.0", + "agent_type": "newrelic/com.newrelic.opentelemetry.collector:0.1.0", "healthy": true }, "nr-infra-agent": { diff --git a/test/k8s-e2e/collector/ac-values-collector.yml b/test/k8s-e2e/collector/ac-values-collector.yml index fd56d27b2b..3282ee015c 100644 --- a/test/k8s-e2e/collector/ac-values-collector.yml +++ b/test/k8s-e2e/collector/ac-values-collector.yml @@ -13,7 +13,7 @@ agentControlDeployment: enabled: false agents: open-telemetry: - agent_type: newrelic/io.opentelemetry.collector:0.1.0 + agent_type: newrelic/com.newrelic.opentelemetry.collector:0.1.0 agentsConfig: open-telemetry: