From 2bc8e4f93c3b098e3267af6e30149f3d69765acb Mon Sep 17 00:00:00 2001 From: Murad Biashimov Date: Tue, 14 Feb 2023 15:43:53 +0100 Subject: [PATCH] fix(userconfig): string enums parsed as int (#267) --- CHANGELOG.md | 4 +-- Makefile | 6 +--- .../userconfigs/cassandra/cassandra.go | 2 +- api/v1alpha1/userconfigs/grafana/grafana.go | 12 +++---- api/v1alpha1/userconfigs/kafka/kafka.go | 18 +++++------ .../kafka_connect/kafka_connect.go | 8 ++--- api/v1alpha1/userconfigs/mysql/mysql.go | 6 ++-- .../userconfigs/opensearch/opensearch.go | 4 +-- api/v1alpha1/userconfigs/pg/pg.go | 22 ++++++------- api/v1alpha1/userconfigs/redis/redis.go | 8 ++--- config/crd/bases/aiven.io_cassandras.yaml | 2 +- config/crd/bases/aiven.io_kafkas.yaml | 6 ++-- config/crd/bases/aiven.io_mysqls.yaml | 2 +- config/crd/bases/aiven.io_opensearches.yaml | 4 +-- config/crd/bases/aiven.io_postgresqls.yaml | 10 +++--- controllers/postgresql_controller_test.go | 3 ++ docs/docs/{CHANGELOG.md => changelog.md} | 4 +-- docs/docs/contributing/developer-guide.md | 10 ++---- docs/mkdocs.yml | 2 +- userconfigs_generator/generator.go | 17 +++------- userconfigs_generator/generator_test.go | 32 ------------------- userconfigs_generator/pg/pg.go | 22 ++++++------- 22 files changed, 79 insertions(+), 125 deletions(-) rename docs/docs/{CHANGELOG.md => changelog.md} (90%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a68f6c3a..848b0d776 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,8 @@ - Add `serviceIntegrations` on service types. Only `read_replica` type for now. - Add CRD validation rules for immutable fields -- Breaking change: `ip_filter` field is now of `object` type. -- Update user configs for following kinds: PostgreSQL, Kafka, Redis, Clickhouse, OpenSearch, KafkaConnect +- **Breaking change:** `ip_filter` field is now of `object` type. +- **Breaking change:** Update user configs for following kinds: PostgreSQL, Kafka, Redis, Clickhouse, OpenSearch, KafkaConnect. - Add KafkaTopic `min_cleanable_dirty_ratio` config field support - Add Clickhouse `spec.disk_space` property - Use updated aiven-go-client with retries diff --git a/Makefile b/Makefile index 105ef6661..51e9780a5 100644 --- a/Makefile +++ b/Makefile @@ -176,16 +176,12 @@ undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/confi .PHONY: generate-api-reference generate-api-reference: ## Generate CRDS api-reference go run ./docs_generator/... - sed 's/\[MAJOR\.MINOR\.PATCH\] - YYYY-MM-DD/🚧 Under development/g' ./CHANGELOG.md > ./docs/docs/CHANGELOG.md + sed 's/\[MAJOR\.MINOR\.PATCH\] - YYYY-MM-DD/🚧 Under development/g' ./CHANGELOG.md > ./docs/docs/changelog.md .PHONY: serve-docs serve-docs: generate-api-reference ## Run live preview. docker run --rm -it -p 8000:8000 -v ${PWD}/docs:/docs squidfunk/mkdocs-material -.PHONY: generate-docs -generate-docs: ## Generate the documentation website locally. - docker run --rm -it -v ${PWD}/docs:/docs squidfunk/mkdocs-material build - ##@ Build Dependencies ## Location to install dependencies to diff --git a/api/v1alpha1/userconfigs/cassandra/cassandra.go b/api/v1alpha1/userconfigs/cassandra/cassandra.go index 361fe3a60..efeeca7ca 100644 --- a/api/v1alpha1/userconfigs/cassandra/cassandra.go +++ b/api/v1alpha1/userconfigs/cassandra/cassandra.go @@ -79,7 +79,7 @@ type CassandraUserConfig struct { // cassandra configuration values Cassandra *Cassandra `groups:"create,update" json:"cassandra,omitempty"` - // +kubebuilder:validation:Enum=4 + // +kubebuilder:validation:Enum="4" // Cassandra major version CassandraVersion *string `groups:"create,update" json:"cassandra_version,omitempty"` diff --git a/api/v1alpha1/userconfigs/grafana/grafana.go b/api/v1alpha1/userconfigs/grafana/grafana.go index 0090d4ba2..b583cd176 100644 --- a/api/v1alpha1/userconfigs/grafana/grafana.go +++ b/api/v1alpha1/userconfigs/grafana/grafana.go @@ -212,7 +212,7 @@ type ExternalImageStorage struct { // Bucket URL for S3 BucketUrl string `groups:"create,update" json:"bucket_url"` - // +kubebuilder:validation:Enum=s3 + // +kubebuilder:validation:Enum="s3" // Provider type Provider string `groups:"create,update" json:"provider"` @@ -307,7 +307,7 @@ type SmtpServer struct { // Skip verifying server certificate. Defaults to false SkipVerify *bool `groups:"create,update" json:"skip_verify,omitempty"` - // +kubebuilder:validation:Enum=OpportunisticStartTLS;MandatoryStartTLS;NoStartTLS + // +kubebuilder:validation:Enum="OpportunisticStartTLS";"MandatoryStartTLS";"NoStartTLS" // Either OpportunisticStartTLS, MandatoryStartTLS or NoStartTLS. Default is OpportunisticStartTLS. StarttlsPolicy *string `groups:"create,update" json:"starttls_policy,omitempty"` @@ -324,7 +324,7 @@ type GrafanaUserConfig struct { // Enable or disable Grafana alerting functionality AlertingEnabled *bool `groups:"create,update" json:"alerting_enabled,omitempty"` - // +kubebuilder:validation:Enum=alerting;keep_state + // +kubebuilder:validation:Enum="alerting";"keep_state" // Default error or timeout setting for new alerting rules AlertingErrorOrTimeout *string `groups:"create,update" json:"alerting_error_or_timeout,omitempty"` @@ -333,7 +333,7 @@ type GrafanaUserConfig struct { // Max number of alert annotations that Grafana stores. 0 (default) keeps all alert annotations. AlertingMaxAnnotationsToKeep *int `groups:"create,update" json:"alerting_max_annotations_to_keep,omitempty"` - // +kubebuilder:validation:Enum=alerting;no_data;keep_state;ok + // +kubebuilder:validation:Enum="alerting";"no_data";"keep_state";"ok" // Default value for 'no data or null values' for new alerting rules AlertingNodataOrNullvalues *string `groups:"create,update" json:"alerting_nodata_or_nullvalues,omitempty"` @@ -358,7 +358,7 @@ type GrafanaUserConfig struct { // Google Auth integration AuthGoogle *AuthGoogle `groups:"create,update" json:"auth_google,omitempty"` - // +kubebuilder:validation:Enum=lax;strict;none + // +kubebuilder:validation:Enum="lax";"strict";"none" // Cookie SameSite attribute: 'strict' prevents sending cookie for cross-site requests, effectively disabling direct linking from other sites to Grafana. 'lax' is the default value. CookieSamesite *string `groups:"create,update" json:"cookie_samesite,omitempty"` @@ -444,7 +444,7 @@ type GrafanaUserConfig struct { // Auto-assign new users on signup to main organization. Defaults to false UserAutoAssignOrg *bool `groups:"create,update" json:"user_auto_assign_org,omitempty"` - // +kubebuilder:validation:Enum=Viewer;Admin;Editor + // +kubebuilder:validation:Enum="Viewer";"Admin";"Editor" // Set role for new signups. Defaults to Viewer UserAutoAssignOrgRole *string `groups:"create,update" json:"user_auto_assign_org_role,omitempty"` diff --git a/api/v1alpha1/userconfigs/kafka/kafka.go b/api/v1alpha1/userconfigs/kafka/kafka.go index 4487f5db3..372338c92 100644 --- a/api/v1alpha1/userconfigs/kafka/kafka.go +++ b/api/v1alpha1/userconfigs/kafka/kafka.go @@ -48,7 +48,7 @@ type Kafka struct { // Enable auto creation of topics AutoCreateTopicsEnable *bool `groups:"create,update" json:"auto_create_topics_enable,omitempty"` - // +kubebuilder:validation:Enum=gzip;snappy;lz4;zstd;uncompressed;producer + // +kubebuilder:validation:Enum="gzip";"snappy";"lz4";"zstd";"uncompressed";"producer" // Specify the final compression type for a given topic. This configuration accepts the standard compression codecs ('gzip', 'snappy', 'lz4', 'zstd'). It additionally accepts 'uncompressed' which is equivalent to no compression; and 'producer' which means retain the original compression codec set by the producer. CompressionType *string `groups:"create,update" json:"compression_type,omitempty"` @@ -93,7 +93,7 @@ type Kafka struct { // The minimum time a message will remain uncompacted in the log. Only applicable for logs that are being compacted. LogCleanerMinCompactionLagMs *int `groups:"create,update" json:"log_cleaner_min_compaction_lag_ms,omitempty"` - // +kubebuilder:validation:Enum=delete;compact;"compact,delete" + // +kubebuilder:validation:Enum="delete";"compact";"compact,delete" // The default cleanup policy for segments beyond the retention window LogCleanupPolicy *string `groups:"create,update" json:"log_cleanup_policy,omitempty"` @@ -122,7 +122,7 @@ type Kafka struct { // The maximum difference allowed between the timestamp when a broker receives a message and the timestamp specified in the message LogMessageTimestampDifferenceMaxMs *int `groups:"create,update" json:"log_message_timestamp_difference_max_ms,omitempty"` - // +kubebuilder:validation:Enum=CreateTime;LogAppendTime + // +kubebuilder:validation:Enum="CreateTime";"LogAppendTime" // Define whether the timestamp in the message is message create time or log append time. LogMessageTimestampType *string `groups:"create,update" json:"log_message_timestamp_type,omitempty"` @@ -232,11 +232,11 @@ type KafkaAuthenticationMethods struct { // Kafka Connect configuration values type KafkaConnectConfig struct { - // +kubebuilder:validation:Enum=None;All + // +kubebuilder:validation:Enum="None";"All" // Defines what client configurations can be overridden by the connector. Default is None ConnectorClientConfigOverridePolicy *string `groups:"create,update" json:"connector_client_config_override_policy,omitempty"` - // +kubebuilder:validation:Enum=earliest;latest + // +kubebuilder:validation:Enum="earliest";"latest" // What to do when there is no initial offset in Kafka or if the current offset does not exist any more on the server. Default is earliest ConsumerAutoOffsetReset *string `groups:"create,update" json:"consumer_auto_offset_reset,omitempty"` @@ -245,7 +245,7 @@ type KafkaConnectConfig struct { // Records are fetched in batches by the consumer, and if the first record batch in the first non-empty partition of the fetch is larger than this value, the record batch will still be returned to ensure that the consumer can make progress. As such, this is not a absolute maximum. ConsumerFetchMaxBytes *int `groups:"create,update" json:"consumer_fetch_max_bytes,omitempty"` - // +kubebuilder:validation:Enum=read_uncommitted;read_committed + // +kubebuilder:validation:Enum="read_uncommitted";"read_committed" // Transaction read isolation level. read_uncommitted is the default, but read_committed can be used if consume-exactly-once behavior is desired. ConsumerIsolationLevel *string `groups:"create,update" json:"consumer_isolation_level,omitempty"` @@ -284,7 +284,7 @@ type KafkaConnectConfig struct { // The total bytes of memory the producer can use to buffer records waiting to be sent to the broker (defaults to 33554432). ProducerBufferMemory *int `groups:"create,update" json:"producer_buffer_memory,omitempty"` - // +kubebuilder:validation:Enum=gzip;snappy;lz4;zstd;none + // +kubebuilder:validation:Enum="gzip";"snappy";"lz4";"zstd";"none" // Specify the default compression type for producers. This configuration accepts the standard compression codecs ('gzip', 'snappy', 'lz4', 'zstd'). It additionally accepts 'none' which is the default and equivalent to no compression. ProducerCompressionType *string `groups:"create,update" json:"producer_compression_type,omitempty"` @@ -320,11 +320,11 @@ type KafkaRestConfig struct { // The maximum total time to wait for messages for a request if the maximum number of messages has not yet been reached ConsumerRequestTimeoutMs *int `groups:"create,update" json:"consumer_request_timeout_ms,omitempty"` - // +kubebuilder:validation:Enum=all;-1;0;1 + // +kubebuilder:validation:Enum="all";"-1";"0";"1" // The number of acknowledgments the producer requires the leader to have received before considering a request complete. If set to 'all' or '-1', the leader will wait for the full set of in-sync replicas to acknowledge the record. ProducerAcks *string `groups:"create,update" json:"producer_acks,omitempty"` - // +kubebuilder:validation:Enum=gzip;snappy;lz4;zstd;none + // +kubebuilder:validation:Enum="gzip";"snappy";"lz4";"zstd";"none" // Specify the default compression type for producers. This configuration accepts the standard compression codecs ('gzip', 'snappy', 'lz4', 'zstd'). It additionally accepts 'none' which is the default and equivalent to no compression. ProducerCompressionType *string `groups:"create,update" json:"producer_compression_type,omitempty"` diff --git a/api/v1alpha1/userconfigs/kafka_connect/kafka_connect.go b/api/v1alpha1/userconfigs/kafka_connect/kafka_connect.go index 82d37aac7..b2d70fedc 100644 --- a/api/v1alpha1/userconfigs/kafka_connect/kafka_connect.go +++ b/api/v1alpha1/userconfigs/kafka_connect/kafka_connect.go @@ -45,11 +45,11 @@ type IpFilter struct { // Kafka Connect configuration values type KafkaConnect struct { - // +kubebuilder:validation:Enum=None;All + // +kubebuilder:validation:Enum="None";"All" // Defines what client configurations can be overridden by the connector. Default is None ConnectorClientConfigOverridePolicy *string `groups:"create,update" json:"connector_client_config_override_policy,omitempty"` - // +kubebuilder:validation:Enum=earliest;latest + // +kubebuilder:validation:Enum="earliest";"latest" // What to do when there is no initial offset in Kafka or if the current offset does not exist any more on the server. Default is earliest ConsumerAutoOffsetReset *string `groups:"create,update" json:"consumer_auto_offset_reset,omitempty"` @@ -58,7 +58,7 @@ type KafkaConnect struct { // Records are fetched in batches by the consumer, and if the first record batch in the first non-empty partition of the fetch is larger than this value, the record batch will still be returned to ensure that the consumer can make progress. As such, this is not a absolute maximum. ConsumerFetchMaxBytes *int `groups:"create,update" json:"consumer_fetch_max_bytes,omitempty"` - // +kubebuilder:validation:Enum=read_uncommitted;read_committed + // +kubebuilder:validation:Enum="read_uncommitted";"read_committed" // Transaction read isolation level. read_uncommitted is the default, but read_committed can be used if consume-exactly-once behavior is desired. ConsumerIsolationLevel *string `groups:"create,update" json:"consumer_isolation_level,omitempty"` @@ -97,7 +97,7 @@ type KafkaConnect struct { // The total bytes of memory the producer can use to buffer records waiting to be sent to the broker (defaults to 33554432). ProducerBufferMemory *int `groups:"create,update" json:"producer_buffer_memory,omitempty"` - // +kubebuilder:validation:Enum=gzip;snappy;lz4;zstd;none + // +kubebuilder:validation:Enum="gzip";"snappy";"lz4";"zstd";"none" // Specify the default compression type for producers. This configuration accepts the standard compression codecs ('gzip', 'snappy', 'lz4', 'zstd'). It additionally accepts 'none' which is the default and equivalent to no compression. ProducerCompressionType *string `groups:"create,update" json:"producer_compression_type,omitempty"` diff --git a/api/v1alpha1/userconfigs/mysql/mysql.go b/api/v1alpha1/userconfigs/mysql/mysql.go index d69ef76d9..7d86516c6 100644 --- a/api/v1alpha1/userconfigs/mysql/mysql.go +++ b/api/v1alpha1/userconfigs/mysql/mysql.go @@ -57,7 +57,7 @@ type Migration struct { // Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment) IgnoreDbs *string `groups:"create,update" json:"ignore_dbs,omitempty"` - // +kubebuilder:validation:Enum=dump;replication + // +kubebuilder:validation:Enum="dump";"replication" // The migration method to be used (currently supported only by Redis and MySQL service types) Method *string `groups:"create,update" json:"method,omitempty"` @@ -160,7 +160,7 @@ type Mysql struct { // The number of seconds the server waits for activity on an interactive connection before closing it. InteractiveTimeout *int `groups:"create,update" json:"interactive_timeout,omitempty"` - // +kubebuilder:validation:Enum=TempTable;MEMORY + // +kubebuilder:validation:Enum="TempTable";"MEMORY" // The storage engine for in-memory internal temporary tables. InternalTmpMemStorageEngine *string `groups:"create,update" json:"internal_tmp_mem_storage_engine,omitempty"` @@ -297,7 +297,7 @@ type MysqlUserConfig struct { // mysql.conf configuration values Mysql *Mysql `groups:"create,update" json:"mysql,omitempty"` - // +kubebuilder:validation:Enum=8 + // +kubebuilder:validation:Enum="8" // MySQL major version MysqlVersion *string `groups:"create,update" json:"mysql_version,omitempty"` diff --git a/api/v1alpha1/userconfigs/opensearch/opensearch.go b/api/v1alpha1/userconfigs/opensearch/opensearch.go index 4721c733f..af739410b 100644 --- a/api/v1alpha1/userconfigs/opensearch/opensearch.go +++ b/api/v1alpha1/userconfigs/opensearch/opensearch.go @@ -16,7 +16,7 @@ type IndexPatterns struct { // fnmatch pattern Pattern string `groups:"create,update" json:"pattern"` - // +kubebuilder:validation:Enum=alphabetical;creation_date + // +kubebuilder:validation:Enum="alphabetical";"creation_date" // Deletion sorting algorithm SortingAlgorithm *string `groups:"create,update" json:"sorting_algorithm,omitempty"` } @@ -314,7 +314,7 @@ type OpensearchUserConfig struct { // OpenSearch Dashboards settings OpensearchDashboards *OpensearchDashboards `groups:"create,update" json:"opensearch_dashboards,omitempty"` - // +kubebuilder:validation:Enum=1;2 + // +kubebuilder:validation:Enum="1";"2" // OpenSearch major version OpensearchVersion *string `groups:"create,update" json:"opensearch_version,omitempty"` diff --git a/api/v1alpha1/userconfigs/pg/pg.go b/api/v1alpha1/userconfigs/pg/pg.go index 5cd42230d..49f5157a3 100644 --- a/api/v1alpha1/userconfigs/pg/pg.go +++ b/api/v1alpha1/userconfigs/pg/pg.go @@ -57,7 +57,7 @@ type Migration struct { // Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment) IgnoreDbs *string `groups:"create,update" json:"ignore_dbs,omitempty"` - // +kubebuilder:validation:Enum=dump;replication + // +kubebuilder:validation:Enum="dump";"replication" // The migration method to be used (currently supported only by Redis and MySQL service types) Method *string `groups:"create,update" json:"method,omitempty"` @@ -144,7 +144,7 @@ type Pg struct { // This is the amount of time, in milliseconds, to wait on a lock before checking to see if there is a deadlock condition. DeadlockTimeout *int `groups:"create,update" json:"deadlock_timeout,omitempty"` - // +kubebuilder:validation:Enum=lz4;pglz + // +kubebuilder:validation:Enum="lz4";"pglz" // Specifies the default TOAST compression method for values of compressible columns (the default is lz4). DefaultToastCompression *string `groups:"create,update" json:"default_toast_compression,omitempty"` @@ -161,7 +161,7 @@ type Pg struct { // Causes each action executed by autovacuum to be logged if it ran for at least the specified number of milliseconds. Setting this to zero logs all autovacuum actions. Minus-one (the default) disables logging autovacuum actions. LogAutovacuumMinDuration *int `groups:"create,update" json:"log_autovacuum_min_duration,omitempty"` - // +kubebuilder:validation:Enum=TERSE;DEFAULT;VERBOSE + // +kubebuilder:validation:Enum="TERSE";"DEFAULT";"VERBOSE" // Controls the amount of detail written in the server log for each message that is logged. LogErrorVerbosity *string `groups:"create,update" json:"log_error_verbosity,omitempty"` @@ -267,7 +267,7 @@ type Pg struct { // Sets the maximum number of buckets PgStatMonitorPgsmMaxBuckets *int `groups:"create,update" json:"pg_stat_monitor.pgsm_max_buckets,omitempty"` - // +kubebuilder:validation:Enum=all;top;none + // +kubebuilder:validation:Enum="all";"top";"none" // Controls which statements are counted. Specify top to track top-level statements (those issued directly by clients), all to also track nested statements (such as statements invoked within functions), or none to disable statement statistics collection. The default value is top. PgStatStatementsTrack *string `groups:"create,update" json:"pg_stat_statements.track,omitempty"` @@ -285,15 +285,15 @@ type Pg struct { // Specifies the number of bytes reserved to track the currently executing command for each active session. TrackActivityQuerySize *int `groups:"create,update" json:"track_activity_query_size,omitempty"` - // +kubebuilder:validation:Enum=off;on + // +kubebuilder:validation:Enum="off";"on" // Record commit time of transactions. TrackCommitTimestamp *string `groups:"create,update" json:"track_commit_timestamp,omitempty"` - // +kubebuilder:validation:Enum=all;pl;none + // +kubebuilder:validation:Enum="all";"pl";"none" // Enables tracking of function call counts and time used. TrackFunctions *string `groups:"create,update" json:"track_functions,omitempty"` - // +kubebuilder:validation:Enum=off;on + // +kubebuilder:validation:Enum="off";"on" // Enables timing of database I/O calls. This parameter is off by default, because it will repeatedly query the operating system for the current time, which may cause significant overhead on some platforms. TrackIoTiming *string `groups:"create,update" json:"track_io_timing,omitempty"` @@ -318,7 +318,7 @@ type Pgbouncer struct { // Do not allow more than this many server connections per database (regardless of user). Setting it to 0 means unlimited. AutodbMaxDbConnections *int `groups:"create,update" json:"autodb_max_db_connections,omitempty"` - // +kubebuilder:validation:Enum=session;transaction;statement + // +kubebuilder:validation:Enum="session";"transaction";"statement" // PGBouncer pool mode AutodbPoolMode *string `groups:"create,update" json:"autodb_pool_mode,omitempty"` @@ -452,7 +452,7 @@ type PgUserConfig struct { // Enable the pg_stat_monitor extension. Enabling this extension will cause the cluster to be restarted.When this extension is enabled, pg_stat_statements results for utility commands are unreliable PgStatMonitorEnable *bool `groups:"create,update" json:"pg_stat_monitor_enable,omitempty"` - // +kubebuilder:validation:Enum=11;12;13;14;15 + // +kubebuilder:validation:Enum="11";"12";"13";"14";"15" // PostgreSQL major version PgVersion *string `groups:"create,update" json:"pg_version,omitempty"` @@ -492,14 +492,14 @@ type PgUserConfig struct { // Use static public IP addresses StaticIps *bool `groups:"create,update" json:"static_ips,omitempty"` - // +kubebuilder:validation:Enum=quorum;off + // +kubebuilder:validation:Enum="quorum";"off" // Synchronous replication type. Note that the service plan also needs to support synchronous replication. SynchronousReplication *string `groups:"create,update" json:"synchronous_replication,omitempty"` // TimescaleDB extension configuration values Timescaledb *Timescaledb `groups:"create,update" json:"timescaledb,omitempty"` - // +kubebuilder:validation:Enum=aiven;timescale + // +kubebuilder:validation:Enum="aiven";"timescale" // Variant of the PostgreSQL service, may affect the features that are exposed by default Variant *string `groups:"create,update" json:"variant,omitempty"` diff --git a/api/v1alpha1/userconfigs/redis/redis.go b/api/v1alpha1/userconfigs/redis/redis.go index 5c5c3569a..f7c9316ce 100644 --- a/api/v1alpha1/userconfigs/redis/redis.go +++ b/api/v1alpha1/userconfigs/redis/redis.go @@ -57,7 +57,7 @@ type Migration struct { // Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment) IgnoreDbs *string `groups:"create,update" json:"ignore_dbs,omitempty"` - // +kubebuilder:validation:Enum=dump;replication + // +kubebuilder:validation:Enum="dump";"replication" // The migration method to be used (currently supported only by Redis and MySQL service types) Method *string `groups:"create,update" json:"method,omitempty"` @@ -135,7 +135,7 @@ type RedisUserConfig struct { // Name of the basebackup to restore in forked service RecoveryBasebackupName *string `groups:"create,update" json:"recovery_basebackup_name,omitempty"` - // +kubebuilder:validation:Enum=allchannels;resetchannels + // +kubebuilder:validation:Enum="allchannels";"resetchannels" // Determines default pub/sub channels' ACL for new users if ACL is not supplied. When this option is not defined, all_channels is assumed to keep backward compatibility. This option doesn't affect Redis configuration acl-pubsub-default. RedisAclChannelsDefault *string `groups:"create,update" json:"redis_acl_channels_default,omitempty"` @@ -154,7 +154,7 @@ type RedisUserConfig struct { // Counter logarithm factor for volatile-lfu and allkeys-lfu maxmemory-policies RedisLfuLogFactor *int `groups:"create,update" json:"redis_lfu_log_factor,omitempty"` - // +kubebuilder:validation:Enum=noeviction;allkeys-lru;volatile-lru;allkeys-random;volatile-random;volatile-ttl;volatile-lfu;allkeys-lfu + // +kubebuilder:validation:Enum="noeviction";"allkeys-lru";"volatile-lru";"allkeys-random";"volatile-random";"volatile-ttl";"volatile-lfu";"allkeys-lfu" // Redis maxmemory-policy RedisMaxmemoryPolicy *string `groups:"create,update" json:"redis_maxmemory_policy,omitempty"` @@ -168,7 +168,7 @@ type RedisUserConfig struct { // Set number of redis databases. Changing this will cause a restart of redis service. RedisNumberOfDatabases *int `groups:"create,update" json:"redis_number_of_databases,omitempty"` - // +kubebuilder:validation:Enum=off;rdb + // +kubebuilder:validation:Enum="off";"rdb" // When persistence is 'rdb', Redis does RDB dumps each 10 minutes if any key is changed. Also RDB dumps are done according to backup schedule for backup purposes. When persistence is 'off', no RDB dumps and backups are done, so data can be lost at any moment if service is restarted for any reason, or if service is powered off. Also service can't be forked. RedisPersistence *string `groups:"create,update" json:"redis_persistence,omitempty"` diff --git a/config/crd/bases/aiven.io_cassandras.yaml b/config/crd/bases/aiven.io_cassandras.yaml index 19c39fa6e..bed5d2e0d 100644 --- a/config/crd/bases/aiven.io_cassandras.yaml +++ b/config/crd/bases/aiven.io_cassandras.yaml @@ -196,7 +196,7 @@ spec: cassandra_version: description: Cassandra major version enum: - - 4 + - "4" type: string ip_filter: description: Allow incoming connections from CIDR address block, diff --git a/config/crd/bases/aiven.io_kafkas.yaml b/config/crd/bases/aiven.io_kafkas.yaml index a3816463f..6aa671f44 100644 --- a/config/crd/bases/aiven.io_kafkas.yaml +++ b/config/crd/bases/aiven.io_kafkas.yaml @@ -630,9 +630,9 @@ spec: record. enum: - all - - -1 - - 0 - - 1 + - "-1" + - "0" + - "1" type: string producer_compression_type: description: Specify the default compression type for producers. diff --git a/config/crd/bases/aiven.io_mysqls.yaml b/config/crd/bases/aiven.io_mysqls.yaml index 88208ac6a..f59f23a17 100644 --- a/config/crd/bases/aiven.io_mysqls.yaml +++ b/config/crd/bases/aiven.io_mysqls.yaml @@ -475,7 +475,7 @@ spec: mysql_version: description: MySQL major version enum: - - 8 + - "8" type: string private_access: description: Allow access to selected service ports from private diff --git a/config/crd/bases/aiven.io_opensearches.yaml b/config/crd/bases/aiven.io_opensearches.yaml index 6b36c9fe7..279e70cf9 100644 --- a/config/crd/bases/aiven.io_opensearches.yaml +++ b/config/crd/bases/aiven.io_opensearches.yaml @@ -490,8 +490,8 @@ spec: opensearch_version: description: OpenSearch major version enum: - - 1 - - 2 + - "1" + - "2" type: string private_access: description: Allow access to selected service ports from private diff --git a/config/crd/bases/aiven.io_postgresqls.yaml b/config/crd/bases/aiven.io_postgresqls.yaml index bf954c05f..731616f86 100644 --- a/config/crd/bases/aiven.io_postgresqls.yaml +++ b/config/crd/bases/aiven.io_postgresqls.yaml @@ -620,11 +620,11 @@ spec: pg_version: description: PostgreSQL major version enum: - - 11 - - 12 - - 13 - - 14 - - 15 + - "11" + - "12" + - "13" + - "14" + - "15" type: string pgbouncer: description: PGBouncer connection pooling settings diff --git a/controllers/postgresql_controller_test.go b/controllers/postgresql_controller_test.go index 8f601da02..2f0fa95c8 100644 --- a/controllers/postgresql_controller_test.go +++ b/controllers/postgresql_controller_test.go @@ -113,6 +113,9 @@ func pgSpec(serviceName, namespace string) *v1alpha1.PostgreSQL { Tags: map[string]string{"key1": "value1"}, }, UserConfig: &pguserconfig.PgUserConfig{ + // YAML converts string integers to real integers, + // Then it fails with the validation as invalid choice + PgVersion: anyPointer("14"), PublicAccess: &pguserconfig.PublicAccess{ Pg: anyPointer(true), Prometheus: anyPointer(true), diff --git a/docs/docs/CHANGELOG.md b/docs/docs/changelog.md similarity index 90% rename from docs/docs/CHANGELOG.md rename to docs/docs/changelog.md index 2a7ca8273..3d641d8ed 100644 --- a/docs/docs/CHANGELOG.md +++ b/docs/docs/changelog.md @@ -4,8 +4,8 @@ - Add `serviceIntegrations` on service types. Only `read_replica` type for now. - Add CRD validation rules for immutable fields -- Breaking change: `ip_filter` field is now of `object` type. -- Update user configs for following kinds: PostgreSQL, Kafka, Redis, Clickhouse, OpenSearch, KafkaConnect +- **Breaking change:** `ip_filter` field is now of `object` type. +- **Breaking change:** Update user configs for following kinds: PostgreSQL, Kafka, Redis, Clickhouse, OpenSearch, KafkaConnect. - Add KafkaTopic `min_cleanable_dirty_ratio` config field support - Add Clickhouse `spec.disk_space` property - Use updated aiven-go-client with retries diff --git a/docs/docs/contributing/developer-guide.md b/docs/docs/contributing/developer-guide.md index 63d65e924..5d815f147 100644 --- a/docs/docs/contributing/developer-guide.md +++ b/docs/docs/contributing/developer-guide.md @@ -46,15 +46,9 @@ make serve-docs And open the `http://localhost:1313/aiven-operator/` page in your web browser. -The [API Reference](https://aiven.github.io/aiven-operator/docs/api-reference/) section is generated automatically from +The documentation API Reference section is generated automatically from the source code during the documentation deployment. To generate it locally, run the following command: ```shell -make generate-docs -``` - -To build the documentation locally (outputs to `docs/public`), run: - -```shell -make generate-docs +make generate-api-reference ``` diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index be0ed62aa..06079c6ab 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -48,7 +48,7 @@ theme: name: Switch to light mode nav: - Home: index.md - - CHANGELOG.md + - changelog.md - Installation: - installation/prerequisites.md - installation/helm.md diff --git a/userconfigs_generator/generator.go b/userconfigs_generator/generator.go index 305fe013e..8ab3d7727 100644 --- a/userconfigs_generator/generator.go +++ b/userconfigs_generator/generator.go @@ -343,7 +343,11 @@ func addFieldComments(s *jen.Statement, obj *object) *jen.Statement { if len(obj.Enum) != 0 { enum := make([]string, len(obj.Enum)) for i, s := range obj.Enum { - enum[i] = safeEnum(s.Value) + if obj.Type == objectTypeString { + enum[i] = fmt.Sprintf("%q", s.Value) + } else { + enum[i] = s.Value + } } c = append(c, fmt.Sprintf("// +kubebuilder:validation:Enum=%s", strings.Join(enum, ";"))) } @@ -385,17 +389,6 @@ func toCamelCase(s string) string { return strcase.UpperCamelCase(strings.ReplaceAll(s, ".", "_")) } -// safeEnumRe operator sdk won't compile enums with special characters -var safeEnumRe = regexp.MustCompile(`[^\w-]`) - -// safeEnum returns quoted enum if it contains special characters -func safeEnum(s string) string { - if safeEnumRe.MatchString(s) { - return fmt.Sprintf("%q", s) - } - return s -} - // objMaximum validates obj maximum func objMaximum(obj *object) string { if obj.Maximum == nil || obj.Type != objectTypeInteger { diff --git a/userconfigs_generator/generator_test.go b/userconfigs_generator/generator_test.go index 748000341..428454b36 100644 --- a/userconfigs_generator/generator_test.go +++ b/userconfigs_generator/generator_test.go @@ -2,7 +2,6 @@ package main import ( "encoding/json" - "fmt" "os" "testing" @@ -32,37 +31,6 @@ func TestNewUserConfigFile(t *testing.T) { assert.Equal(t, expectedStr, actualStr) } -func TestSafeEnumKeepsOriginal(t *testing.T) { - cases := []string{ - "1", - "foo", - "foo_bar", - "foo-bar", - "Foo", - "foo123", - } - for _, s := range cases { - t.Run(s, func(t *testing.T) { - assert.Equal(t, s, safeEnum(s)) - }) - } -} - -func TestSafeEnumAddsQuotes(t *testing.T) { - cases := []string{ - "foo%p", - "foo{}", - "[foo]", - "foo bar", - "foo,bar", - } - for _, s := range cases { - t.Run(s, func(t *testing.T) { - assert.Equal(t, fmt.Sprintf("%q", s), safeEnum(s)) - }) - } -} - func TestIpFilterString(t *testing.T) { var c pgtestuserconfig.PgTestUserConfig s := `{ diff --git a/userconfigs_generator/pg/pg.go b/userconfigs_generator/pg/pg.go index 8351571b2..5fffca07e 100644 --- a/userconfigs_generator/pg/pg.go +++ b/userconfigs_generator/pg/pg.go @@ -57,7 +57,7 @@ type Migration struct { // Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment) IgnoreDbs *string `groups:"create,update" json:"ignore_dbs,omitempty"` - // +kubebuilder:validation:Enum=dump;replication + // +kubebuilder:validation:Enum="dump";"replication" // The migration method to be used (currently supported only by Redis and MySQL service types) Method *string `groups:"create,update" json:"method,omitempty"` @@ -144,7 +144,7 @@ type Pg struct { // This is the amount of time, in milliseconds, to wait on a lock before checking to see if there is a deadlock condition. DeadlockTimeout *int `groups:"create,update" json:"deadlock_timeout,omitempty"` - // +kubebuilder:validation:Enum=lz4;pglz + // +kubebuilder:validation:Enum="lz4";"pglz" // Specifies the default TOAST compression method for values of compressible columns (the default is lz4). DefaultToastCompression *string `groups:"create,update" json:"default_toast_compression,omitempty"` @@ -161,7 +161,7 @@ type Pg struct { // Causes each action executed by autovacuum to be logged if it ran for at least the specified number of milliseconds. Setting this to zero logs all autovacuum actions. Minus-one (the default) disables logging autovacuum actions. LogAutovacuumMinDuration *int `groups:"create,update" json:"log_autovacuum_min_duration,omitempty"` - // +kubebuilder:validation:Enum=TERSE;DEFAULT;VERBOSE + // +kubebuilder:validation:Enum="TERSE";"DEFAULT";"VERBOSE" // Controls the amount of detail written in the server log for each message that is logged. LogErrorVerbosity *string `groups:"create,update" json:"log_error_verbosity,omitempty"` @@ -267,7 +267,7 @@ type Pg struct { // Sets the maximum number of buckets PgStatMonitorPgsmMaxBuckets *int `groups:"create,update" json:"pg_stat_monitor.pgsm_max_buckets,omitempty"` - // +kubebuilder:validation:Enum=all;top;none + // +kubebuilder:validation:Enum="all";"top";"none" // Controls which statements are counted. Specify top to track top-level statements (those issued directly by clients), all to also track nested statements (such as statements invoked within functions), or none to disable statement statistics collection. The default value is top. PgStatStatementsTrack *string `groups:"create,update" json:"pg_stat_statements.track,omitempty"` @@ -285,15 +285,15 @@ type Pg struct { // Specifies the number of bytes reserved to track the currently executing command for each active session. TrackActivityQuerySize *int `groups:"create,update" json:"track_activity_query_size,omitempty"` - // +kubebuilder:validation:Enum=off;on + // +kubebuilder:validation:Enum="off";"on" // Record commit time of transactions. TrackCommitTimestamp *string `groups:"create,update" json:"track_commit_timestamp,omitempty"` - // +kubebuilder:validation:Enum=all;pl;none + // +kubebuilder:validation:Enum="all";"pl";"none" // Enables tracking of function call counts and time used. TrackFunctions *string `groups:"create,update" json:"track_functions,omitempty"` - // +kubebuilder:validation:Enum=off;on + // +kubebuilder:validation:Enum="off";"on" // Enables timing of database I/O calls. This parameter is off by default, because it will repeatedly query the operating system for the current time, which may cause significant overhead on some platforms. TrackIoTiming *string `groups:"create,update" json:"track_io_timing,omitempty"` @@ -318,7 +318,7 @@ type Pgbouncer struct { // Do not allow more than this many server connections per database (regardless of user). Setting it to 0 means unlimited. AutodbMaxDbConnections *int `groups:"create,update" json:"autodb_max_db_connections,omitempty"` - // +kubebuilder:validation:Enum=session;transaction;statement + // +kubebuilder:validation:Enum="session";"transaction";"statement" // PGBouncer pool mode AutodbPoolMode *string `groups:"create,update" json:"autodb_pool_mode,omitempty"` @@ -452,7 +452,7 @@ type PgTestUserConfig struct { // Enable the pg_stat_monitor extension. Enabling this extension will cause the cluster to be restarted.When this extension is enabled, pg_stat_statements results for utility commands are unreliable PgStatMonitorEnable *bool `groups:"create,update" json:"pg_stat_monitor_enable,omitempty"` - // +kubebuilder:validation:Enum=10;11;12;13;14 + // +kubebuilder:validation:Enum="10";"11";"12";"13";"14" // PostgreSQL major version PgVersion *string `groups:"create,update" json:"pg_version,omitempty"` @@ -492,14 +492,14 @@ type PgTestUserConfig struct { // Use static public IP addresses StaticIps *bool `groups:"create,update" json:"static_ips,omitempty"` - // +kubebuilder:validation:Enum=quorum;off + // +kubebuilder:validation:Enum="quorum";"off" // Synchronous replication type. Note that the service plan also needs to support synchronous replication. SynchronousReplication *string `groups:"create,update" json:"synchronous_replication,omitempty"` // TimescaleDB extension configuration values Timescaledb *Timescaledb `groups:"create,update" json:"timescaledb,omitempty"` - // +kubebuilder:validation:Enum=aiven;timescale + // +kubebuilder:validation:Enum="aiven";"timescale" // Variant of the PostgreSQL service, may affect the features that are exposed by default Variant *string `groups:"create,update" json:"variant,omitempty"`