From ff533c71e61a2bf4e877e65030fcb1e409e5554d Mon Sep 17 00:00:00 2001
From: Harshil Sanjay Jain <harshil.jain@brightspot.com>
Date: Wed, 25 Sep 2024 05:52:23 -0400
Subject: [PATCH] Add validations

---
 .../java/gyro/google/cloudsql/DbAclEntry.java | 18 +++++++++++-----
 .../cloudsql/DbBackupConfiguration.java       |  2 +-
 .../google/cloudsql/DbInsightsConfig.java     |  5 +----
 .../google/cloudsql/DbMaintenanceWindow.java  |  4 ++++
 .../cloudsql/DbPasswordValidationPolicy.java  | 21 +++++++++++++++++++
 .../gyro/google/cloudsql/DbPscConfig.java     | 15 +++++++++++++
 .../google/cloudsql/DbReplicationCluster.java |  2 ++
 .../java/gyro/google/cloudsql/DbSettings.java |  4 +++-
 8 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/src/main/java/gyro/google/cloudsql/DbAclEntry.java b/src/main/java/gyro/google/cloudsql/DbAclEntry.java
index 14e0fb68..e77fb82a 100644
--- a/src/main/java/gyro/google/cloudsql/DbAclEntry.java
+++ b/src/main/java/gyro/google/cloudsql/DbAclEntry.java
@@ -70,11 +70,19 @@ public void copyFrom(AclEntry model) {
 
     @Override
     public String primaryKey() {
-        return String.format(
-            "Acl Entry [Value: %s, Expiration Time: %s, Name: %s]",
-            getValue(),
-            getExpirationTime(),
-            getName());
+        StringBuilder sb = new StringBuilder();
+        sb.append("Acl Entry [Value: ").append(getValue());
+
+        if (getName() != null) {
+            sb.append(", Name: ").append(getName());
+        }
+
+        if (getExpirationTime() != null) {
+            sb.append(", Expiration Time: ").append(getExpirationTime());
+        }
+
+        sb.append("]");
+        return sb.toString();
     }
 
     public AclEntry toAclEntry() {
diff --git a/src/main/java/gyro/google/cloudsql/DbBackupConfiguration.java b/src/main/java/gyro/google/cloudsql/DbBackupConfiguration.java
index b80acb5e..8b40e91b 100644
--- a/src/main/java/gyro/google/cloudsql/DbBackupConfiguration.java
+++ b/src/main/java/gyro/google/cloudsql/DbBackupConfiguration.java
@@ -104,7 +104,7 @@ public void setPointInTimeRecoveryEnabled(Boolean pointInTimeRecoveryEnabled) {
      * The start time for the daily backup configuration in UTC timezone in the 24 hour format - `HH:MM`.
      */
     @Updatable
-    @Regex("[0-2][0-9]:[0-5][0-9]")
+    @Regex("([01][0-9]|2[0-3]):([0-5][0-9])")
     public String getStartTime() {
         return startTime;
     }
diff --git a/src/main/java/gyro/google/cloudsql/DbInsightsConfig.java b/src/main/java/gyro/google/cloudsql/DbInsightsConfig.java
index 1f434429..75abdea0 100644
--- a/src/main/java/gyro/google/cloudsql/DbInsightsConfig.java
+++ b/src/main/java/gyro/google/cloudsql/DbInsightsConfig.java
@@ -110,10 +110,7 @@ public String primaryKey() {
 
     public InsightsConfig toInsightsConfig() {
         InsightsConfig config = new InsightsConfig();
-
-        if (getQueryInsightsEnabled() != null) {
-            config.setQueryInsightsEnabled(getQueryInsightsEnabled());
-        }
+        config.setQueryInsightsEnabled(getQueryInsightsEnabled());
 
         if (getQueryPlansPerMinute() != null) {
             config.setQueryPlansPerMinute(getQueryPlansPerMinute());
diff --git a/src/main/java/gyro/google/cloudsql/DbMaintenanceWindow.java b/src/main/java/gyro/google/cloudsql/DbMaintenanceWindow.java
index c78527a9..f14345bf 100644
--- a/src/main/java/gyro/google/cloudsql/DbMaintenanceWindow.java
+++ b/src/main/java/gyro/google/cloudsql/DbMaintenanceWindow.java
@@ -20,6 +20,7 @@
 import gyro.core.resource.Diffable;
 import gyro.core.resource.Updatable;
 import gyro.core.validation.Range;
+import gyro.core.validation.Required;
 import gyro.core.validation.ValidStrings;
 import gyro.google.Copyable;
 
@@ -35,6 +36,7 @@ public class DbMaintenanceWindow extends Diffable implements Copyable<Maintenanc
      */
     @Range(min = 1, max = 7)
     @Updatable
+    @Required
     public Integer getDay() {
         return day;
     }
@@ -48,6 +50,7 @@ public void setDay(Integer day) {
      */
     @Range(min = 0, max = 23)
     @Updatable
+    @Required
     public Integer getHour() {
         return hour;
     }
@@ -62,6 +65,7 @@ public void setHour(Integer hour) {
      */
     @ValidStrings({ "canary", "stable", "week5" })
     @Updatable
+    @Required
     public String getUpdateTrack() {
         return updateTrack;
     }
diff --git a/src/main/java/gyro/google/cloudsql/DbPasswordValidationPolicy.java b/src/main/java/gyro/google/cloudsql/DbPasswordValidationPolicy.java
index 84e38fe8..62963deb 100644
--- a/src/main/java/gyro/google/cloudsql/DbPasswordValidationPolicy.java
+++ b/src/main/java/gyro/google/cloudsql/DbPasswordValidationPolicy.java
@@ -16,11 +16,16 @@
 
 package gyro.google.cloudsql;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 import com.google.api.services.sqladmin.model.PasswordValidationPolicy;
 import gyro.core.resource.Diffable;
 import gyro.core.resource.Updatable;
 import gyro.core.validation.Required;
 import gyro.core.validation.ValidStrings;
+import gyro.core.validation.ValidationError;
 import gyro.google.Copyable;
 
 public class DbPasswordValidationPolicy extends Diffable implements Copyable<PasswordValidationPolicy> {
@@ -148,4 +153,20 @@ public PasswordValidationPolicy toPasswordValidationPolicy() {
 
         return policy;
     }
+
+    @Override
+    public List<ValidationError> validate(Set<String> configuredFields) {
+        List<ValidationError> errors = new ArrayList<>();
+
+        if (configuredFields.contains("enable-password-policy") && !getEnablePasswordPolicy() &&
+            (getDisallowUsernameSubstring() != null || getMinLength() != null || getComplexity() != null
+                || getPasswordChangeInterval() != null || getReuseInterval() != null)) {
+            errors.add(new ValidationError(
+                this,
+                "enable-password-policy",
+                "'enable-password-policy' needs to be set to 'true' explicitly, in order to enable other password validation options."));
+        }
+
+        return errors;
+    }
 }
diff --git a/src/main/java/gyro/google/cloudsql/DbPscConfig.java b/src/main/java/gyro/google/cloudsql/DbPscConfig.java
index 8431ee72..54184e85 100644
--- a/src/main/java/gyro/google/cloudsql/DbPscConfig.java
+++ b/src/main/java/gyro/google/cloudsql/DbPscConfig.java
@@ -24,6 +24,7 @@
 import gyro.core.resource.Updatable;
 import gyro.core.validation.DependsOn;
 import gyro.core.validation.Required;
+import gyro.core.validation.ValidationError;
 import gyro.google.Copyable;
 
 public class DbPscConfig extends Diffable implements Copyable<PscConfig> {
@@ -82,4 +83,18 @@ public PscConfig toPscConfig() {
 
         return config;
     }
+
+    @Override
+    public List<ValidationError> validate() {
+        List<ValidationError> errors = new ArrayList<>();
+
+        if (!getPscEnabled() && !getAllowedConsumerProjects().isEmpty()) {
+            errors.add(new ValidationError(
+                this,
+                "allowed-consumer-projects",
+                "'psc-enabled' should be set to 'true' in order to set 'allowed-consumer-projects'."));
+        }
+
+        return errors;
+    }
 }
diff --git a/src/main/java/gyro/google/cloudsql/DbReplicationCluster.java b/src/main/java/gyro/google/cloudsql/DbReplicationCluster.java
index 734241a8..da17d90e 100644
--- a/src/main/java/gyro/google/cloudsql/DbReplicationCluster.java
+++ b/src/main/java/gyro/google/cloudsql/DbReplicationCluster.java
@@ -20,6 +20,7 @@
 import gyro.core.resource.Diffable;
 import gyro.core.resource.Output;
 import gyro.core.resource.Updatable;
+import gyro.core.validation.Required;
 import gyro.google.Copyable;
 
 public class DbReplicationCluster extends Diffable implements Copyable<ReplicationCluster> {
@@ -37,6 +38,7 @@ public class DbReplicationCluster extends Diffable implements Copyable<Replicati
      * Only for Enterprise Plus edition instances.
      */
     @Updatable
+    @Required
     public String getFailoverDrReplicaName() {
         return failoverDrReplicaName;
     }
diff --git a/src/main/java/gyro/google/cloudsql/DbSettings.java b/src/main/java/gyro/google/cloudsql/DbSettings.java
index 6b63249d..094cc362 100644
--- a/src/main/java/gyro/google/cloudsql/DbSettings.java
+++ b/src/main/java/gyro/google/cloudsql/DbSettings.java
@@ -58,7 +58,6 @@ public class DbSettings extends Diffable implements Copyable<Settings> {
     private DbMaintenanceWindow maintenanceWindow;
     private DbPasswordValidationPolicy passwordValidationPolicy;
     private String pricingPlan;
-    private Long settingsVersion;
     private DbSqlServerAuditConfig sqlServerAuditConfig;
     private Boolean storageAutoResize;
     private Long storageAutoResizeLimit;
@@ -66,6 +65,9 @@ public class DbSettings extends Diffable implements Copyable<Settings> {
     private String timeZone;
     private Map<String, String> userLabels;
 
+    // Read-only
+    private Long settingsVersion;
+
     /**
      * The activation policy specifies when the instance is activated.
      */