Skip to content

Commit eda64e7

Browse files
authored
chore(config): properly enforce specifying docs::enum_tag_description for internally tagged enums (#15853)
1 parent f55e0cc commit eda64e7

34 files changed

+146
-105
lines changed

lib/codecs/src/encoding/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ impl From<std::io::Error> for Error {
5555
#[configurable_component]
5656
#[derive(Clone, Debug, Eq, PartialEq)]
5757
#[serde(tag = "method", rename_all = "snake_case")]
58+
#[configurable(metadata(docs::enum_tag_description = "The framing method."))]
5859
pub enum FramingConfig {
5960
/// Event data is not delimited at all.
6061
Bytes,

scripts/generate-component-docs.rb

+23-17
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
require 'tempfile'
77
rescue LoadError => e
88
puts "Load error: #{e.message}"
9-
exit
9+
exit 1
1010
end
1111

1212
DEBUG_LEVEL = 1
@@ -277,7 +277,7 @@ def get_docs_type_for_value(schema, value)
277277
@logger.error "Schema instance type and value type are a mismatch, which should not happen."
278278
@logger.error "Schema instance type: #{schema_instance_type}"
279279
@logger.error "Value: #{value} (type: #{value_type})"
280-
exit
280+
exit 1
281281
end
282282

283283
# For any numeric type, extract the value of `docs::numeric_type`, which must always be present in
@@ -288,7 +288,7 @@ def get_docs_type_for_value(schema, value)
288288
numeric_type = get_schema_metadata(schema, 'docs::numeric_type')
289289
if numeric_type.nil?
290290
@logger.error "All fields with numeric types should have 'docs::numeric_type' metadata included."
291-
exit
291+
exit 1
292292
end
293293

294294
return numeric_type
@@ -461,7 +461,7 @@ def get_schema_by_name(root_schema, schema_name)
461461
schema_def = root_schema.dig('definitions', schema_name)
462462
if schema_def.nil?
463463
@logger.error "Could not find schema definition '#{schema_name}' in given schema."
464-
exit
464+
exit 1
465465
end
466466

467467
schema_def
@@ -713,7 +713,7 @@ def resolve_schema_by_name(root_schema, schema_name)
713713
cycles with `#[configurable(metadata(docs::cycle_entrypoint))]`. As such a field will have no type \
714714
information rendered, it is advised to supply a sufficiently detailed field description that \
715715
describes the allowable values, etc."
716-
exit
716+
exit 1
717717
end
718718

719719
# It wasn't already cached, so we actually have to resolve it.
@@ -949,7 +949,7 @@ def resolve_bare_schema(root_schema, schema)
949949
grouped
950950
else
951951
@logger.error "Failed to resolve the schema. Schema: #{schema}"
952-
exit
952+
exit 1
953953
end
954954

955955
{ 'type' => resolved }
@@ -985,7 +985,7 @@ def resolve_enum_schema(root_schema, schema)
985985
@logger.error 'Enum schemas should never be missing the metadata for the enum tagging mode.'
986986
@logger.error "Schema: #{JSON.pretty_generate(schema)}"
987987
@logger.error "Filter subschemas: #{JSON.pretty_generate(subschemas)}"
988-
exit
988+
exit 1
989989
end
990990

991991
enum_tag_field = get_schema_metadata(schema, 'docs::enum_tag_field')
@@ -1098,12 +1098,12 @@ def resolve_enum_schema(root_schema, schema)
10981098
if tag_value.nil?
10991099
@logger.error 'All enum subschemas representing an internally-tagged enum must have the tag field use a const value.'
11001100
@logger.error "Tag subschema: #{tag_subschema}"
1101-
exit
1101+
exit 1
11021102
end
11031103

11041104
if unique_tag_values.key?(tag_value)
11051105
@logger.error "Found duplicate tag value '#{tag_value}' when resolving enum subschemas."
1106-
exit
1106+
exit 1
11071107
end
11081108

11091109
unique_tag_values[tag_value] = tag_subschema
@@ -1122,7 +1122,7 @@ def resolve_enum_schema(root_schema, schema)
11221122
@logger.error "Had overlapping property '#{property_name}' from resolved enum subschema, but schemas differed:"
11231123
@logger.error "Existing property schema (reduced): #{to_pretty_json(reduced_existing_property)}"
11241124
@logger.error "New property schema (reduced): #{to_pretty_json(reduced_new_property)}"
1125-
exit
1125+
exit 1
11261126
end
11271127

11281128
@logger.debug "Adding relevant tag to existing resolved property schema for '#{property_name}'."
@@ -1185,8 +1185,14 @@ def resolve_enum_schema(root_schema, schema)
11851185
}
11861186
}
11871187
}
1188+
11881189
tag_description = get_schema_metadata(schema, 'docs::enum_tag_description')
1189-
resolved_tag_property['description'] = tag_description unless tag_description.nil?
1190+
if tag_description.nil?
1191+
@logger.error "A unique tag description must be specified for enums which are internally tagged (i.e. `#[serde(tag = \"...\")/`). This can be specified via `#[configurable(metadata(docs::enum_tag_description = \"...\"))]`."
1192+
@logger.error "Schema being generated: #{JSON.pretty_generate(schema)}"
1193+
exit 1
1194+
end
1195+
resolved_tag_property['description'] = tag_description
11901196
unique_resolved_properties[enum_tag_field] = resolved_tag_property
11911197

11921198
@logger.debug "Resolved as 'internally-tagged with named fields' enum schema."
@@ -1366,7 +1372,7 @@ def apply_schema_default_value!(source_schema, resolved_schema)
13661372
Source schema: #{to_pretty_json(source_schema)} \
13671373
Default value: #{to_pretty_json(default_value)} (type: #{default_value_type}) \
13681374
Resolved schema: #{to_pretty_json(resolved_schema)}"
1369-
exit
1375+
exit 1
13701376
end
13711377

13721378
case default_value_type
@@ -1487,7 +1493,7 @@ def apply_schema_metadata!(source_schema, resolved_schema)
14871493
if !syntax_override.nil?
14881494
if resolved_schema_type?(resolved_schema) != "string"
14891495
@logger.error "Non-string schemas should not use the `syntax_override` metadata attribute."
1490-
exit
1496+
exit 1
14911497
end
14921498

14931499
resolved_schema['type']['string']['syntax'] = syntax_override.to_s
@@ -1656,7 +1662,7 @@ def render_and_import_schema(root_schema, schema_name, friendly_name, config_map
16561662
unwrapped_resolved_schema = resolved_schema.dig('type', 'object', 'options')
16571663
if unwrapped_resolved_schema.nil?
16581664
@logger.error 'Configuration types must always resolve to an object schema.'
1659-
exit
1665+
exit 1
16601666
end
16611667

16621668
unwrapped_resolved_schema = sort_hash_nested(unwrapped_resolved_schema)
@@ -1689,7 +1695,7 @@ def render_and_import_schema(root_schema, schema_name, friendly_name, config_map
16891695
cue_output_file = "website/cue/reference/components/#{cue_relative_path}"
16901696
unless system(@cue_binary_path, 'import', '-f', '-o', cue_output_file, '-p', 'metadata', json_output_file)
16911697
@logger.error "[!] Failed to import #{friendly_name} schema as valid Cue."
1692-
exit
1698+
exit 1
16931699
end
16941700
@logger.info "[✓] Imported #{friendly_name} schema to '#{cue_output_file}'."
16951701
end
@@ -1716,13 +1722,13 @@ def render_and_import_component_schema(root_schema, schema_name, component_type,
17161722

17171723
if ARGV.empty?
17181724
puts 'usage: extract-component-schema.rb <configuration schema path>'
1719-
exit
1725+
exit 1
17201726
end
17211727

17221728
# Ensure that Cue is present since we need it to import our intermediate JSON representation.
17231729
if @cue_binary_path.nil?
17241730
puts 'Failed to find \'cue\' binary on the current path. Install \'cue\' (or make it available on the current path) and try again.'
1725-
exit
1731+
exit 1
17261732
end
17271733

17281734
schema_path = ARGV[0]

src/nats.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,35 @@ pub enum NatsConfigError {
1919
#[configurable_component]
2020
#[derive(Clone, Debug)]
2121
#[serde(rename_all = "snake_case", tag = "strategy")]
22+
#[configurable(metadata(
23+
docs::enum_tag_description = "The strategy used to authenticate with the NATS server.
24+
25+
More information on NATS authentication, and the various authentication strategies, can be found in the
26+
NATS [documentation][nats_auth_docs]. For TLS client certificate authentication specifically, see the
27+
`tls` settings.
28+
29+
[nats_auth_docs]: https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro"
30+
))]
2231
pub(crate) enum NatsAuthConfig {
23-
/// Username and password authentication.
24-
/// ([documentation](https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro/username_password))
32+
/// Username/password authentication.
2533
UserPassword {
2634
#[configurable(derived)]
2735
user_password: NatsAuthUserPassword,
2836
},
2937

3038
/// Token authentication.
31-
/// ([documentation](https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro/tokens))
3239
Token {
3340
#[configurable(derived)]
3441
token: NatsAuthToken,
3542
},
3643

37-
/// Credentials file authentication.
38-
/// ([documentation](https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro/jwt))
44+
/// Credentials file authentication. (JWT-based)
3945
CredentialsFile {
4046
#[configurable(derived)]
4147
credentials_file: NatsAuthCredentialsFile,
4248
},
4349

4450
/// NKey authentication.
45-
/// ([documentation](https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro/nkey_auth))
4651
Nkey {
4752
#[configurable(derived)]
4853
nkey: NatsAuthNKey,

src/sinks/elasticsearch/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use crate::{
3535
#[configurable_component]
3636
#[derive(Clone, Debug)]
3737
#[serde(deny_unknown_fields, rename_all = "snake_case", tag = "strategy")]
38+
#[configurable(metadata(docs::enum_tag_description = "The authentication strategy to use."))]
3839
pub enum ElasticsearchAuth {
3940
/// HTTP Basic Authentication.
4041
Basic {

src/sinks/prometheus/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::aws::AwsAuthentication;
1414
#[configurable_component]
1515
#[derive(Clone, Debug)]
1616
#[serde(deny_unknown_fields, rename_all = "snake_case", tag = "strategy")]
17+
#[configurable(metadata(docs::enum_tag_description = "The authentication strategy to use."))]
1718
pub enum PrometheusRemoteWriteAuth {
1819
/// HTTP Basic Authentication.
1920
Basic {

src/sinks/socket.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,15 @@ pub struct SocketSinkConfig {
3232
#[configurable_component]
3333
#[derive(Clone, Debug)]
3434
#[serde(tag = "mode", rename_all = "snake_case")]
35+
#[configurable(metadata(docs::enum_tag_description = "The type of socket to use."))]
3536
pub enum Mode {
36-
/// TCP.
37+
/// Send over TCP.
3738
Tcp(#[configurable(transparent)] TcpMode),
3839

39-
/// UDP.
40+
/// Send over UDP.
4041
Udp(#[configurable(transparent)] UdpMode),
4142

42-
/// Unix Domain Socket.
43+
/// Send over a Unix domain socket (UDS).
4344
#[cfg(unix)]
4445
Unix(#[configurable(transparent)] UnixMode),
4546
}

src/sinks/statsd.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,15 @@ pub struct StatsdSinkConfig {
6262
#[configurable_component]
6363
#[derive(Clone, Debug)]
6464
#[serde(tag = "mode", rename_all = "snake_case")]
65+
#[configurable(metadata(docs::enum_tag_description = "The type of socket to use."))]
6566
pub enum Mode {
66-
/// TCP.
67+
/// Send over TCP.
6768
Tcp(#[configurable(transparent)] TcpSinkConfig),
6869

69-
/// UDP.
70+
/// Send over UDP.
7071
Udp(#[configurable(transparent)] StatsdUdpConfig),
7172

72-
/// Unix Domain Socket.
73+
/// Send over a Unix domain socket (UDS).
7374
#[cfg(unix)]
7475
Unix(#[configurable(transparent)] UnixSinkConfig),
7576
}

src/sources/demo_logs.rs

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ pub enum DemoLogsConfigError {
8181
#[derive(Clone, Debug, Derivative)]
8282
#[derivative(Default)]
8383
#[serde(tag = "format", rename_all = "snake_case")]
84+
#[configurable(metadata(
85+
docs::enum_tag_description = "The format of the randomly generated output."
86+
))]
8487
pub enum OutputFormat {
8588
/// Lines are chosen at random from the list specified using `lines`.
8689
Shuffle {

src/sources/file.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,15 @@ fn default_line_delimiter() -> String {
243243
#[configurable_component]
244244
#[derive(Clone, Debug, PartialEq, Eq)]
245245
#[serde(tag = "strategy", rename_all = "snake_case")]
246+
#[configurable(metadata(
247+
docs::enum_tag_description = "The strategy used to uniquely identify files.\n\nThis is important for checkpointing when file rotation is used."
248+
))]
246249
pub enum FingerprintConfig {
247250
/// Read lines from the beginning of the file and compute a checksum over them.
248251
Checksum {
249252
/// Maximum number of bytes to use, from the lines that are read, for generating the checksum.
250-
///
251-
/// TODO: Should we properly expose this in the documentation? There could definitely be value in allowing more
252-
/// bytes to be used for the checksum generation, but we should commit to exposing it rather than hiding it.
253+
// TODO: Should we properly expose this in the documentation? There could definitely be value in allowing more
254+
// bytes to be used for the checksum generation, but we should commit to exposing it rather than hiding it.
253255
#[serde(alias = "fingerprint_bytes")]
254256
bytes: Option<usize>,
255257

@@ -267,7 +269,9 @@ pub enum FingerprintConfig {
267269
lines: usize,
268270
},
269271

270-
/// Use the [device and inode](https://en.wikipedia.org/wiki/Inode) as the identifier.
272+
/// Use the [device and inode][inode] as the identifier.
273+
///
274+
/// [inode]: https://en.wikipedia.org/wiki/Inode
271275
#[serde(rename = "device_and_inode")]
272276
DevInode,
273277
}

src/sources/socket/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub struct SocketConfig {
3030
#[configurable_component]
3131
#[derive(Clone, Debug)]
3232
#[serde(tag = "mode", rename_all = "snake_case")]
33+
#[configurable(metadata(docs::enum_tag_description = "The type of socket to use."))]
3334
#[allow(clippy::large_enum_variant)] // just used for configuration
3435
pub enum Mode {
3536
/// Listen on TCP.
@@ -38,11 +39,11 @@ pub enum Mode {
3839
/// Listen on UDP.
3940
Udp(#[configurable(derived)] udp::UdpConfig),
4041

41-
/// Listen on UDS, in datagram mode. (Unix domain socket)
42+
/// Listen on a Unix domain socket (UDS), in datagram mode.
4243
#[cfg(unix)]
4344
UnixDatagram(#[configurable(derived)] unix::UnixConfig),
4445

45-
/// Listen on UDS, in stream mode. (Unix domain socket)
46+
/// Listen on a Unix domain socket (UDS), in stream mode.
4647
#[cfg(unix)]
4748
#[serde(alias = "unix")]
4849
UnixStream(#[configurable(derived)] unix::UnixConfig),

src/sources/statsd/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ use vector_core::config::LogNamespace;
4242
#[configurable_component(source("statsd"))]
4343
#[derive(Clone, Debug)]
4444
#[serde(tag = "mode", rename_all = "snake_case")]
45+
#[configurable(metadata(docs::enum_tag_description = "The type of socket to use."))]
4546
pub enum StatsdConfig {
4647
/// Listen on TCP.
4748
Tcp(#[configurable(derived)] TcpConfig),

src/sources/syslog.rs

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub struct SyslogConfig {
6767
#[configurable_component]
6868
#[derive(Clone, Debug)]
6969
#[serde(tag = "mode", rename_all = "snake_case")]
70+
#[configurable(metadata(docs::enum_tag_description = "The type of socket to use."))]
7071
pub enum Mode {
7172
/// Listen on TCP.
7273
Tcp {

src/transforms/log_to_metric.rs

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub enum TagConfig {
8888
#[configurable_component]
8989
#[derive(Clone, Debug)]
9090
#[serde(tag = "type", rename_all = "snake_case")]
91+
#[configurable(metadata(docs::enum_tag_description = "The type of metric to create."))]
9192
pub enum MetricTypeConfig {
9293
/// A counter.
9394
Counter(#[configurable(derived)] CounterConfig),

src/transforms/tag_cardinality_limit/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ pub struct TagCardinalityLimitConfig {
2525
#[configurable_component]
2626
#[derive(Clone, Debug)]
2727
#[serde(tag = "mode", rename_all = "snake_case", deny_unknown_fields)]
28+
#[configurable(metadata(
29+
docs::enum_tag_description = "Controls the approach taken for tracking tag cardinality."
30+
))]
2831
pub enum Mode {
2932
/// Tracks cardinality exactly.
3033
///

website/cue/reference/components/sinks/base/aws_s3.cue

+2-1
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,8 @@ base: components: sinks: aws_s3: configuration: {
429429
}
430430
}
431431
method: {
432-
required: true
432+
description: "The framing method."
433+
required: true
433434
type: string: enum: {
434435
bytes: "Event data is not delimited at all."
435436
character_delimited: "Event data is delimited by a single ASCII (7-bit) character."

website/cue/reference/components/sinks/base/azure_blob.cue

+2-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ base: components: sinks: azure_blob: configuration: {
272272
}
273273
}
274274
method: {
275-
required: true
275+
description: "The framing method."
276+
required: true
276277
type: string: enum: {
277278
bytes: "Event data is not delimited at all."
278279
character_delimited: "Event data is delimited by a single ASCII (7-bit) character."

website/cue/reference/components/sinks/base/console.cue

+2-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ base: components: sinks: console: configuration: {
158158
}
159159
}
160160
method: {
161-
required: true
161+
description: "The framing method."
162+
required: true
162163
type: string: enum: {
163164
bytes: "Event data is not delimited at all."
164165
character_delimited: "Event data is delimited by a single ASCII (7-bit) character."

website/cue/reference/components/sinks/base/elasticsearch.cue

+2-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ base: components: sinks: elasticsearch: configuration: {
126126
type: string: {}
127127
}
128128
strategy: {
129-
required: true
129+
description: "The authentication strategy to use."
130+
required: true
130131
type: string: enum: {
131132
aws: "Amazon OpenSearch Service-specific authentication."
132133
basic: "HTTP Basic Authentication."

0 commit comments

Comments
 (0)