Skip to content

Commit

Permalink
atlas/schema: fixed panic when not set policy.lint (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
giautm authored Oct 24, 2024
1 parent 0df58f9 commit 61ffeb9
Show file tree
Hide file tree
Showing 6 changed files with 497 additions and 12 deletions.
16 changes: 11 additions & 5 deletions internal/controller/atlasschema_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"io"
"net/url"
"path/filepath"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -197,10 +198,8 @@ func (r *AtlasSchemaReconciler) Reconcile(ctx context.Context, req ctrl.Request)
"lint_review": "ERROR",
}
if p := data.Policy; p != nil && p.Lint != nil {
if d := p.Lint.Destructive; d != nil && !d.Error {
// Remove the lint_destructive variable.
// if the lint policy is not set to error.
delete(vars, "lint_destructive")
if d := p.Lint.Destructive; d != nil {
vars["lint_destructive"] = strconv.FormatBool(d.Error)
}
if r := p.Lint.Review; r != "" {
vars["lint_review"] = r
Expand Down Expand Up @@ -367,7 +366,13 @@ func (r *AtlasSchemaReconciler) Reconcile(ctx context.Context, req ctrl.Request)
})
// Run the linting policy.
case data.shouldLint():
if err = r.lint(ctx, wd, data, nil); err != nil {
vars := atlasexec.Vars2{}
if p := data.Policy; p != nil && p.Lint != nil {
if d := p.Lint.Destructive; d != nil {
vars["lint_destructive"] = strconv.FormatBool(d.Error)
}
}
if err = r.lint(ctx, wd, data, vars); err != nil {
reason, msg := "LintPolicyError", err.Error()
res.SetNotReady(reason, msg)
r.recorder.Event(res, corev1.EventTypeWarning, reason, msg)
Expand All @@ -379,6 +384,7 @@ func (r *AtlasSchemaReconciler) Reconcile(ctx context.Context, req ctrl.Request)
}
report, err = cli.SchemaApply(ctx, &atlasexec.SchemaApplyParams{
Env: data.EnvName,
Vars: vars,
To: desiredURL,
TxMode: string(data.TxMode),
AutoApprove: true,
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/atlasschema_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,8 @@ func TestConfigTemplate(t *testing.T) {
err := data.render(&buf)
require.NoError(t, err)
expected := `variable "lint_destructive" {
type = bool
default = true
type = bool
default = false
}
variable "lint_review" {
type = string
Expand Down
6 changes: 1 addition & 5 deletions internal/controller/templates/atlas_schema.tmpl
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
variable "lint_destructive" {
type = bool
{{- with .Policy }}
default = {{ .Lint.Destructive.Error }}
{{- else }}
type = bool
default = false
{{- end }}
}
variable "lint_review" {
type = string
Expand Down
134 changes: 134 additions & 0 deletions test/e2e/testscript/schema-lint-destructive.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
env DB_URL=mysql://root:pass@mysql.${NAMESPACE}:3306/myapp
kubectl apply -f database.yaml
kubectl create secret generic db-creds --from-literal=url=${DB_URL}
# Wait for the DB ready before creating the schema
kubectl-wait-ready -l app=mysql pods

# Create the schema
kubectl apply -f schema.yaml
kubectl-wait-ready AtlasSchema/mysql

# Inspect the schema to ensure it's correct
atlas schema inspect -u ${DB_URL}
cmp stdout schema.hcl

kubectl patch -f schema.yaml --type merge --patch-file patch-remove-bio.yaml

# Wait for the controller to detect the change
exec sleep 10

# Ensure the controller is aware of the change
kubectl wait --for=jsonpath='{.status.conditions[*].reason}'=LintPolicyError --timeout=120s AtlasSchemas/mysql
# Check the error message
kubectl get AtlasSchema/mysql -o jsonpath --template='{.status.conditions[*].message}'
stdout 'destructive changes detected:'
stdout '- Dropping non-virtual column "short_bio"'
-- schema.hcl --
table "users" {
schema = schema.myapp
column "id" {
null = false
type = int
auto_increment = true
}
column "name" {
null = false
type = varchar(255)
}
column "email" {
null = false
type = varchar(255)
}
column "short_bio" {
null = false
type = varchar(255)
}
primary_key {
columns = [column.id]
}
index "email" {
unique = true
columns = [column.email]
}
}
schema "myapp" {
charset = "utf8mb4"
collate = "utf8mb4_0900_ai_ci"
}
-- patch-remove-bio.yaml --
spec:
schema:
sql: |
create table users (
id int not null auto_increment,
name varchar(255) not null,
email varchar(255) unique not null,
primary key (id)
);
-- schema.yaml --
apiVersion: db.atlasgo.io/v1alpha1
kind: AtlasSchema
metadata:
name: mysql
spec:
urlFrom:
secretKeyRef:
name: db-creds
key: url
policy:
lint:
destructive:
error: true
schema:
sql: |
create table users (
id int not null auto_increment,
name varchar(255) not null,
email varchar(255) unique not null,
short_bio varchar(255) not null,
primary key (id)
);
-- database.yaml --
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
selector:
app: mysql
ports:
- name: mysql
port: 3306
targetPort: mysql
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:latest
env:
- name: MYSQL_ROOT_PASSWORD
value: pass
- name: MYSQL_DATABASE
value: myapp
ports:
- containerPort: 3306
name: mysql
startupProbe:
exec:
command: [ "mysql", "-ppass", "-h", "127.0.0.1", "-e", "SELECT 1" ]
failureThreshold: 30
periodSeconds: 10
Loading

0 comments on commit 61ffeb9

Please sign in to comment.