Skip to content

Commit

Permalink
internal/controller: override desired url if it is provided in the cu…
Browse files Browse the repository at this point in the history
…stom config
  • Loading branch information
datdao committed Jan 16, 2025
1 parent 424d10f commit 604966a
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 9 deletions.
2 changes: 1 addition & 1 deletion api/v1alpha1/atlasschema_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ func (s Schema) DesiredState(ctx context.Context, r client.Reader, ns string) (*
}
return u, nil, err
}
return nil, nil, fmt.Errorf("no desired state specified")
return nil, nil, nil
}

// AsBlock returns the HCL block representation of the diff.
Expand Down
11 changes: 6 additions & 5 deletions internal/controller/atlasschema_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func (r *AtlasSchemaReconciler) Reconcile(ctx context.Context, req ctrl.Request)
r.recordErrEvent(res, err)
return result(err)
}
switch desiredURL := data.Desired.String(); {
switch desiredURL := data.targetURL(); {
// The resource is connected to Atlas Cloud.
case whoami != nil:
err = editAtlasHCL(func(m *managedData) {
Expand All @@ -257,7 +257,7 @@ func (r *AtlasSchemaReconciler) Reconcile(ctx context.Context, req ctrl.Request)
// This is to ensure that the schema is in sync with the Atlas Cloud.
// And the schema is available for the Atlas CLI (on local machine)
// to modify or approve the changes.
if data.Desired.Scheme == dbv1alpha1.SchemaTypeFile {
if data.Desired != nil && data.Desired.Scheme == dbv1alpha1.SchemaTypeFile {
tag, err := cli.SchemaInspect(ctx, &atlasexec.SchemaInspectParams{
Env: data.EnvName,
URL: desiredURL,
Expand Down Expand Up @@ -794,9 +794,6 @@ func (d *managedData) render(w io.Writer) error {
if d.EnvName == "" {
return errors.New("env name is not set")
}
if d.Desired == nil {
return errors.New("the desired state is not set")
}
env := searchBlock(f.Body(), hclwrite.NewBlock("env", []string{d.EnvName}))
if env == nil {
return fmt.Errorf("env block %q is not found", d.EnvName)
Expand All @@ -808,6 +805,10 @@ func (d *managedData) render(w io.Writer) error {
if b.GetAttribute("dev") == nil {
return errors.New("dev url is not set")
}
schema := searchBlock(b, hclwrite.NewBlock("schema", nil))
if schema == nil && b.GetAttribute("src") == nil {
return errors.New("the desired state is not set")
}
if _, err := f.WriteTo(w); err != nil {
return err
}
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 @@ -134,7 +134,7 @@ func TestReconcile_Reconcile(t *testing.T) {
},
})
// Third reconcile, return error for missing schema
assert(ctrl.Result{RequeueAfter: 5000000000}, false, "ReadSchema", "no desired state specified")
assert(ctrl.Result{}, false, "CreatingWorkingDir", "the desired state is not set")
// Add schema,
h.patch(t, &dbv1alpha1.AtlasSchema{
ObjectMeta: meta,
Expand All @@ -160,7 +160,7 @@ func TestReconcile_Reconcile(t *testing.T) {
// Check the events generated by the controller
require.Equal(t, []string{
"Warning TransientErr no target database defined",
"Warning TransientErr no desired state specified",
"Warning Error the desired state is not set",
"Normal Applied Applied schema",
"Normal Applied Applied schema",
}, h.events())
Expand Down
2 changes: 1 addition & 1 deletion internal/controller/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (r *AtlasSchemaReconciler) lint(ctx context.Context, wd *atlasexec.WorkingD
plans, err := cli.SchemaApplySlice(ctx, &atlasexec.SchemaApplyParams{
Env: data.EnvName,
Vars: vars,
To: data.Desired.String(),
To: data.targetURL(),
DryRun: true, // Dry run to get pending changes.
})
if err != nil {
Expand Down
193 changes: 193 additions & 0 deletions test/e2e/testscript/schema-composite.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
env SCHEMA_DB_URL=postgres://root:pass@postgres.${NAMESPACE}:5432/postgres?sslmode=disable
env SCHEMA_DB_DEV_URL=postgres://root:pass@postgres.${NAMESPACE}:5433/postgres?sslmode=disable
kubectl apply -f database.yaml
kubectl create secret generic schema-db-creds --from-literal=url=${SCHEMA_DB_URL}
kubectl create configmap schema-db-dev-creds --from-literal=url=${SCHEMA_DB_DEV_URL}
# Create the secret to store ATLAS_TOKEN
kubectl create secret generic atlas-token --from-literal=ATLAS_TOKEN=${ATLAS_TOKEN}

# Wait for the first pod created
kubectl-wait-available deploy/postgres
# Wait for the DB ready before creating the schema
kubectl-wait-ready -l app=postgres pods

# Create the schema
kubectl apply -f schema.yaml
kubectl wait --for=jsonpath='{.status.conditions[*].reason}'=Applied --timeout=500s AtlasSchemas/sample

atlas schema inspect -u ${SCHEMA_DB_URL}
cmp stdout schema.hcl

-- schema.yaml --
apiVersion: db.atlasgo.io/v1alpha1
kind: AtlasSchema
metadata:
name: sample
spec:
envName: "test"
cloud:
repo: atlas-operator
tokenFrom:
secretKeyRef:
name: atlas-token
key: ATLAS_TOKEN
vars:
- key: "db_url"
valueFrom:
secretKeyRef:
name: schema-db-creds
key: url
- key: "dev_db_url"
valueFrom:
configMapKeyRef:
name: schema-db-dev-creds
key: url
config: |
variable "db_url" {
type = string
}
variable "dev_db_url" {
type = string
}
data "external_schema" "users" {
program = ["echo", "CREATE TABLE users (id int not null, name varchar(255) not null, email varchar(255) not null, short_bio varchar(255) not null, PRIMARY KEY (id));"]
}
data "external_schema" "posts" {
program = ["echo", "CREATE TABLE posts (id int not null, title varchar(255) not null, body text not null, PRIMARY KEY (id));"]
}
data "composite_schema" "app" {
schema "public" {
url = data.external_schema.users.url
}
schema "public" {
url = data.external_schema.posts.url
}
}
env "test" {
schema {
src = data.composite_schema.app.url
}
url = var.db_url
dev = var.dev_db_url
}
-- schema.hcl --
table "posts" {
schema = schema.public
column "id" {
null = false
type = integer
}
column "title" {
null = false
type = character_varying(255)
}
column "body" {
null = false
type = text
}
primary_key {
columns = [column.id]
}
}
table "users" {
schema = schema.public
column "id" {
null = false
type = integer
}
column "name" {
null = false
type = character_varying(255)
}
column "email" {
null = false
type = character_varying(255)
}
column "short_bio" {
null = false
type = character_varying(255)
}
primary_key {
columns = [column.id]
}
}
schema "public" {
comment = "standard public schema"
}
-- database.yaml --
apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
selector:
app: postgres
ports:
- name: postgres
port: 5432
targetPort: postgres
- name: postgres-dev
port: 5433
targetPort: postgres-dev
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
selector:
matchLabels:
app: postgres
replicas: 1
template:
metadata:
labels:
app: postgres
spec:
securityContext:
runAsNonRoot: true
runAsUser: 999
containers:
- name: postgres
image: postgres:15.4
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
env:
- name: POSTGRES_PASSWORD
value: pass
- name: POSTGRES_USER
value: root
ports:
- containerPort: 5432
name: postgres
startupProbe:
exec:
command: [ "pg_isready" ]
failureThreshold: 30
periodSeconds: 10
- name: postgres-dev
image: postgres:15.4
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
env:
- name: POSTGRES_PASSWORD
value: pass
- name: POSTGRES_USER
value: root
- name: PGPORT
value: "5433"
ports:
- containerPort: 5433
name: postgres-dev
startupProbe:
exec:
command: [ "pg_isready" ]
failureThreshold: 30
periodSeconds: 10

0 comments on commit 604966a

Please sign in to comment.