Skip to content
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
8 changes: 8 additions & 0 deletions api/synapse/v1alpha1/synapse_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ type SynapseHomeserverValues struct {

// Whether or not to report anonymized homeserver usage statistics
ReportStats bool `json:"reportStats"`

// +kubebuilder:default:=false

// Whether new user registration is allowed. Defaults to false.
EnableRegistration *bool `json:"enableRegistration,omitempty"`
}

// SynapseStatus defines the observed state of Synapse.
Expand Down Expand Up @@ -155,6 +160,9 @@ type SynapseStatusHomeserverConfiguration struct {

// Whether or not to report anonymized homeserver usage statistics
ReportStats bool `json:"reportStats,omitempty"`

// Whether new user registration is enabled
RegistrationEnabled bool `json:"registrationEnabled,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
7 changes: 6 additions & 1 deletion api/synapse/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions bundle/manifests/synapse.opdev.io_synapses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ spec:
Holds the required values for the creation of a homeserver.yaml
configuration file by the Synapse Operator
properties:
enableRegistration:
default: false
description: Whether new user registration is allowed. Defaults
to false.
type: boolean
reportStats:
description: Whether or not to report anonymized homeserver
usage statistics
Expand Down Expand Up @@ -150,6 +155,9 @@ spec:
homeserverConfiguration:
description: Holds configuration information for Synapse
properties:
registrationEnabled:
description: Whether new user registration is enabled
type: boolean
reportStats:
description: Whether or not to report anonymized homeserver usage
statistics
Expand Down
8 changes: 8 additions & 0 deletions config/crd/bases/synapse.opdev.io_synapses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ spec:
Holds the required values for the creation of a homeserver.yaml
configuration file by the Synapse Operator
properties:
enableRegistration:
default: false
description: Whether new user registration is allowed. Defaults
to false.
type: boolean
reportStats:
description: Whether or not to report anonymized homeserver
usage statistics
Expand Down Expand Up @@ -145,6 +150,9 @@ spec:
homeserverConfiguration:
description: Holds configuration information for Synapse
properties:
registrationEnabled:
description: Whether new user registration is enabled
type: boolean
reportStats:
description: Whether or not to report anonymized homeserver usage
statistics
Expand Down
7 changes: 7 additions & 0 deletions internal/controller/synapse/synapse/synapse_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ func (r *SynapseReconciler) setStatusHomeserverConfiguration(
s.Status.HomeserverConfiguration.ServerName = s.Spec.Homeserver.Values.ServerName
s.Status.HomeserverConfiguration.ReportStats = s.Spec.Homeserver.Values.ReportStats

// Set registration enabled status - default to false if not specified
registrationEnabled := false
if s.Spec.Homeserver.Values.EnableRegistration != nil {
registrationEnabled = *s.Spec.Homeserver.Values.EnableRegistration
}
s.Status.HomeserverConfiguration.RegistrationEnabled = registrationEnabled

err := utils.UpdateResourceStatus(ctx, r.Client, s, &synapsev1alpha1.Synapse{})
if err != nil {
log.Error(err, "Error updating Synapse Status")
Expand Down
225 changes: 162 additions & 63 deletions internal/controller/synapse/synapse/synapse_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,20 @@ var _ = Describe("Integration tests for the Synapse controller", Ordered, Label(
},
},
),
Entry(
"when registration option is provided",
map[string]any{
"spec": map[string]any{
"homeserver": map[string]any{
"values": map[string]any{
"serverName": ServerName,
"reportStats": ReportStats,
"enableRegistration": true,
},
},
},
},
),
Entry(
"when optional CreateNewPostgreSQL and ConfigMap Namespace are missing",
map[string]any{
Expand Down Expand Up @@ -408,75 +422,157 @@ var _ = Describe("Integration tests for the Synapse controller", Ordered, Label(
}

When("Specifying the Synapse configuration via Values", func() {
BeforeAll(func() {
initSynapseVariables()
When("Creating a simple Synapse instance", func() {
BeforeAll(func() {
initSynapseVariables()

synapseSpec = synapsev1alpha1.SynapseSpec{
Homeserver: synapsev1alpha1.SynapseHomeserver{
Values: &synapsev1alpha1.SynapseHomeserverValues{
ServerName: ServerName,
ReportStats: ReportStats,
synapseSpec = synapsev1alpha1.SynapseSpec{
Homeserver: synapsev1alpha1.SynapseHomeserver{
Values: &synapsev1alpha1.SynapseHomeserverValues{
ServerName: ServerName,
ReportStats: ReportStats,
},
},
},
IsOpenshift: true,
}
IsOpenshift: true,
}

createSynapseInstance()
})
createSynapseInstance()
})

AfterAll(func() {
cleanupSynapseResources()
})
AfterAll(func() {
cleanupSynapseResources()
})

It("Should should update the Synapse Status", func() {
expectedStatus := synapsev1alpha1.SynapseStatus{
State: "RUNNING",
Reason: "",
HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{
ServerName: ServerName,
ReportStats: ReportStats,
},
}
// Status may need some time to be updated
Eventually(func() synapsev1alpha1.SynapseStatus {
_ = k8sClient.Get(ctx, synapseLookupKey, synapse)
return synapse.Status
}, timeout, interval).Should(Equal(expectedStatus))
})
It("Should should update the Synapse Status", func() {
expectedStatus := synapsev1alpha1.SynapseStatus{
State: "RUNNING",
Reason: "",
HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{
ServerName: ServerName,
ReportStats: ReportStats,
RegistrationEnabled: false, // Default value
},
}
// Status may need some time to be updated
Eventually(func() synapsev1alpha1.SynapseStatus {
_ = k8sClient.Get(ctx, synapseLookupKey, synapse)
return synapse.Status
}, timeout, interval).Should(Equal(expectedStatus))
})

It("Should create a Synapse ConfigMap", func() {
checkResourcePresence(createdConfigMap, synapseLookupKey, expectedOwnerReference)
})
It("Should create a Synapse ConfigMap", func() {
checkResourcePresence(createdConfigMap, synapseLookupKey, expectedOwnerReference)
})

It("Should create a Synapse PVC", func() {
checkResourcePresence(createdPVC, synapseLookupKey, expectedOwnerReference)
})
It("Should create a Synapse PVC", func() {
checkResourcePresence(createdPVC, synapseLookupKey, expectedOwnerReference)
})

It("Should create a Synapse Deployment", func() {
By("Checking that a Synapse Deployment exists and is correctly configured")
checkResourcePresence(createdDeployment, synapseLookupKey, expectedOwnerReference)

By("Checking that initContainer for generating config file contains the required environment variables")
envVars := []corev1.EnvVar{{
Name: "SYNAPSE_SERVER_NAME",
Value: ServerName,
}, {
Name: "SYNAPSE_REPORT_STATS",
Value: utils.BoolToYesNo(ReportStats),
}}
Expect(createdDeployment.Spec.Template.Spec.InitContainers[1].Env).Should(ContainElements(envVars))
})
It("Should create a Synapse Deployment", func() {
By("Checking that a Synapse Deployment exists and is correctly configured")
checkResourcePresence(createdDeployment, synapseLookupKey, expectedOwnerReference)

It("Should create a Synapse Service", func() {
checkResourcePresence(createdService, synapseLookupKey, expectedOwnerReference)
})
By("Checking that initContainer for generating config file contains the required environment variables")
envVars := []corev1.EnvVar{{
Name: "SYNAPSE_SERVER_NAME",
Value: ServerName,
}, {
Name: "SYNAPSE_REPORT_STATS",
Value: utils.BoolToYesNo(ReportStats),
}}
Expect(createdDeployment.Spec.Template.Spec.InitContainers[1].Env).Should(ContainElements(envVars))
})

It("Should create a Synapse ServiceAccount", func() {
checkResourcePresence(createdServiceAccount, synapseLookupKey, expectedOwnerReference)
It("Should create a Synapse Service", func() {
checkResourcePresence(createdService, synapseLookupKey, expectedOwnerReference)
})

It("Should create a Synapse ServiceAccount", func() {
checkResourcePresence(createdServiceAccount, synapseLookupKey, expectedOwnerReference)
})

It("Should create a Synapse RoleBinding", func() {
checkResourcePresence(createdRoleBinding, synapseLookupKey, expectedOwnerReference)
})
})

It("Should create a Synapse RoleBinding", func() {
checkResourcePresence(createdRoleBinding, synapseLookupKey, expectedOwnerReference)
When("Specifying a registration option", func() {
DescribeTable("Should create a ConfigMap with the correct enable_registration setting",
func(enableRegistration *bool, expectedValue bool) {
initSynapseVariables()

synapseSpec = synapsev1alpha1.SynapseSpec{
Homeserver: synapsev1alpha1.SynapseHomeserver{
Values: &synapsev1alpha1.SynapseHomeserverValues{
ServerName: ServerName,
ReportStats: ReportStats,
},
},
IsOpenshift: true,
}

// Only set enableRegistration if provided
if enableRegistration != nil {
synapseSpec.Homeserver.Values.EnableRegistration = enableRegistration
}

createSynapseInstance()

By("Checking that the Synapse Status is correctly updated")
expectedStatus := synapsev1alpha1.SynapseStatus{
State: "RUNNING",
Reason: "",
HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{
ServerName: ServerName,
ReportStats: ReportStats,
RegistrationEnabled: expectedValue,
},
}
// Status may need some time to be updated
Eventually(func() synapsev1alpha1.SynapseStatus {
_ = k8sClient.Get(ctx, synapseLookupKey, synapse)
return synapse.Status
}, timeout, interval).Should(Equal(expectedStatus))

// Verify ConfigMap content
Eventually(func(g Gomega) {
By("Checking that the Synapse ConfigMap exists")
checkResourcePresence(createdConfigMap, synapseLookupKey, expectedOwnerReference)

By("Checking that the ConfigMap contains the enable_registration setting")
ConfigMapData, ok := createdConfigMap.Data["homeserver.yaml"]
g.Expect(ok).Should(BeTrue())

homeserver := make(map[string]any)
g.Expect(yaml.Unmarshal([]byte(ConfigMapData), homeserver)).Should(Succeed())

// Check enable_registration setting
enableRegistrationValue, exists := homeserver["enable_registration"]
if exists {
g.Expect(enableRegistrationValue).Should(Equal(expectedValue))
} else {
// If not present, Synapse defaults to false
g.Expect(expectedValue).Should(BeFalse())
}

// Check enable_registration_without_verification setting
enableRegistrationWithoutVerificationValue, withoutVerificationExists := homeserver["enable_registration_without_verification"]
if expectedValue {
// When registration is enabled, enable_registration_without_verification should also be true
g.Expect(withoutVerificationExists).Should(BeTrue())
g.Expect(enableRegistrationWithoutVerificationValue).Should(BeTrue())
} else {
// When registration is disabled, enable_registration_without_verification should not be present
g.Expect(withoutVerificationExists).Should(BeFalse())
}
}, timeout, interval).Should(Succeed())

cleanupSynapseResources()
},
Entry("when enableRegistration is nil (default)", nil, false),
Entry("when enableRegistration is false", utils.BoolAddr(false), false),
Entry("when enableRegistration is true", utils.BoolAddr(true), true),
)
})
})

Expand Down Expand Up @@ -534,8 +630,9 @@ var _ = Describe("Integration tests for the Synapse controller", Ordered, Label(
State: "RUNNING",
Reason: "",
HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{
ServerName: ServerName,
ReportStats: ReportStats,
ServerName: ServerName,
ReportStats: ReportStats,
RegistrationEnabled: false, // Default value
},
}
// Status may need some time to be updated
Expand Down Expand Up @@ -764,8 +861,9 @@ var _ = Describe("Integration tests for the Synapse controller", Ordered, Label(
State: "RUNNING",
Reason: "",
HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{
ServerName: ServerName,
ReportStats: ReportStats,
ServerName: ServerName,
ReportStats: ReportStats,
RegistrationEnabled: false, // Default value
},
}
// Status may need some time to be updated
Expand Down Expand Up @@ -912,8 +1010,9 @@ var _ = Describe("Integration tests for the Synapse controller", Ordered, Label(
State: "RUNNING",
Reason: "",
HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{
ServerName: ServerName,
ReportStats: ReportStats,
ServerName: ServerName,
ReportStats: ReportStats,
RegistrationEnabled: false, // Default value
},
}
// Status may need some time to be updated
Expand Down
2 changes: 2 additions & 0 deletions internal/templates/synapse_configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ data:
media_store_path: "/data/media_store"
registration_shared_secret: "{{ .Values.RegistrationSharedSecret }}"
report_stats: {{ if .Values.Spec.Homeserver.Values.ReportStats }}yes{{ else }}no{{ end }}
enable_registration: {{ if eq (Deref .Values.Spec.Homeserver.Values.EnableRegistration) true }}true{{ else }}false{{ end }}
{{ if eq (Deref .Values.Spec.Homeserver.Values.EnableRegistration) true }}enable_registration_without_verification: true{{ end }}
macaroon_secret_key: "{{ .Values.MacaroonSecretKey }}"
form_secret: "{{ .Values.FormSecret }}"
signing_key_path: "data/{{ .Values.Spec.Homeserver.Values.ServerName }}.signing.key"
Expand Down
4 changes: 3 additions & 1 deletion internal/templates/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ func ResourceFromTemplate[T any, R any](t *T, name string) (*R, error) {
if err != nil {
return nil, fmt.Errorf("could not read %s template: %v", name, err)
}
tmpl, err := template.New(name).Parse(string(resYaml))
tmpl, err := template.New(name).Funcs(template.FuncMap{
"Deref": func(i *bool) bool { return *i },
}).Parse(string(resYaml))
if err != nil {
return nil, fmt.Errorf("could not parse %s template: %v", name, err)
}
Expand Down