@@ -17,14 +17,21 @@ limitations under the License.
1717package k0smotronio
1818
1919import (
20+ "os"
21+ "os/exec"
22+ "strings"
2023 "testing"
2124
2225 km "github.com/k0sproject/k0smotron/api/k0smotron.io/v1beta1"
2326 "github.com/stretchr/testify/assert"
27+ "github.com/stretchr/testify/require"
28+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29+ "k8s.io/apimachinery/pkg/runtime"
30+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
2431)
2532
2633func TestGetControllerFlags (t * testing.T ) {
27- var tests = []struct {
34+ tests : = []struct {
2835 name string
2936 kmc km.Cluster
3037 result string
@@ -60,3 +67,125 @@ func TestGetControllerFlags(t *testing.T) {
6067 assert .Equal (t , test .result , getControllerFlags (& test .kmc ), test .name )
6168 }
6269}
70+
71+ func TestKineDataSourceURLSubstitution (t * testing.T ) {
72+ if _ , err := exec .LookPath ("sed" ); err != nil {
73+ t .Skip ("sed command not available, skipping test" )
74+ }
75+
76+ tests := []struct {
77+ name string
78+ kineDataSourceURL string
79+ expectedSubstitution string
80+ }{
81+ {
82+ name : "URL without ampersands" ,
83+ kineDataSourceURL : "postgres://user:pass@host:5432/db?sslmode=disable" ,
84+ expectedSubstitution : "postgres://user:pass@host:5432/db?sslmode=disable" ,
85+ },
86+ {
87+ name : "URL with single ampersand" ,
88+ kineDataSourceURL : "postgres://user:pass@host:5432/db?param1=value1¶m2=value2" ,
89+ expectedSubstitution : "postgres://user:pass@host:5432/db?param1=value1¶m2=value2" ,
90+ },
91+ {
92+ name : "URL with multiple ampersands" ,
93+ kineDataSourceURL : "postgres://user:pass@host:5432/db?param1=value1¶m2=value2¶m3=value3" ,
94+ expectedSubstitution : "postgres://user:pass@host:5432/db?param1=value1¶m2=value2¶m3=value3" ,
95+ },
96+ {
97+ name : "URL with ampersand in password" ,
98+ kineDataSourceURL : "postgres://user:pa&ss@host:5432/db" ,
99+ expectedSubstitution : "postgres://user:pa&ss@host:5432/db" ,
100+ },
101+ }
102+
103+ for _ , tc := range tests {
104+ t .Run (tc .name , func (t * testing.T ) {
105+ kmc := & km.Cluster {
106+ ObjectMeta : metav1.ObjectMeta {
107+ Name : "test-cluster" ,
108+ Namespace : "default" ,
109+ },
110+ Spec : km.ClusterSpec {
111+ Service : km.ServiceSpec {
112+ APIPort : 6443 ,
113+ },
114+ KineDataSourceURL : tc .kineDataSourceURL ,
115+ },
116+ }
117+
118+ scheme := runtime .NewScheme ()
119+ require .NoError (t , km .AddToScheme (scheme ))
120+
121+ client := fake .NewClientBuilder ().
122+ WithScheme (scheme ).
123+ WithObjects (kmc ).
124+ Build ()
125+
126+ scope := & kmcScope {
127+ client : client ,
128+ }
129+
130+ cm , err := scope .generateEntrypointCM (kmc )
131+ require .NoError (t , err )
132+
133+ entrypointScript := cm .Data ["k0smotron-entrypoint.sh" ]
134+
135+ // Extract the sed command from the script
136+ lines := strings .Split (entrypointScript , "\n " )
137+ var sedLine string
138+ for _ , line := range lines {
139+ if strings .Contains (line , "sed -i" ) && strings .Contains (line , "K0SMOTRON_KINE_DATASOURCE_URL" ) {
140+ sedLine = strings .TrimSpace (line )
141+ break
142+ }
143+ }
144+ require .NotEmpty (t , sedLine , "sed command not found in entrypoint script" )
145+
146+ testK0sConfig := `apiVersion: k0s.k0sproject.io/v1beta1
147+ kind: ClusterConfig
148+ metadata:
149+ name: k0s
150+ spec:
151+ storage:
152+ type: kine
153+ kine:
154+ dataSource: ` + kineDataSourceURLPlaceholder + `
155+ api:
156+ port: 6443`
157+
158+ tmpFile , err := os .CreateTemp ("" , "k0s-test-*.yaml" )
159+ require .NoError (t , err )
160+ t .Cleanup (func () { os .Remove (tmpFile .Name ()) })
161+
162+ _ , err = tmpFile .WriteString (testK0sConfig )
163+ require .NoError (t , err )
164+ require .NoError (t , tmpFile .Close ())
165+
166+ os .Setenv ("K0SMOTRON_KINE_DATASOURCE_URL" , tc .kineDataSourceURL )
167+ t .Cleanup (func () { os .Unsetenv ("K0SMOTRON_KINE_DATASOURCE_URL" ) })
168+
169+ actualSedCmd := strings .Replace (sedLine , "/etc/k0s/k0s.yaml" , tmpFile .Name (), 1 )
170+
171+ cmd := exec .Command ("sh" , "-c" , actualSedCmd )
172+ cmd .Env = append (os .Environ (), "K0SMOTRON_KINE_DATASOURCE_URL=" + tc .kineDataSourceURL )
173+
174+ output , err := cmd .CombinedOutput ()
175+ if err != nil {
176+ t .Logf ("sed command: %s" , actualSedCmd )
177+ t .Logf ("sed output: %s" , string (output ))
178+ }
179+ require .NoError (t , err , "sed command failed: %s" , string (output ))
180+
181+ modifiedContent , err := os .ReadFile (tmpFile .Name ())
182+ require .NoError (t , err )
183+
184+ modifiedStr := string (modifiedContent )
185+ assert .Contains (t , modifiedStr , tc .expectedSubstitution ,
186+ "Expected URL %q not found in modified config" , tc .expectedSubstitution )
187+ assert .NotContains (t , modifiedStr , kineDataSourceURLPlaceholder ,
188+ "Placeholder should be completely replaced" )
189+ })
190+ }
191+ }
0 commit comments