Skip to content
This repository was archived by the owner on May 28, 2021. It is now read-only.

Commit e8328a6

Browse files
author
bcurrerb
committed
Allow MySQL server image default to be specified in operator config
1 parent 83c4da0 commit e8328a6

File tree

7 files changed

+73
-38
lines changed

7 files changed

+73
-38
lines changed

docs/enterprise-edition-example.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Enterprise edition tutorial
2-
This tutorial will explain how to create a mysqlcluster that runs the enterprise version of mysql.
2+
This tutorial will explain how to create a MySQL cluster that runs the enterprise version of MySQL.
33

44
## Prerequisites
55

6-
- The mysql-operator repository checked out locally.
7-
- Access to a Docker registry that contains the enterprise version of mysql.
6+
- The MySQL operator repository checked out locally.
7+
- Access to a Docker registry that contains the enterprise version of MySQL.
88

99
## 01 - Create the Operator
1010
You will need to create the following:
@@ -14,18 +14,17 @@ You will need to create the following:
1414
3. The Operator
1515
4. The Agent ServiceAccount & RoleBinding
1616

17-
The creation of these resources can be achieved by following the [introductory tutorial][1]; return here before creating a MySQL Cluster.
17+
The creation of these resources can be achieved by following the [introductory tutorial][1]; return here before creating a MySQL cluster.
1818

1919
## 02 - Create a secret with registry credentials
20-
To be able to pull the mysql enterprise edition from docker it is necessary to provide credentials, these credentials must be supplied in the form of a Kubernetes secret.
20+
To be able to pull the MySQL Enterprise Edition from Docker it is necessary to provide credentials, these credentials must be supplied in the form of a Kubernetes secret.
2121

22-
- The name of the secret `myregistrykey` must match the name in the `imagepullsecrets` which we will specify in the cluster config in step 03.
23-
- The secret must be created in the same namespace as the MySQL Cluster which we will make in step 03. It must also be in the same namespace as the RBAC permissions created in step 01.
24-
- If you are pulling the mysql enterprise image from a different registry then the secret must contain the relevant credentials for that registry.
22+
- Remember the name of the secret *myregistrykey* as this will need to be used in step 03 when creating the cluster.
23+
- If you are pulling the MySQL Enterprise image from a different registry than the one in the example then the secret must contain the relevant credentials for that registry.
2524

26-
>For alternative ways to create Kubernetes secretes see their documentation on [creating secrets from docker configs](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) or [creating secrets manually](https://kubernetes.io/docs/concepts/containers/images/#creating-a-secret-with-a-docker-config).
25+
>For alternative ways to create Kubernetes secrets see their documentation on [creating secrets from Docker configs](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) or [creating secrets manually](https://kubernetes.io/docs/concepts/containers/images/#creating-a-secret-with-a-docker-config).
2726
28-
Enter your credentials into the following command and execute it to create a Kubernetes secret that will enable pulling images from the Docker store. add the `-n` flag to specify a namespace if you do not want to use the default namespace.
27+
Enter your credentials into the following command and execute it to create a Kubernetes secret that will enable pulling images from the Docker store. Add the `-n` flag to specify a namespace if you do not want to use the default namespace.
2928
```
3029
kubectl create secret docker-registry myregistrykey \
3130
--docker-server=https://index.docker.io/v1/ \
@@ -36,10 +35,10 @@ kubectl create secret docker-registry myregistrykey \
3635
## 03 - Create your MySQL Cluster
3736
Finally, create your MySQL Cluster with the required specifications entered under `spec:`
3837

39-
- The mysqlServer field should be the path to a registry containing the enterprise edition of MySQL.
40-
- The imagePullSecret: name: Should be the name of a Kubernetes secret in the same namespace that contains your credentials for the docker registry.
41-
- The version to be used must be specified, without this, a default version is used which is **not** guaranteed to match an available image of MySQL Enterprise.
42-
- The namespace of the cluster must match the namespace of the secret we created in step 02.
38+
- The `repository:` field should be the path to a Docker registry containing the enterprise edition of MySQL. If this is ommited, the default is taken from the MySQL operator field `defaultMysqlServer:` which you can also specify.
39+
- The `imagePullSecrets`: field allows you to specify a list of Kubernetes secret names. These secret(s) should contains your credentials for the Docker registry.
40+
- The version to be used should be specified, without this, a default version is used which is **not** guaranteed to match an available image of MySQL Enterprise.
41+
- The namespace of the cluster must match the namespace of the RBAC permissions created in step 01.
4342
```
4443
kubectl apply -f examples/cluster/cluster-enterprise-version.yaml
4544
```
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
apiVersion: mysql.oracle.com/v1alpha1
22
kind: Cluster
33
metadata:
4-
name: mysql
5-
namespace: default
4+
name: mysql-enterprise
65
spec:
76
version: "8.0.11"
8-
mysqlServer: store/oracle/mysql-enterprise-server
9-
imagePullSecret:
10-
name: myregistrykey
7+
repository: store/oracle/mysql-enterprise-server
8+
imagePullSecrets:
9+
- name: myregistrykey

pkg/apis/mysql/v1alpha1/helpers.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ func getOperatorVersionLabel(labelMap map[string]string) string {
5454

5555
// EnsureDefaults will ensure that if a user omits any fields in the
5656
// spec that are required, we set some sensible defaults.
57-
// For example a user can choose to omit the version
58-
// and number of members.
57+
// For example a user can choose to omit the version and number of
58+
// members. MySQL server image default is defined through operator spec.
5959
func (c *Cluster) EnsureDefaults() *Cluster {
6060
if c.Spec.Members == 0 {
6161
c.Spec.Members = defaultMembers
@@ -69,10 +69,6 @@ func (c *Cluster) EnsureDefaults() *Cluster {
6969
c.Spec.Version = DefaultVersion
7070
}
7171

72-
if c.Spec.MySQLServerImage == "" {
73-
c.Spec.MySQLServerImage = MysqlServer
74-
}
75-
7672
return c
7773
}
7874

pkg/apis/mysql/v1alpha1/types.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ const MinimumMySQLVersion = "8.0.11"
2828
type ClusterSpec struct {
2929
// Version defines the MySQL Docker image version.
3030
Version string `json:"version"`
31-
// MySQLServerImage defines the image to be pulled for the mysqlServer.
32-
MySQLServerImage string `json:"mysqlServer"`
31+
// Repository defines the image to be pulled for the MySQL server.
32+
Repository string `json:"repository"`
3333
// ImagePullSecret defines the name of the secret that contains the
34-
// required credentials for pulling the MySQLServerImage.
35-
ImagePullSecret *v1.LocalObjectReference `json:"imagePullSecret"`
34+
// required credentials for pulling from the specified Repository.
35+
ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecret"`
3636
// Members defines the number of MySQL instances in a cluster
3737
Members int32 `json:"members,omitempty"`
3838
// BaseServerID defines the base number used to create unique server_id

pkg/options/operator/options.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,16 @@ import (
2929
)
3030

3131
const (
32-
mysqlAgent = "iad.ocir.io/oracle/mysql-agent"
32+
mysqlAgent = "iad.ocir.io/oracle/mysql-agent"
33+
mysqlServer = "mysql/mysql-server"
3334
)
3435

3536
// Images is the configuration of required MySQLOperator images. Remember to configure the appropriate
36-
// credentials for the target repositories. Image for mysqlServer is specified in ClusterSpec
37+
// credentials for the target repositories. The DefaultMySQLServerImage can be overridden on a per-cluster
38+
// basis by setting the Repository field.
3739
type Images struct {
38-
MySQLAgentImage string `yaml:"mysqlAgent"`
40+
MySQLAgentImage string `yaml:"mysqlAgent"`
41+
DefaultMySQLServerImage string `yaml:"defaultMysqlServer"`
3942
}
4043

4144
// MySQLOperatorOpts holds the options for the MySQLOperator.
@@ -107,6 +110,9 @@ func (s *MySQLOperatorOpts) EnsureDefaults() {
107110
if s.Images.MySQLAgentImage == "" {
108111
s.Images.MySQLAgentImage = mysqlAgent
109112
}
113+
if s.Images.DefaultMySQLServerImage == "" {
114+
s.Images.DefaultMySQLServerImage = mysqlServer
115+
}
110116
if s.MinResyncPeriod.Duration <= 0 {
111117
s.MinResyncPeriod = metav1.Duration{Duration: 12 * time.Hour}
112118
}
@@ -117,6 +123,7 @@ func (s *MySQLOperatorOpts) AddFlags(fs *pflag.FlagSet) *pflag.FlagSet {
117123
fs.StringVar(&s.KubeConfig, "kubeconfig", s.KubeConfig, "Path to Kubeconfig file with authorization and master location information.")
118124
fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig).")
119125
fs.StringVar(&s.Namespace, "namespace", metav1.NamespaceAll, "The namespace for which the MySQL operator manages MySQL clusters. Defaults to all.")
126+
fs.StringVar(&s.Images.DefaultMySQLServerImage, "mysql-server-image", mysqlServer, "The name of the default target for the 'mysql-server' image (can be overridden on a per-cluster basis). Defaults to: "+mysqlServer+".")
120127
fs.StringVar(&s.Images.MySQLAgentImage, "mysql-agent-image", s.Images.MySQLAgentImage, "The name of the target 'mysql-agent' image. Defaults to: iad.ocir.io/oracle/mysql-agent.")
121128
fs.DurationVar(&s.MinResyncPeriod.Duration, "min-resync-period", s.MinResyncPeriod.Duration, "The resync period in reflectors will be random between MinResyncPeriod and 2*MinResyncPeriod.")
122129
return fs

pkg/resources/statefulsets/statefulset.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,15 @@ func NewForCluster(cluster *v1alpha1.Cluster, images operatoropts.Images, servic
344344
})
345345
}
346346

347+
var serverImage string
348+
if cluster.Spec.Repository != "" {
349+
serverImage = cluster.Spec.Repository
350+
} else {
351+
serverImage = images.DefaultMySQLServerImage
352+
}
353+
347354
containers := []v1.Container{
348-
mysqlServerContainer(cluster, cluster.Spec.MySQLServerImage, rootPassword, members, baseServerID),
355+
mysqlServerContainer(cluster, serverImage, rootPassword, members, baseServerID),
349356
mysqlAgentContainer(cluster, images.MySQLAgentImage, rootPassword, members)}
350357

351358
podLabels := map[string]string{
@@ -399,8 +406,8 @@ func NewForCluster(cluster *v1alpha1.Cluster, images operatoropts.Images, servic
399406
},
400407
}
401408

402-
if cluster.Spec.ImagePullSecret != nil {
403-
ss.Spec.Template.Spec.ImagePullSecrets = append(ss.Spec.Template.Spec.ImagePullSecrets, *cluster.Spec.ImagePullSecret)
409+
if cluster.Spec.ImagePullSecrets != nil {
410+
ss.Spec.Template.Spec.ImagePullSecrets = append(ss.Spec.Template.Spec.ImagePullSecrets, cluster.Spec.ImagePullSecrets...)
404411
}
405412
if cluster.Spec.VolumeClaimTemplate != nil {
406413
ss.Spec.VolumeClaimTemplates = append(ss.Spec.VolumeClaimTemplates, *cluster.Spec.VolumeClaimTemplate)

pkg/resources/statefulsets/statefulset_test.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,10 +292,10 @@ func TestClusterWithOnlyMysqlServerResourceRequirements(t *testing.T) {
292292
func TestClusterEnterpriseImage(t *testing.T) {
293293
cluster := &v1alpha1.Cluster{
294294
Spec: v1alpha1.ClusterSpec{
295-
MySQLServerImage: "some/image/path",
296-
ImagePullSecret: &corev1.LocalObjectReference{
295+
Repository: "some/image/path",
296+
ImagePullSecrets: []corev1.LocalObjectReference{{
297297
Name: "someSecretName",
298-
},
298+
}},
299299
},
300300
}
301301
cluster.EnsureDefaults()
@@ -320,3 +320,30 @@ func TestClusterNoImage(t *testing.T) {
320320

321321
assert.Equal(t, v1alpha1.MysqlServer+":"+v1alpha1.DefaultVersion, si)
322322
}
323+
324+
func TestClusterNoImageOperatorDefault(t *testing.T) {
325+
cluster := &v1alpha1.Cluster{}
326+
cluster.EnsureDefaults()
327+
328+
operatorConf := mockOperatorConfig()
329+
operatorConf.Images.DefaultMySQLServerImage = "newDefaultImage"
330+
statefulSet := NewForCluster(cluster, operatorConf.Images, "mycluster")
331+
332+
si := statefulSet.Spec.Template.Spec.Containers[0].Image
333+
334+
assert.Equal(t, "newDefaultImage:"+v1alpha1.DefaultVersion, si)
335+
}
336+
337+
func TestClusterDefaultOverride(t *testing.T) {
338+
cluster := &v1alpha1.Cluster{}
339+
cluster.EnsureDefaults()
340+
cluster.Spec.Repository = "OverrideDefaultImage"
341+
342+
operatorConf := mockOperatorConfig()
343+
operatorConf.Images.DefaultMySQLServerImage = "newDefaultImage"
344+
statefulSet := NewForCluster(cluster, operatorConf.Images, "mycluster")
345+
346+
si := statefulSet.Spec.Template.Spec.Containers[0].Image
347+
348+
assert.Equal(t, "OverrideDefaultImage:"+v1alpha1.DefaultVersion, si)
349+
}

0 commit comments

Comments
 (0)