diff --git a/.fixtures.yml b/.fixtures.yml index 6470f44..d50c51e 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -4,3 +4,4 @@ fixtures: forge_modules: stdlib: "puppetlabs/stdlib" + concat: "puppetlabs-concat" diff --git a/REFERENCE.md b/REFERENCE.md index cf083f9..0a290ce 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -16,6 +16,20 @@ * `otelcol::service`: Manages the Otelcol service +### Defined types + +#### Public Defined types + +* [`otelcol::exporter`](#otelcol--exporter): Define a OpenTelemetry Collector exporter +* [`otelcol::extension`](#otelcol--extension): Add an extension to the OpenTelemetry Collector configuration +* [`otelcol::pipeline`](#otelcol--pipeline): Add a pipeline to the OpenTelemetry Collector configuration +* [`otelcol::processor`](#otelcol--processor): Add a processor to the OpenTelemetry Collector configuration +* [`otelcol::receiver`](#otelcol--receiver): Add a receiver to the OpenTelemetry Collector configuration + +#### Private Defined types + +* `otelcol::component`: Define a component for the OpenTelemetry Collector Configuration + ## Classes ### `otelcol` @@ -125,22 +139,11 @@ Default value: `'0644'` ##### `receivers` -Data type: `Hash` +Data type: `Optional[Hash]` Hash for receivers config -Default value: - -```puppet -{ - 'otlp' => { - 'protocols' => { - 'http' => {}, - 'grpc' => {}, - }, - }, - } -``` +Default value: `undef` ##### `processors` @@ -236,7 +239,7 @@ Data type: `String[1]` Version of otelcol that will be used, param is not used if archive_location is set -Default value: `'0.79.0'` +Default value: `'0.89.0'` ##### `archive_location` @@ -267,3 +270,234 @@ Templated generation of otelcol.conf Conditionally handle repos or package paths and install the necessary otelcol package. +## Defined types + +### `otelcol::exporter` + +Create a OpenTelemetry Collector exporter in the configuration file. + +#### Examples + +##### + +```puppet +otelcol::exporter { 'namevar': } +``` + +#### Parameters + +The following parameters are available in the `otelcol::exporter` defined type: + +* [`name`](#-otelcol--exporter--name) +* [`config`](#-otelcol--exporter--config) +* [`order`](#-otelcol--exporter--order) +* [`pipelines`](#-otelcol--exporter--pipelines) + +##### `name` + +The name of the exporter. + +##### `config` + +Data type: `Hash` + +The configuration of the exporter. + +Default value: `{}` + +##### `order` + +Data type: `Integer[0,999]` + +The order of the exporter. + +Default value: `0` + +##### `pipelines` + +Data type: `Array[String[1]]` + +The pipelines to attach the exporter to. + +Default value: `[]` + +### `otelcol::extension` + +Add an extension to the OpenTelemetry Collector configuration + +#### Examples + +##### + +```puppet +otelcol::extension { 'namevar': } +``` + +#### Parameters + +The following parameters are available in the `otelcol::extension` defined type: + +* [`name`](#-otelcol--extension--name) +* [`config`](#-otelcol--extension--config) +* [`order`](#-otelcol--extension--order) + +##### `name` + +The name of the extension + +##### `config` + +Data type: `Hash` + +The configuration for the extension + +Default value: `{}` + +##### `order` + +Data type: `Integer[0,999]` + +The order in which the extension should be loaded + +Default value: `0` + +### `otelcol::pipeline` + +Used for explicitly configuring a pipeline in the OpenTelemetry Collector. +This is useful for configuring a pipeline that is not automatically +configured by its Components. + +#### Examples + +##### + +```puppet +otelcol::pipeline { 'namevar': } +``` + +#### Parameters + +The following parameters are available in the `otelcol::pipeline` defined type: + +* [`name`](#-otelcol--pipeline--name) +* [`config`](#-otelcol--pipeline--config) +* [`order`](#-otelcol--pipeline--order) + +##### `name` + +The name of the pipeline to configure. + +##### `config` + +Data type: `Hash` + +The configuration for the pipeline. + +Default value: `{}` + +##### `order` + +Data type: `Integer[0,999]` + +The order in which the pipeline should be configured. + +Default value: `0` + +### `otelcol::processor` + +Add a processor to the OpenTelemetry Collector configuration + +#### Examples + +##### + +```puppet +otelcol::processor { 'namevar': } +``` + +#### Parameters + +The following parameters are available in the `otelcol::processor` defined type: + +* [`name`](#-otelcol--processor--name) +* [`config`](#-otelcol--processor--config) +* [`order`](#-otelcol--processor--order) +* [`pipelines`](#-otelcol--processor--pipelines) + +##### `name` + +The name of the processor + +##### `config` + +Data type: `Hash` + +The configuration of the processor + +Default value: `{}` + +##### `order` + +Data type: `Integer[0,999]` + +The order of the processor + +Default value: `0` + +##### `pipelines` + +Data type: `Array[String[1]]` + +The pipelines to attach the processor to + +Default value: `[]` + +### `otelcol::receiver` + +Add a receiver to the OpenTelemetry Collector configuration + +#### Examples + +##### + +```puppet +otelcol::receiver { 'namevar': } +``` + +#### Parameters + +The following parameters are available in the `otelcol::receiver` defined type: + +* [`name`](#-otelcol--receiver--name) +* [`config`](#-otelcol--receiver--config) +* [`order`](#-otelcol--receiver--order) +* [`pipelines`](#-otelcol--receiver--pipelines) + +##### `name` + +The name of the receiver + +##### `config` + +Data type: `Hash` + +The configuration of the receiver + +Default value: `{}` + +##### `order` + +Data type: `Integer[0,999]` + +The order of the receiver + +Default value: `0` + +##### `pipelines` + +Data type: `Array[String[1]]` + +The pipelines the receiver is part of + +Default value: `[]` + diff --git a/examples/basic_installation.pp b/examples/basic_installation.pp index c1832e0..00cc906 100644 --- a/examples/basic_installation.pp +++ b/examples/basic_installation.pp @@ -1,32 +1,40 @@ -class { 'otelcol': - manage_archive => true, - receivers => { - 'otlp' => { - 'protocols' => { - 'grpc' => { 'endpoint' => 'localhost:4317' }, - 'http' => { 'endpoint' => 'localhost:4318' }, - }, - }, - 'prometheus' => { - 'config' => { - 'scrape_configs' => [ - { - 'job_name' => 'otel-collector', - 'scrape_interval' => '10s', - 'static_configs' => [ - { 'targets' => ['localhost:8888'] } - ], - }, - ], - }, +Otelcol::Receiver { 'otlp' : + config => { + 'protocols' => { + 'grpc' => { 'endpoint' => 'localhost:4317' }, + 'http' => { 'endpoint' => 'localhost:4318' }, }, }, - exporters => { 'logging' => { 'verbosity' => 'detailed' } }, - pipelines => { - 'metrics' => { - 'receivers' => ['otlp', 'prometheus'], - 'exporters' => ['logging'], + pipelines => ['metrics'], +} + +Otelcol::Receiver { 'prometheus' : + config => { + 'config' => { + 'scrape_configs' => [ + { + 'job_name' => 'otel-collector', + 'scrape_interval' => '10s', + 'static_configs' => [ + { 'targets' => ['localhost:8888'] } + ], + }, + ], }, }, - processors => { 'batch' => {} }, + pipelines => ['metrics'], +} + +Otelcol::Exporter { 'logging': + config => { 'verbosity' => 'detailed' }, + pipelines => ['metrics'], +} + +Otelcol::Processor { 'batch': + config => {}, + pipelines => ['metrics'], +} + +class { 'otelcol': + manage_archive => true, } diff --git a/examples/basic_installation_oldstyle.pp b/examples/basic_installation_oldstyle.pp new file mode 100644 index 0000000..93fb7b6 --- /dev/null +++ b/examples/basic_installation_oldstyle.pp @@ -0,0 +1,33 @@ +class { 'otelcol': + manage_archive => true, + receivers => { + 'otlp' => { + 'protocols' => { + 'grpc' => { 'endpoint' => 'localhost:4317' }, + 'http' => { 'endpoint' => 'localhost:4318' }, + }, + }, + 'prometheus' => { + 'config' => { + 'scrape_configs' => [ + { + 'job_name' => 'otel-collector', + 'scrape_interval' => '10s', + 'static_configs' => [ + { 'targets' => ['localhost:8888'] } + ], + }, + ], + }, + }, + }, + exporters => { 'logging' => { 'verbosity' => 'detailed' } }, + pipelines => { + 'metrics' => { + 'receivers' => ['otlp', 'prometheus'], + 'processors' => ['batch'], + 'exporters' => ['logging'], + }, + }, + processors => { 'batch' => {} }, +} diff --git a/examples/complex_order.pp b/examples/complex_order.pp new file mode 100644 index 0000000..64a2e64 --- /dev/null +++ b/examples/complex_order.pp @@ -0,0 +1,46 @@ +Otelcol::Receiver { 'otlp' : + config => { + 'protocols' => { + 'grpc' => { 'endpoint' => 'localhost:4317' }, + 'http' => { 'endpoint' => 'localhost:4318' }, + }, + }, + pipelines => ['metrics','logs'], +} + +Otelcol::Receiver { 'prometheus' : + config => { + 'config' => { + 'scrape_configs' => [ + { + 'job_name' => 'otel-collector', + 'scrape_interval' => '10s', + 'static_configs' => [ + { 'targets' => ['localhost:8888'] } + ], + }, + ], + }, + }, + pipelines => ['metrics'], +} + +Otelcol::Exporter { 'logging': + config => { 'verbosity' => 'detailed' }, + pipelines => ['metrics','logs'], +} + +Otelcol::Processor { 'batch/1': + config => {}, + pipelines => ['metrics','logs'], + order => 1, +} +Otelcol::Processor { 'memory_limiter/2': + config => { 'check_interval' => '5s', 'limit_mib' => 512 }, + pipelines => ['metrics','logs'], + order => 2, +} + +class { 'otelcol': + manage_archive => true, +} diff --git a/manifests/component.pp b/manifests/component.pp new file mode 100644 index 0000000..b7bd8b8 --- /dev/null +++ b/manifests/component.pp @@ -0,0 +1,57 @@ +# @summary Define a component for the OpenTelemetry Collector Configuration +# +# Generic Type for defining a component for the OpenTelemetry Collector Configuration +# +# @param component_name +# The name of the component +# @param type +# The type of the component +# @param config +# The configuration for the component +# @param order +# The order of the component +# @param pipelines +# The pipelines to add the component to +# +# @example +# otelcol::component { 'receiver_name-receiver':': +# component_name => 'receiver_name', +# type => 'receiver', +# } +# @api private +define otelcol::component ( + String $component_name, + String $type, + Hash $config = {}, + Integer[0,10999] $order = 0, + Array[String[1]] $pipelines = [], +) { + # assert_private() + $component = { + $type => { + $component_name => $config, + }, + } + concat::fragment { "otelcol-config-${type}-${component_name}" : + target => 'otelcol-config', + order => $order, + content => template('otelcol/component.yml.erb'), + } + + $pipelines.each |String $pipeline| { + $component = { + 'service' => { + 'pipelines' => { + $pipeline => { + $type => [$component_name], + }, + }, + }, + } + concat::fragment { "otelcol-config-${type}-${component_name}-${pipeline}" : + target => 'otelcol-config', + order => $order, + content => template('otelcol/component.yml.erb'), + } + } +} diff --git a/manifests/config.pp b/manifests/config.pp index f5044a8..cfc836e 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -4,15 +4,8 @@ # class otelcol::config inherits otelcol { assert_private() - - $settings = { - 'receivers' => $otelcol::receivers, - 'processors' => $otelcol::processors, - 'exporters' => $otelcol::exporters, - 'extensions' => $otelcol::extensions, + $component = { 'service' => { - 'extensions' => $otelcol::extensions.keys(), - 'pipelines' => $otelcol::pipelines, 'telemetry' => { 'logs' => $otelcol::log_options, 'metrics' => { @@ -23,13 +16,31 @@ }, } - file { 'otelcol-config' : - ensure => 'file', - path => $otelcol::config_file, - content => template('otelcol/config.yml.erb'), - owner => $otelcol::config_file_owner, - group => $otelcol::config_file_group, - mode => $otelcol::config_file_mode, + concat { 'otelcol-config' : + ensure => present, + path => $otelcol::config_file, + format => 'yaml', + # content => template('otelcol/config.yml.erb'), + owner => $otelcol::config_file_owner, + group => $otelcol::config_file_group, + mode => $otelcol::config_file_mode, + } + concat::fragment { 'otelcol-config-header' : + target => 'otelcol-config', + order => 0, + content => template('otelcol/config-header.yml.erb'), + } + + concat::fragment { 'otelcol-config-baseconfig' : + target => 'otelcol-config', + order => 10000, + content => template('otelcol/component.yml.erb'), + } + + concat::fragment { 'otelcol-config-footer' : + target => 'otelcol-config', + order => 10001, + content => template('otelcol/config-footer.yml.erb'), } file { 'otelcol-environment' : ensure => 'file', @@ -39,4 +50,59 @@ group => $otelcol::config_file_group, mode => $otelcol::config_file_mode, } + + if($otelcol::receivers) { + $otelcol::receivers.each|String $rname, Hash $rvalue| { + if($rvalue['config'] and $rvalue['config'].is_a(Hash)) { + ensure_resource('Otelcol::Receiver', $rname, $rvalue) + } + else { + ensure_resource('Otelcol::Receiver', $rname, { 'config' => $rvalue }) + } + } + } + + if($otelcol::processors) { + $otelcol::processors.each|String $rname, Hash $rvalue| { + if($rvalue['config'] and $rvalue['config'].is_a(Hash)) { + ensure_resource('Otelcol::Processor', $rname, $rvalue) + } + else { + ensure_resource('Otelcol::Processor', $rname, { 'config' => $rvalue }) + } + } + } + + if($otelcol::exporters) { + $otelcol::exporters.each|String $rname, Hash $rvalue| { + if($rvalue['config'] and $rvalue['config'].is_a(Hash)) { + ensure_resource('Otelcol::Exporter', $rname, $rvalue) + } + else { + ensure_resource('Otelcol::Exporter', $rname, { 'config' => $rvalue }) + } + } + } + + if($otelcol::pipelines) { + $otelcol::pipelines.each|String $rname, Hash $rvalue| { + if($rvalue['config'] and $rvalue['config'].is_a(Hash)) { + ensure_resource('Otelcol::Pipeline', $rname, $rvalue) + } + else { + ensure_resource('Otelcol::Pipeline', $rname, { 'config' => $rvalue }) + } + } + } + + if($otelcol::extensions) { + $otelcol::extensions.each|String $rname, Hash $rvalue| { + if($rvalue['config'] and $rvalue['config'].is_a(Hash)) { + ensure_resource('Otelcol::Extension', $rname, $rvalue) + } + else { + ensure_resource('Otelcol::Extension', $rname, { 'config' => $rvalue }) + } + } + } } diff --git a/manifests/exporter.pp b/manifests/exporter.pp new file mode 100644 index 0000000..4a22734 --- /dev/null +++ b/manifests/exporter.pp @@ -0,0 +1,28 @@ +# @summary Define a OpenTelemetry Collector exporter +# +# Create a OpenTelemetry Collector exporter in the configuration file. +# +# @param name +# The name of the exporter. +# @param config +# The configuration of the exporter. +# @param order +# The order of the exporter. +# @param pipelines +# The pipelines to attach the exporter to. +# @example +# otelcol::exporter { 'namevar': } +define otelcol::exporter ( + Hash $config = {}, + Integer[0,999] $order = 0, + Array[String[1]] $pipelines = [], +) { + $real_order = 3000+$order + Otelcol::Component { "${name}-exporter": + order => $real_order, + config => $config, + pipelines => $pipelines, + component_name => $name, + type => 'exporters', + } +} diff --git a/manifests/extension.pp b/manifests/extension.pp new file mode 100644 index 0000000..661c111 --- /dev/null +++ b/manifests/extension.pp @@ -0,0 +1,30 @@ +# @summary Add an extension to the OpenTelemetry Collector configuration +# +# @param name +# The name of the extension +# @param config +# The configuration for the extension +# @param order +# The order in which the extension should be loaded +# +# @example +# otelcol::extension { 'namevar': } +define otelcol::extension ( + Hash $config = {}, + Integer[0,999] $order = 0, +) { + $component = { + 'extensions' => { + $name => $config, + }, + 'service' => { + 'extensions' => [$name], + }, + } + $real_order = 4000+$order + concat::fragment { "otelcol-config-extension-${name}" : + target => 'otelcol-config', + order => $real_order, + content => template('otelcol/component.yml.erb'), + } +} diff --git a/manifests/init.pp b/manifests/init.pp index dc584b0..999e049 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -56,14 +56,7 @@ String $config_file_owner = 'root', String $config_file_group = 'root', Stdlib::Filemode $config_file_mode = '0644', - Hash $receivers = { - 'otlp' => { - 'protocols' => { - 'http' => {}, - 'grpc' => {}, - }, - }, - }, + Optional[Hash] $receivers = undef, Variant[Hash,String[1]] $processors = {}, Variant[Hash,String[1]] $exporters = {}, Variant[Hash,String[1]] $pipelines = {}, @@ -72,16 +65,17 @@ Enum['none','basic','normal','detailed'] $metrics_level = 'basic', Optional[Stdlib::Host] $metrics_address_host = undef, Stdlib::Port $metrics_address_port = 8888, - Stdlib::Ensure::Service $service_ensure = 'running', + Stdlib::Ensure::Service $service_ensure = 'running', Boolean $manage_service = true, Boolean $manage_archive = false, String[1] $localpath_archive = '/tmp', # Boolean $manage_user = false, - String[1] $archive_version = '0.79.0', + String[1] $archive_version = '0.89.0', String[1] $archive_location = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v${archive_version}/${package_name}_${archive_version}_linux_amd64", ) { contain otelcol::install contain otelcol::config + if($manage_service) { contain otelcol::service Class['otelcol::config'] ~> Class['otelcol::service'] diff --git a/manifests/pipeline.pp b/manifests/pipeline.pp new file mode 100644 index 0000000..d71a25c --- /dev/null +++ b/manifests/pipeline.pp @@ -0,0 +1,32 @@ +# @summary Add a pipeline to the OpenTelemetry Collector configuration +# +# Used for explicitly configuring a pipeline in the OpenTelemetry Collector. +# This is useful for configuring a pipeline that is not automatically +# configured by its Components. +# +# @param name +# The name of the pipeline to configure. +# @param config +# The configuration for the pipeline. +# @param order +# The order in which the pipeline should be configured. +# @example +# otelcol::pipeline { 'namevar': } +define otelcol::pipeline ( + Hash $config = {}, + Integer[0,999] $order = 0, +) { + $component = { + 'service' => { + 'pipelines' => { + $name => $config, + }, + }, + } + $real_order = 5000+$order + concat::fragment { "otelcol-config-pipeline-${name}" : + target => 'otelcol-config', + order => $real_order, + content => template('otelcol/component.yml.erb'), + } +} diff --git a/manifests/processor.pp b/manifests/processor.pp new file mode 100644 index 0000000..cb2088f --- /dev/null +++ b/manifests/processor.pp @@ -0,0 +1,27 @@ +# @summary Add a processor to the OpenTelemetry Collector configuration +# +# @param name +# The name of the processor +# @param config +# The configuration of the processor +# @param order +# The order of the processor +# @param pipelines +# The pipelines to attach the processor to +# +# @example +# otelcol::processor { 'namevar': } +define otelcol::processor ( + Hash $config = {}, + Integer[0,999] $order = 0, + Array[String[1]] $pipelines = [], +) { + $real_order = 2000+$order + Otelcol::Component { "${name}-processors": + order => $real_order, + config => $config, + pipelines => $pipelines, + component_name => $name, + type => 'processors', + } +} diff --git a/manifests/receiver.pp b/manifests/receiver.pp new file mode 100644 index 0000000..3a96f74 --- /dev/null +++ b/manifests/receiver.pp @@ -0,0 +1,26 @@ +# @summary Add a receiver to the OpenTelemetry Collector configuration +# +# @param name +# The name of the receiver +# @param config +# The configuration of the receiver +# @param order +# The order of the receiver +# @param pipelines +# The pipelines the receiver is part of +# @example +# otelcol::receiver { 'namevar': } +define otelcol::receiver ( + Hash $config = {}, + Integer[0,999] $order = 0, + Array[String[1]] $pipelines = [], +) { + $real_order = 1000+$order + Otelcol::Component { "${name}-receivers": + order => $real_order, + config => $config, + pipelines => $pipelines, + component_name => $name, + type => 'receivers', + } +} diff --git a/manifests/service.pp b/manifests/service.pp index 4747116..5747823 100644 --- a/manifests/service.pp +++ b/manifests/service.pp @@ -28,6 +28,6 @@ ensure => $ensure, name => $otelcol::service_name, require => Package['otelcol'], - subscribe => [File['otelcol-config'], File['otelcol-environment']], + subscribe => [Concat['otelcol-config'], File['otelcol-environment']], } } diff --git a/metadata.json b/metadata.json index 5f4ad47..cf7acc5 100644 --- a/metadata.json +++ b/metadata.json @@ -11,6 +11,10 @@ { "name": "puppetlabs/stdlib", "version_requirement": ">= 8.0.0 < 9.0.0" + }, + { + "name": "puppetlabs/concat", + "version_requirement": ">= 9.0.0 < 10.0.0" } ], "operatingsystem_support": [ diff --git a/spec/classes/otelcol_spec.rb b/spec/classes/otelcol_spec.rb index 5f6a43f..ef1e132 100644 --- a/spec/classes/otelcol_spec.rb +++ b/spec/classes/otelcol_spec.rb @@ -8,41 +8,19 @@ let(:facts) do facts end - - let(:configcontent) do - { - 'receivers' => { - 'otlp' => { - 'protocols' => { - 'http' => {}, - 'grpc' => {}, - }, - }, - }, - 'processors' => {}, - 'exporters' => {}, - 'extensions' => {}, - 'service' => { - 'extensions' => [], - 'pipelines' => {}, - 'telemetry' => { - 'logs' => {}, - 'metrics' => { - 'level' => 'basic', - 'address' => ':8888', - }, - }, - }, - - } - end - + context 'default include' do it { is_expected.to compile.with_all_deps } it { is_expected.to contain_class('otelcol::config') - is_expected.to contain_file('otelcol-config').with_path('/etc/otelcol/config.yaml') + is_expected.to contain_concat('otelcol-config').with({ + 'path' => '/etc/otelcol/config.yaml', + 'format' => 'yaml', + }) + is_expected.to contain_concat__fragment('otelcol-config-header') + is_expected.to contain_concat__fragment('otelcol-config-baseconfig') + is_expected.to contain_concat__fragment('otelcol-config-footer') is_expected.to contain_file('otelcol-environment').with_path('/etc/otelcol/otelcol.conf') is_expected.to contain_file('otelcol-environment').with_content(%r{--config=/etc/otelcol/config.yaml"}) } @@ -72,7 +50,7 @@ it { is_expected.to contain_class('otelcol::config') - is_expected.to contain_file('otelcol-config').with_path('/etc/otelcol-contrib/config.yaml') + is_expected.to contain_concat('otelcol-config').with_path('/etc/otelcol-contrib/config.yaml') # is_expected.to contain_file('otelcol-config').with_content(%r{"otlp":\s\{\s"protocols":\s\{\s"http":}) is_expected.to contain_file('otelcol-environment').with_path('/etc/otelcol-contrib/otelcol-contrib.conf') @@ -80,7 +58,7 @@ } it { # Validate vaild YAML for config - is_expected.to contain_file('otelcol-config').with_content(configcontent.to_yaml) + is_expected.to contain_concat('otelcol-config')# .with_content(configcontent.to_yaml) # yaml_object = YAML.load(catalogue.resource('file', 'otelcol-config').send(:parameters)[:content]) # expect(yaml_object.length).to be > 0 } @@ -105,9 +83,9 @@ let(:package_source) do case facts[:osfamily] when 'Debian' - 'https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.79.0/otelcol-contrib_0.79.0_linux_amd64.deb' + 'https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.89.0/otelcol-contrib_0.89.0_linux_amd64.deb' when 'RedHat' - 'https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.79.0/otelcol-contrib_0.79.0_linux_amd64.rpm' + 'https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.89.0/otelcol-contrib_0.89.0_linux_amd64.rpm' end end let(:package_localpath) do @@ -163,7 +141,7 @@ it { is_expected.to compile.with_all_deps } it { - is_expected.to contain_file('otelcol-config').with_path('/etc/otelcol/test.conf') + is_expected.to contain_concat('otelcol-config').with_path('/etc/otelcol/test.conf') is_expected.to contain_file('otelcol-environment').with_content(%r{--config=/etc/otelcol/test.conf"}) } end @@ -180,7 +158,7 @@ it { is_expected.to compile.with_all_deps } it { - is_expected.to contain_file('otelcol-config').with( + is_expected.to contain_concat('otelcol-config').with( 'owner' => 'root', 'group' => 'root', 'mode' => '0600' @@ -196,12 +174,17 @@ }, } end - let(:configcontent_ext) do - configcontent.merge({ 'receivers' => { 'test' => {} } }) - end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_file('otelcol-config').with_content(configcontent_ext.to_yaml) } + it { is_expected.to contain_otelcol__receiver('test').with({ + 'config' => {}, + 'pipelines' => [], + 'order' => 0, + 'name' => 'test', + }) + is_expected.to contain_otelcol__component('test-receivers') + is_expected.to contain_concat__fragment('otelcol-config-receivers-test') + } end context 'with processors' do @@ -212,12 +195,17 @@ }, } end - let(:configcontent_ext) do - configcontent.merge({ 'processors' => { 'test' => {} } }) - end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_file('otelcol-config').with_content(configcontent_ext.to_yaml) } + it { is_expected.to contain_otelcol__processor('test').with({ + 'config' => {}, + 'pipelines' => [], + 'order' => 0, + 'name' => 'test', + }) + is_expected.to contain_otelcol__component('test-processors') + is_expected.to contain_concat__fragment('otelcol-config-processors-test') + } end context 'with exporters' do @@ -228,12 +216,17 @@ }, } end - let(:configcontent_ext) do - configcontent.merge({ 'exporters' => { 'test' => {} } }) - end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_file('otelcol-config').with_content(configcontent_ext.to_yaml) } + it { is_expected.to contain_otelcol__exporter('test').with({ + 'config' => {}, + 'pipelines' => [], + 'order' => 0, + 'name' => 'test', + }) + is_expected.to contain_otelcol__component('test-exporter') + is_expected.to contain_concat__fragment('otelcol-config-exporters-test') + } end context 'with pipelines' do @@ -244,26 +237,15 @@ }, } end - let(:configcontent_ext) do - configcontent.merge( - { - 'service' => { - 'extensions' => [], - 'pipelines' => { 'test' => {} }, - 'telemetry' => { - 'logs' => {}, - 'metrics' => { - 'level' => 'basic', - 'address' => ':8888', - }, - }, - }, - } - ) - end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_file('otelcol-config').with_content(configcontent_ext.to_yaml) } + it { is_expected.to contain_otelcol__pipeline('test').with({ + 'config' => {}, + 'order' => 0, + 'name' => 'test', + }) + is_expected.to contain_concat__fragment('otelcol-config-pipeline-test') + } end context 'with extensions' do @@ -274,60 +256,48 @@ }, } end - let(:configcontent_ext) do - configcontent.merge( - { - 'extensions' => { 'test' => {} }, - 'service' => { - 'extensions' => ['test'], - 'pipelines' => {}, - 'telemetry' => { - 'logs' => {}, - 'metrics' => { - 'level' => 'basic', - 'address' => ':8888', - }, - }, - } - } - ) - end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_file('otelcol-config').with_content(configcontent_ext.to_yaml) } + it { is_expected.to contain_otelcol__extension('test').with({ + 'config' => {}, + 'order' => 0, + 'name' => 'test', + }) + is_expected.to contain_concat__fragment('otelcol-config-extension-test') + } end - context 'with include files' do - let :params do - { - processors: '${file:processors.yaml}', - exporters: '${file:exporters.yaml}', - pipelines: '${file:pipelines.yaml}', - } - end - let(:configcontent_ext) do - configcontent.merge( - { - 'processors' => '${file:processors.yaml}', - 'exporters' => '${file:exporters.yaml}', - 'service' => { - 'extensions' => [], - 'pipelines' => '${file:pipelines.yaml}', - 'telemetry' => { - 'logs' => {}, - 'metrics' => { - 'level' => 'basic', - 'address' => ':8888', - }, - }, - } - } - ) - end - - it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_file('otelcol-config').with_content(configcontent_ext.to_yaml) } - end + # context 'with include files' do + # let :params do + # { + # processors: '${file:processors.yaml}', + # exporters: '${file:exporters.yaml}', + # pipelines: '${file:pipelines.yaml}', + # } + # end + # let(:configcontent_ext) do + # configcontent.merge( + # { + # 'processors' => '${file:processors.yaml}', + # 'exporters' => '${file:exporters.yaml}', + # 'service' => { + # 'extensions' => [], + # 'pipelines' => '${file:pipelines.yaml}', + # 'telemetry' => { + # 'logs' => {}, + # 'metrics' => { + # 'level' => 'basic', + # 'address' => ':8888', + # }, + # }, + # } + # } + # ) + # end + + # it { is_expected.to compile.with_all_deps } + # # it { is_expected.to contain_file('otelcol-config').with_content(configcontent_ext.to_yaml) } + # end context 'with logoptions' do let :params do @@ -337,29 +307,24 @@ }, } end - let(:configcontent_ext) do - configcontent.merge( - { - 'extensions' => {}, - 'service' => { - 'extensions' => [], - 'pipelines' => {}, - 'telemetry' => { - 'logs' => { - 'level' => 'debug' - }, - 'metrics' => { - 'level' => 'basic', - 'address' => ':8888', - }, + let(:configcontent) do + { + 'service' => { + 'telemetry' => { + 'logs' => { + 'level' => 'debug' }, - } + 'metrics' => { + 'level' => 'basic', + 'address' => ':8888', + }, + }, } - ) + } end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_file('otelcol-config').with_content(configcontent_ext.to_yaml) } + it { is_expected.to contain_concat__fragment('otelcol-config-baseconfig').with_content(configcontent.to_yaml) } end context 'with metrics config' do @@ -370,27 +335,22 @@ metrics_address_port: 1234, } end - let(:configcontent_ext) do - configcontent.merge( - { - 'extensions' => {}, - 'service' => { - 'extensions' => [], - 'pipelines' => {}, - 'telemetry' => { - 'logs' => {}, - 'metrics' => { - 'level' => 'detailed', - 'address' => '127.0.0.1:1234', - }, + let(:configcontent) do + { + 'service' => { + 'telemetry' => { + 'logs' => {}, + 'metrics' => { + 'level' => 'detailed', + 'address' => '127.0.0.1:1234', }, - } + }, } - ) + } end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_file('otelcol-config').with_content(configcontent_ext.to_yaml) } + it { is_expected.to contain_concat__fragment('otelcol-config-baseconfig').with_content(configcontent.to_yaml) } end context 'with service_ensure' do @@ -425,9 +385,9 @@ let(:package_source) do case facts[:osfamily] when 'Debian' - 'https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.79.0/otelcol_0.79.0_linux_amd64.deb' + 'https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.89.0/otelcol_0.89.0_linux_amd64.deb' when 'RedHat' - 'https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.79.0/otelcol_0.79.0_linux_amd64.rpm' + 'https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.89.0/otelcol_0.89.0_linux_amd64.rpm' end end let(:package_localpath) do diff --git a/spec/defines/component_spec.rb b/spec/defines/component_spec.rb new file mode 100644 index 0000000..8cf58f7 --- /dev/null +++ b/spec/defines/component_spec.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'otelcol::component' do + let(:title) { 'otlp-receivers' } + let(:params) do + { + 'config' => { + 'key' => 'value', + }, + 'type' => 'receivers', + 'component_name' => 'otlp' + } + end + + let(:configcontent) do + { + 'receivers' => { + 'otlp' => { + 'key' => 'value', + }, + }, + } + end + + + let(:configcontentpipeline) do + { + 'service' => { + 'pipelines' => { + 'test' => { + 'receivers' => ['otlp'], + } + }, + }, + } + end + + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp') } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp').with_content(configcontent.to_yaml) } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp').with_order(0) } + + # Create Checks for importer with extended parameters with order + context 'with order' do + let :params do + super().merge({'order' => 1}) + end + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp').with_order(1) } + end + + # Create Check for importer with extended parameters with pipelines array + context 'with pipelines array' do + let :params do + super().merge({'pipelines' => ['test']}) + end + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp-test') } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp-test').with_content(configcontentpipeline.to_yaml) } + end + + # Create Check for importer with extended parameters with pipelines array + context 'with pipelines array' do + let(:params) do + super().merge({'pipelines' => ['test', 'test2']}) + end + + let(:configcontentpipeline2) do + { + 'service' => { + 'pipelines' => { + 'test2' => { + 'receivers' => ['otlp'], + } + }, + }, + } + end + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp-test') } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp-test').with_content(configcontentpipeline.to_yaml) } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp-test2') } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp-test2').with_content(configcontentpipeline2.to_yaml) } + end + + # Create Check for importer with extended parameters with pipelines array and order + context 'with pipelines array and order' do + let(:params) do + super().merge({'pipelines' => ['test'], 'order' => 1}) + end + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp-test') } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp-test').with_content(configcontentpipeline.to_yaml) } + it { is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp-test').with_order(1) } + end + end + end +end diff --git a/spec/defines/exporter_spec.rb b/spec/defines/exporter_spec.rb new file mode 100644 index 0000000..872cd6e --- /dev/null +++ b/spec/defines/exporter_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'otelcol::exporter' do + let(:title) { 'otlp' } + let(:params) do + { + 'config' => { + 'key' => 'value', + } + } + end + + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + it { is_expected.to compile } + it { is_expected.to contain_otelcol__component('otlp-exporter').with({ + 'order' => 3000, + 'config' => { + 'key' => 'value', + }, + 'pipelines' => [], + 'type' => 'exporters', + 'component_name' => 'otlp', + }) } + it { + is_expected.to contain_concat__fragment('otelcol-config-exporters-otlp').with({ + 'order' => 3000, + 'target' => 'otelcol-config', + }) + } + + + context 'with order' do + let :params do + super().merge({'order' => 1}) + end + + it { is_expected.to compile } + it { is_expected.to contain_otelcol__component('otlp-exporter').with({ + 'order' => 3001, + 'config' => { + 'key' => 'value', + }, + 'pipelines' => [], + 'type' => 'exporters', + 'component_name' => 'otlp', + }) } + end + + end + end +end diff --git a/spec/defines/extension_spec.rb b/spec/defines/extension_spec.rb new file mode 100644 index 0000000..c315e61 --- /dev/null +++ b/spec/defines/extension_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'otelcol::extension' do + let(:title) { 'health_check' } + let(:params) do + { + 'config' => {}, + } + end + + let(:configcontent) do + { + 'extensions' => { + 'health_check' => {}, + }, + 'service' => { + 'extensions' => ['health_check'], + }, + } + end + + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('otelcol-config-extension-health_check').with({ + 'order' => 4000, + 'target' => 'otelcol-config', + 'content' => configcontent.to_yaml, + }) + } + + + context 'with order' do + let :params do + super().merge({'order' => 1}) + end + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('otelcol-config-extension-health_check').with({ + 'order' => 4001, + 'target' => 'otelcol-config', + 'content' => configcontent.to_yaml, + }) + } + end + end + end +end diff --git a/spec/defines/pipeline_spec.rb b/spec/defines/pipeline_spec.rb new file mode 100644 index 0000000..65b8b2d --- /dev/null +++ b/spec/defines/pipeline_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'otelcol::pipeline' do + let(:title) { 'mypipeline' } + let(:params) do + { + 'config' => {}, + } + end + + let(:configcontent) do + { + 'service' => { + 'pipelines' => { + 'mypipeline' => {}, + }, + }, + } + end + + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('otelcol-config-pipeline-mypipeline').with({ + 'order' => 5000, + 'target' => 'otelcol-config', + 'content' => configcontent.to_yaml, + }) + } + + + context 'with order' do + let :params do + super().merge({'order' => 1}) + end + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('otelcol-config-pipeline-mypipeline').with({ + 'order' => 5001, + 'target' => 'otelcol-config', + 'content' => configcontent.to_yaml, + }) + } + end + end + end +end diff --git a/spec/defines/processor_spec.rb b/spec/defines/processor_spec.rb new file mode 100644 index 0000000..9a3e3ab --- /dev/null +++ b/spec/defines/processor_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'otelcol::processor' do + let(:title) { 'batch' } + let(:params) do + { + 'config' => { + 'key' => 'value', + } + } + end + + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + it { is_expected.to compile } + it { is_expected.to contain_otelcol__component('batch-processors').with({ + 'order' => 2000, + 'config' => { + 'key' => 'value', + }, + 'pipelines' => [], + 'type' => 'processors', + 'component_name' => 'batch', + }) } + it { + is_expected.to contain_concat__fragment('otelcol-config-processors-batch').with({ + 'order' => 2000, + 'target' => 'otelcol-config', + }) + } + + + context 'with order' do + let :params do + super().merge({'order' => 1}) + end + + it { is_expected.to compile } + it { is_expected.to contain_otelcol__component('batch-processors').with({ + 'order' => 2001, + 'config' => { + 'key' => 'value', + }, + 'pipelines' => [], + 'type' => 'processors', + 'component_name' => 'batch', + }) } + end + + end + end +end diff --git a/spec/defines/receiver_spec.rb b/spec/defines/receiver_spec.rb new file mode 100644 index 0000000..82a12c6 --- /dev/null +++ b/spec/defines/receiver_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'otelcol::receiver' do + let(:title) { 'otlp' } + let(:params) do + { + 'config' => { + 'key' => 'value', + } + } + end + + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + it { is_expected.to compile } + it { is_expected.to contain_otelcol__component('otlp-receivers').with({ + 'order' => 1000, + 'config' => { + 'key' => 'value', + }, + 'pipelines' => [], + 'type' => 'receivers', + 'component_name' => 'otlp', + }) } + it { + is_expected.to contain_concat__fragment('otelcol-config-receivers-otlp').with({ + 'order' => 1000, + 'target' => 'otelcol-config', + }) + } + + + context 'with order' do + let :params do + super().merge({'order' => 1}) + end + + it { is_expected.to compile } + it { is_expected.to contain_otelcol__component('otlp-receivers').with({ + 'order' => 1001, + 'config' => { + 'key' => 'value', + }, + 'pipelines' => [], + 'type' => 'receivers', + 'component_name' => 'otlp', + }) } + end + + end + end +end diff --git a/templates/component.yml.erb b/templates/component.yml.erb new file mode 100644 index 0000000..7d961a8 --- /dev/null +++ b/templates/component.yml.erb @@ -0,0 +1 @@ +<%= @component.to_yaml %> \ No newline at end of file diff --git a/templates/config-footer.yml.erb b/templates/config-footer.yml.erb new file mode 100644 index 0000000..e69de29 diff --git a/templates/config-header.yml.erb b/templates/config-header.yml.erb new file mode 100644 index 0000000..04f8fdc --- /dev/null +++ b/templates/config-header.yml.erb @@ -0,0 +1 @@ +# File Managed by Puppet \ No newline at end of file