Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

internal/controller: override desired url if it is provided in the custom config #257

Merged
merged 1 commit into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
4 changes: 0 additions & 4 deletions api/v1alpha1/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,6 @@ func TestSchema_Content(t *testing.T) {
}).
Build()
)
// error
_, _, err := sch.DesiredState(ctx, client, "default")
require.ErrorContains(t, err, "no desired state specified")

sch.SQL = "bar"
u, data, err := sch.DesiredState(ctx, client, "default")
require.NoError(t, err)
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
Loading