2
2
3
3
import java .sql .Connection ;
4
4
import java .sql .DriverManager ;
5
- import java .sql .PreparedStatement ;
6
- import java .sql .ResultSet ;
7
5
import java .sql .SQLException ;
8
- import java .sql .Statement ;
9
6
import java .util .Base64 ;
10
7
import java .util .Optional ;
11
8
12
9
import org .apache .commons .lang3 .RandomStringUtils ;
13
10
import org .slf4j .Logger ;
14
11
import org .slf4j .LoggerFactory ;
15
12
13
+ import io .fabric8 .kubernetes .api .model .OwnerReference ;
16
14
import io .fabric8 .kubernetes .api .model .Secret ;
17
15
import io .fabric8 .kubernetes .api .model .SecretBuilder ;
18
16
import io .fabric8 .kubernetes .client .KubernetesClient ;
19
17
import io .javaoperatorsdk .operator .api .reconciler .*;
18
+ import io .javaoperatorsdk .operator .sample .schema .SchemaService ;
20
19
21
20
import static java .lang .String .format ;
22
21
23
22
@ ControllerConfiguration
24
23
public class MySQLSchemaReconciler
25
24
implements Reconciler <MySQLSchema >, ErrorStatusHandler <MySQLSchema > {
26
- static final String USERNAME_FORMAT = "%s-user" ;
27
- static final String SECRET_FORMAT = "%s-secret" ;
28
-
25
+ public static final String SECRET_FORMAT = "%s-secret" ;
26
+ public static final String USERNAME_FORMAT = "%s-user" ;
29
27
private final Logger log = LoggerFactory .getLogger (getClass ());
30
28
31
29
private final KubernetesClient kubernetesClient ;
@@ -40,98 +38,36 @@ public MySQLSchemaReconciler(KubernetesClient kubernetesClient, MySQLDbConfig my
40
38
public UpdateControl <MySQLSchema > reconcile (MySQLSchema schema ,
41
39
Context context ) {
42
40
try (Connection connection = getConnection ()) {
43
- if (!schemaExists (connection , schema .getMetadata ().getName ())) {
44
- try (Statement statement = connection .createStatement ()) {
45
- statement .execute (
46
- format (
47
- "CREATE SCHEMA `%1$s` DEFAULT CHARACTER SET %2$s" ,
48
- schema .getMetadata ().getName (), schema .getSpec ().getEncoding ()));
49
- }
50
-
41
+ var dbSchema = SchemaService .getSchema (connection , schema .getMetadata ().getName ());
42
+ if (!dbSchema .isPresent ()) {
43
+ var schemaName = schema .getMetadata ().getName ();
51
44
String password = RandomStringUtils .randomAlphanumeric (16 );
52
- String userName = String .format (USERNAME_FORMAT , schema .getMetadata ().getName ());
53
- String secretName = String .format (SECRET_FORMAT , schema .getMetadata ().getName ());
54
- try (Statement statement = connection .createStatement ()) {
55
- statement .execute (format ("CREATE USER '%1$s' IDENTIFIED BY '%2$s'" , userName , password ));
56
- }
57
- try (Statement statement = connection .createStatement ()) {
58
- statement .execute (
59
- format ("GRANT ALL ON `%1$s`.* TO '%2$s'" , schema .getMetadata ().getName (), userName ));
60
- }
61
- Secret credentialsSecret =
62
- new SecretBuilder ()
63
- .withNewMetadata ()
64
- .withName (secretName )
65
- .endMetadata ()
66
- .addToData (
67
- "MYSQL_USERNAME" , Base64 .getEncoder ().encodeToString (userName .getBytes ()))
68
- .addToData (
69
- "MYSQL_PASSWORD" , Base64 .getEncoder ().encodeToString (password .getBytes ()))
70
- .build ();
71
- this .kubernetesClient
72
- .secrets ()
73
- .inNamespace (schema .getMetadata ().getNamespace ())
74
- .create (credentialsSecret );
45
+ String secretName = String .format (SECRET_FORMAT , schemaName );
46
+ String userName = String .format (USERNAME_FORMAT , schemaName );
75
47
76
- SchemaStatus status = new SchemaStatus ();
77
- status .setUrl (
78
- format (
79
- "jdbc:mysql://%1$s/%2$s" ,
80
- System .getenv ("MYSQL_HOST" ), schema .getMetadata ().getName ()));
81
- status .setUserName (userName );
82
- status .setSecretName (secretName );
83
- status .setStatus ("CREATED" );
84
- schema .setStatus (status );
48
+ SchemaService .createSchemaAndRelatedUser (connection , schemaName ,
49
+ schema .getSpec ().getEncoding (), userName , password );
50
+ createSecret (schema , password , secretName , userName );
51
+ updateStatusPojo (schema , secretName , userName );
85
52
log .info ("Schema {} created - updating CR status" , schema .getMetadata ().getName ());
86
-
87
53
return UpdateControl .updateStatus (schema );
88
54
}
89
55
return UpdateControl .noUpdate ();
90
56
} catch (SQLException e ) {
91
57
log .error ("Error while creating Schema" , e );
92
- SchemaStatus status = new SchemaStatus ();
93
- status .setUrl (null );
94
- status .setUserName (null );
95
- status .setSecretName (null );
96
- status .setStatus ("ERROR: " + e .getMessage ());
97
- schema .setStatus (status );
98
-
99
- return UpdateControl .updateStatus (schema );
58
+ throw new IllegalStateException (e );
100
59
}
101
60
}
102
61
103
- @ Override
104
- public Optional <MySQLSchema > updateErrorStatus (MySQLSchema resource , RetryInfo retryInfo ,
105
- RuntimeException e ) {
106
-
107
- return Optional .empty ();
108
- }
109
-
110
62
@ Override
111
63
public DeleteControl cleanup (MySQLSchema schema , Context context ) {
112
64
log .info ("Execution deleteResource for: {}" , schema .getMetadata ().getName ());
113
-
114
65
try (Connection connection = getConnection ()) {
115
- if (schemaExists (connection , schema .getMetadata ().getName ())) {
116
- try (Statement statement = connection .createStatement ()) {
117
- statement .execute (format ("DROP DATABASE `%1$s`" , schema .getMetadata ().getName ()));
118
- }
119
- log .info ("Deleted Schema '{}'" , schema .getMetadata ().getName ());
120
-
121
- if (schema .getStatus () != null ) {
122
- if (userExists (connection , schema .getStatus ().getUserName ())) {
123
- try (Statement statement = connection .createStatement ()) {
124
- statement .execute (format ("DROP USER '%1$s'" , schema .getStatus ().getUserName ()));
125
- }
126
- log .info ("Deleted User '{}'" , schema .getStatus ().getUserName ());
127
- }
128
- }
129
-
130
- this .kubernetesClient
131
- .secrets ()
132
- .inNamespace (schema .getMetadata ().getNamespace ())
133
- .withName (schema .getStatus ().getSecretName ())
134
- .delete ();
66
+ var dbSchema = SchemaService .getSchema (connection , schema .getMetadata ().getName ());
67
+ if (dbSchema .isPresent ()) {
68
+ var userName = schema .getStatus () != null ? schema .getStatus ().getUserName () : null ;
69
+ SchemaService .deleteSchemaAndRelatedUser (connection , schema .getMetadata ().getName (),
70
+ userName );
135
71
} else {
136
72
log .info (
137
73
"Delete event ignored for schema '{}', real schema doesn't exist" ,
@@ -144,6 +80,18 @@ public DeleteControl cleanup(MySQLSchema schema, Context context) {
144
80
}
145
81
}
146
82
83
+ @ Override
84
+ public Optional <MySQLSchema > updateErrorStatus (MySQLSchema schema , RetryInfo retryInfo ,
85
+ RuntimeException e ) {
86
+ SchemaStatus status = new SchemaStatus ();
87
+ status .setUrl (null );
88
+ status .setUserName (null );
89
+ status .setSecretName (null );
90
+ status .setStatus ("ERROR: " + e .getMessage ());
91
+ schema .setStatus (status );
92
+ return Optional .empty ();
93
+ }
94
+
147
95
private Connection getConnection () throws SQLException {
148
96
String connectionString =
149
97
format ("jdbc:mysql://%1$s:%2$s" , mysqlDbConfig .getHost (), mysqlDbConfig .getPort ());
@@ -153,26 +101,36 @@ private Connection getConnection() throws SQLException {
153
101
mysqlDbConfig .getPassword ());
154
102
}
155
103
156
- private boolean schemaExists (Connection connection , String schemaName ) throws SQLException {
157
- try (PreparedStatement ps =
158
- connection .prepareStatement (
159
- "SELECT * FROM information_schema.schemata WHERE schema_name = ?" )) {
160
- ps .setString (1 , schemaName );
161
- try (ResultSet resultSet = ps .executeQuery ()) {
162
- // CATALOG_NAME, SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME, SQL_PATH
163
- var exists = resultSet .next ();
164
- return exists ;
165
- }
166
- }
104
+ private void updateStatusPojo (MySQLSchema schema , String secretName , String userName ) {
105
+ SchemaStatus status = new SchemaStatus ();
106
+ status .setUrl (
107
+ format (
108
+ "jdbc:mysql://%1$s/%2$s" ,
109
+ System .getenv ("MYSQL_HOST" ), schema .getMetadata ().getName ()));
110
+ status .setUserName (userName );
111
+ status .setSecretName (secretName );
112
+ status .setStatus ("CREATED" );
113
+ schema .setStatus (status );
167
114
}
168
115
169
- private boolean userExists (Connection connection , String userName ) throws SQLException {
170
- try (PreparedStatement ps =
171
- connection .prepareStatement ("SELECT User FROM mysql.user WHERE User = ?" )) {
172
- ps .setString (1 , userName );
173
- try (ResultSet resultSet = ps .executeQuery ()) {
174
- return resultSet .first ();
175
- }
176
- }
116
+ private void createSecret (MySQLSchema schema , String password , String secretName ,
117
+ String userName ) {
118
+ Secret credentialsSecret =
119
+ new SecretBuilder ()
120
+ .withNewMetadata ()
121
+ .withName (secretName )
122
+ .withOwnerReferences (new OwnerReference ("mysql.sample.javaoperatorsdk/v1" ,
123
+ false , false , "MySQLSchema" ,
124
+ schema .getMetadata ().getName (), schema .getMetadata ().getUid ()))
125
+ .endMetadata ()
126
+ .addToData (
127
+ "MYSQL_USERNAME" , Base64 .getEncoder ().encodeToString (userName .getBytes ()))
128
+ .addToData (
129
+ "MYSQL_PASSWORD" , Base64 .getEncoder ().encodeToString (password .getBytes ()))
130
+ .build ();
131
+ this .kubernetesClient
132
+ .secrets ()
133
+ .inNamespace (schema .getMetadata ().getNamespace ())
134
+ .create (credentialsSecret );
177
135
}
178
136
}
0 commit comments