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

Refactor components to use default labels and owner references from etcd #559

Merged
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9e5bb9b
Refactor: Update `configmap` component to use default labels and owne…
seshachalam-yv Mar 18, 2023
99873dc
Refactor: Update `lease` component to use default labels and owner re…
seshachalam-yv Mar 18, 2023
5f5e90d
Refactor: Update `poddisruptionbudget` component to use default label…
seshachalam-yv Mar 18, 2023
4b557ee
Refactor: Update `service` component to use default labels and owner …
seshachalam-yv Mar 18, 2023
aa12001
Refactor: Update `statefulset` component to use default labels and ow…
seshachalam-yv Mar 18, 2023
40fe384
Updated the E2E test suite to use the appropriate component names.
seshachalam-yv Apr 18, 2023
3a879d0
Addressed review comment from Madhav about OwnerReferences.
seshachalam-yv Apr 19, 2023
cfd9b47
This commit addresses the review comment from Shreyas about improving…
seshachalam-yv Apr 19, 2023
41835d7
Refactor API version to use 'druidv1alpha1.GroupVersion.String()' ins…
seshachalam-yv Apr 20, 2023
f697e05
Addressed review comment
seshachalam-yv Apr 26, 2023
4f94694
Renamed function name checkConfigmap to checkConfigMap
seshachalam-yv Apr 27, 2023
dc67736
Renamed ServerPort to PeerPort
seshachalam-yv Apr 27, 2023
50eaa9e
Removed arguments of emptyPodDisruptionBudget and reused name, namesp…
seshachalam-yv Apr 27, 2023
d8a4a13
Constructing a etcdconfig YAML using strut instead of string string c…
seshachalam-yv Apr 27, 2023
175b5df
Used default labels for lease component
seshachalam-yv Apr 27, 2023
56efc9f
Update log message with OwnerReference <name>:<uid>
seshachalam-yv Apr 27, 2023
7d2832f
make revendor
seshachalam-yv Apr 27, 2023
a5a9440
fix failing test
seshachalam-yv Apr 27, 2023
a55c6e7
Removed checkPDBMetadata function
seshachalam-yv Apr 27, 2023
bf89a7f
minor refactoring to configmap component
unmarshall Apr 27, 2023
683f0c1
Removed JSON tags
seshachalam-yv May 2, 2023
7840a6f
Rebase with master
seshachalam-yv May 31, 2023
78bd923
Fix integration test
seshachalam-yv May 31, 2023
c69fe26
Fix failing test
seshachalam-yv Jun 1, 2023
31c66b7
Apply suggestions from code review
seshachalam-yv Jun 5, 2023
539e7d0
Addressed review feedback
seshachalam-yv Jun 5, 2023
6edd92d
Apply suggestions from code review
seshachalam-yv Jun 9, 2023
975e66f
Addressed review comment
seshachalam-yv Jun 9, 2023
ea9f5ae
Update pkg/component/etcd/configmap/values.go
seshachalam-yv Jun 9, 2023
b85a38b
Fixed typo
seshachalam-yv Jun 9, 2023
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
1 change: 0 additions & 1 deletion api/v1alpha1/types_etcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ var _ = Describe("Etcd", func() {

Context("GetAsOwnerReference", func() {
It("should return an OwnerReference object that represents the current Etcd instance", func() {

expected := metav1.OwnerReference{
APIVersion: GroupVersion.String(),
Kind: "Etcd",
Expand Down
2 changes: 1 addition & 1 deletion controllers/compaction/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ func (r *Reconciler) createCompactionJob(ctx context.Context, logger logr.Logger
Labels: getLabels(etcd),
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: "druid.gardener.cloud/v1alpha1",
APIVersion: druidv1alpha1.GroupVersion.String(),
BlockOwnerDeletion: pointer.Bool(true),
Controller: pointer.Bool(true),
Kind: "Etcd",
Expand Down
2 changes: 1 addition & 1 deletion controllers/etcd/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ func (r *Reconciler) reconcileEtcd(ctx context.Context, logger logr.Logger, etcd
peerUrlTLSChangedToEnabled := isPeerTLSChangedToEnabled(peerTLSEnabled, configMapValues)
statefulSetValues := componentsts.GenerateValues(etcd,
&serviceValues.ClientPort,
&serviceValues.ServerPort,
&serviceValues.PeerPort,
&serviceValues.BackupPort,
*etcdImage,
*etcdBackupImage,
Expand Down
2 changes: 1 addition & 1 deletion controllers/etcdcopybackupstask/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ func matchJob(task *druidv1alpha1.EtcdCopyBackupsTask, imageVector imagevector.I
}),
"OwnerReferences": MatchAllElements(testutils.OwnerRefIterator, Elements{
task.Name: MatchAllFields(Fields{
"APIVersion": Equal("druid.gardener.cloud/v1alpha1"),
"APIVersion": Equal(druidv1alpha1.GroupVersion.String()),
"Kind": Equal("EtcdCopyBackupsTask"),
"Name": Equal(task.Name),
"UID": Equal(task.UID),
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/prometheus/client_golang v1.14.0
go.uber.org/zap v1.24.0
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.26.1
k8s.io/apimachinery v0.26.1
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
Expand Down Expand Up @@ -118,7 +119,6 @@ require (
google.golang.org/grpc v1.49.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
istio.io/api v0.0.0-20221013011440-bc935762d2b9 // indirect
istio.io/client-go v1.15.3 // indirect
Expand Down
263 changes: 105 additions & 158 deletions pkg/component/etcd/configmap/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ import (
"context"
"encoding/json"
"fmt"
"strconv"

druidv1alpha1 "github.com/gardener/etcd-druid/api/v1alpha1"
corev1 "k8s.io/api/core/v1"

"github.com/gardener/gardener/pkg/controllerutils"
gardenercomponent "github.com/gardener/gardener/pkg/operation/botanist/component"
"github.com/gardener/gardener/pkg/utils"
"gopkg.in/yaml.v2"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"

druidv1alpha1 "github.com/gardener/etcd-druid/api/v1alpha1"
"github.com/gardener/gardener/pkg/controllerutils"
"github.com/gardener/gardener/pkg/utils"
)

type component struct {
Expand All @@ -48,146 +48,84 @@ func New(c client.Client, namespace string, values *Values) gardenercomponent.De
}

func (c *component) Deploy(ctx context.Context) error {
cm := c.emptyConfigmap(c.values.ConfigMapName)

cm := c.emptyConfigmap()
if err := c.syncConfigmap(ctx, cm); err != nil {
return err
}

return nil
}

func (c *component) syncConfigmap(ctx context.Context, cm *corev1.ConfigMap) error {
etcdConfigYaml := `# Human-readable name for this member.
name: ` + fmt.Sprintf("etcd-%s", c.values.EtcdUID[:6]) + `
# Path to the data directory.
data-dir: /var/etcd/data/new.etcd`
metricsLevel := druidv1alpha1.Basic
if c.values.Metrics != nil {
metricsLevel = *c.values.Metrics
func (c *component) Destroy(ctx context.Context) error {
configMap := c.emptyConfigmap()
if err := c.deleteConfigmap(ctx, configMap); err != nil {
return err
}
return nil
}

etcdConfigYaml = etcdConfigYaml + `
# metrics configuration
metrics: ` + string(metricsLevel) + `
# Number of committed transactions to trigger a snapshot to disk.
snapshot-count: 75000
type etcdTLSTarget string

# Accept etcd V2 client requests
enable-v2: false`
var quota int64 = 8 * 1024 * 1024 * 1024 // 8Gi
const (
clientTLS etcdTLSTarget = "client"
peerTLS etcdTLSTarget = "peer"
defaultQuota = int64(8 * 1024 * 1024 * 1024) // 8Gi
defaultSnapshotCount = 75000 // for more information refer to https://etcd.io/docs/v3.4/op-guide/maintenance/#raft-log-retention
defaultInitialClusterState = "new"
defaultInitialClusterToken = "etcd-cluster"
)

func (c *component) syncConfigmap(ctx context.Context, cm *corev1.ConfigMap) error {
peerScheme, peerSecurity := getSchemeAndSecurityConfig(c.values.PeerUrlTLS, peerTLS)
clientScheme, clientSecurity := getSchemeAndSecurityConfig(c.values.ClientUrlTLS, clientTLS)

quota := defaultQuota
if c.values.Quota != nil {
quota = c.values.Quota.Value()
}

etcdConfigYaml = etcdConfigYaml + `
# Raise alarms when backend size exceeds the given quota. 0 means use the
# default quota.
quota-backend-bytes: ` + fmt.Sprint(quota)

enableTLS := (c.values.ClientUrlTLS != nil)

protocol := "http"
if enableTLS {
protocol = "https"
tlsCASecretKey := "ca.crt"
if dataKey := c.values.ClientUrlTLS.TLSCASecretRef.DataKey; dataKey != nil {
tlsCASecretKey = *dataKey
}
etcdConfigYaml = etcdConfigYaml + `
client-transport-security:
# Path to the client server TLS cert file.
cert-file: /var/etcd/ssl/client/server/tls.crt

# Path to the client server TLS key file.
key-file: /var/etcd/ssl/client/server/tls.key

# Enable client cert authentication.
client-cert-auth: true

# Path to the client server TLS trusted CA cert file.
trusted-ca-file: /var/etcd/ssl/client/ca/` + tlsCASecretKey + `

# Client TLS using generated certificates
auto-tls: false`
autoCompactionMode := string(druidv1alpha1.Periodic)
if c.values.AutoCompactionMode != nil {
autoCompactionMode = string(*c.values.AutoCompactionMode)
}

clientPort := strconv.Itoa(int(pointer.Int32Deref(c.values.ClientPort, defaultClientPort)))

serverPort := strconv.Itoa(int(pointer.Int32Deref(c.values.ServerPort, defaultServerPort)))

etcdConfigYaml = etcdConfigYaml + `
# List of comma separated URLs to listen on for client traffic.
listen-client-urls: ` + protocol + `://0.0.0.0:` + clientPort + `

# List of this member's client URLs to advertise to the public.
# The URLs needed to be a comma-separated list.
advertise-client-urls: ` + protocol + `@` + c.values.PeerServiceName + `@` + c.values.EtcdNameSpace + `@` + clientPort

enableTLS = (c.values.PeerUrlTLS != nil)
protocol = "http"
if enableTLS {
protocol = "https"
tlsCASecretKey := "ca.crt"
if dataKey := c.values.PeerUrlTLS.TLSCASecretRef.DataKey; dataKey != nil {
tlsCASecretKey = *dataKey
}
etcdConfigYaml = etcdConfigYaml + `
peer-transport-security:
# Path to the peer server TLS cert file.
cert-file: /var/etcd/ssl/peer/server/tls.crt

# Path to the peer server TLS key file.
key-file: /var/etcd/ssl/peer/server/tls.key

# Enable peer cert authentication.
client-cert-auth: true

# Path to the peer server TLS trusted CA cert file.
trusted-ca-file: /var/etcd/ssl/peer/ca/` + tlsCASecretKey + `

# Peer TLS using generated certificates
auto-tls: false`
etcdConfig := &etcdConfig{
Name: fmt.Sprintf("etcd-%s", c.values.EtcdUID[:6]),
DataDir: "/var/etcd/data/new.etcd",
Metrics: string(druidv1alpha1.Basic),
SnapshotCount: defaultSnapshotCount,
EnableV2: false,
QuotaBackendBytes: quota,
InitialClusterToken: defaultInitialClusterToken,
InitialClusterState: defaultInitialClusterState,
InitialCluster: c.values.InitialCluster,
AutoCompactionMode: autoCompactionMode,
AutoCompactionRetention: pointer.StringDeref(c.values.AutoCompactionRetention, "30m"),

ListenPeerUrls: fmt.Sprintf("%s://0.0.0.0:%d", peerScheme, pointer.Int32Deref(c.values.ServerPort, defaultServerPort)),
ListenClientUrls: fmt.Sprintf("%s://0.0.0.0:%d", clientScheme, pointer.Int32Deref(c.values.ClientPort, defaultClientPort)),
AdvertisePeerUrls: fmt.Sprintf("%s@%s@%s@%d", peerScheme, c.values.PeerServiceName, c.namespace, pointer.Int32Deref(c.values.ServerPort, defaultServerPort)),
AdvertiseClientUrls: fmt.Sprintf("%s@%s@%s@%d", clientScheme, c.values.PeerServiceName, c.namespace, pointer.Int32Deref(c.values.ClientPort, defaultClientPort)),
}

etcdConfigYaml = etcdConfigYaml + `
# List of comma separated URLs to listen on for peer traffic.
listen-peer-urls: ` + protocol + `://0.0.0.0:` + serverPort + `

# List of this member's peer URLs to advertise to the public.
# The URLs needed to be a comma-separated list.
initial-advertise-peer-urls: ` + protocol + `@` + c.values.PeerServiceName + `@` + c.values.EtcdNameSpace + `@` + serverPort + `

# Initial cluster token for the etcd cluster during bootstrap.
initial-cluster-token: etcd-cluster

# Initial cluster state ('new' or 'existing').
initial-cluster-state: new

# Initial cluster
initial-cluster: ` + c.values.InitialCluster + `

# auto-compaction-mode ("periodic" or "revision").`
if clientSecurity != nil {
etcdConfig.ClientSecurity = *clientSecurity
}

autoCompactionMode := "periodic"
if c.values.AutoCompactionMode != nil {
autoCompactionMode = string(*c.values.AutoCompactionMode)
if peerSecurity != nil {
etcdConfig.PeerSecurity = *peerSecurity
}
etcdConfigYaml = etcdConfigYaml + `
auto-compaction-mode: ` + autoCompactionMode

autoCompactionRetention := "30m"
if c.values.AutoCompactionRetention != nil {
autoCompactionRetention = string(*c.values.AutoCompactionRetention)
etcdConfigYaml, err := yaml.Marshal(etcdConfig)
if err != nil {
return err
}
etcdConfigYaml = etcdConfigYaml + `
# auto-compaction-retention defines Auto compaction retention length for etcd.
auto-compaction-retention: ` + autoCompactionRetention

_, err := controllerutils.GetAndCreateOrMergePatch(ctx, c.client, cm, func() error {
cm.ObjectMeta = getObjectMeta(c.values)
cm.OwnerReferences = getOwnerReferences(c.values)
cm.Data = map[string]string{"etcd.conf.yaml": etcdConfigYaml}

_, err = controllerutils.GetAndCreateOrMergePatch(ctx, c.client, cm, func() error {
cm.Name = c.values.Name
cm.Namespace = c.namespace
cm.Labels = c.values.Labels
cm.OwnerReferences = []metav1.OwnerReference{c.values.OwnerReference}
cm.Data = map[string]string{"etcd.conf.yaml": string(etcdConfigYaml)}
return nil
})
if err != nil {
Expand All @@ -200,54 +138,63 @@ func (c *component) syncConfigmap(ctx context.Context, cm *corev1.ConfigMap) err
return err
}
c.values.ConfigMapChecksum = utils.ComputeSHA256Hex(jsonString)

return nil

}

func (c *component) Destroy(ctx context.Context) error {
configMap := c.emptyConfigmap(c.values.ConfigMapName)

if err := c.deleteConfigmap(ctx, configMap); err != nil {
return err
}
return nil
}

func (c *component) deleteConfigmap(ctx context.Context, cm *corev1.ConfigMap) error {
return client.IgnoreNotFound(c.client.Delete(ctx, cm))
}

func (c *component) emptyConfigmap(name string) *corev1.ConfigMap {
func (c *component) emptyConfigmap() *corev1.ConfigMap {
return &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Name: c.values.Name,
Namespace: c.namespace,
},
}
}

func getObjectMeta(val *Values) metav1.ObjectMeta {
labels := map[string]string{"name": "etcd", "instance": val.EtcdName}
for key, value := range val.Labels {
labels[key] = value
}
return metav1.ObjectMeta{
Name: val.ConfigMapName,
Namespace: val.EtcdNameSpace,
Labels: labels,
}
type etcdConfig struct {
seshachalam-yv marked this conversation as resolved.
Show resolved Hide resolved
Name string `yaml:"name"`
DataDir string `yaml:"data-dir"`
Metrics string `yaml:"metrics"`
SnapshotCount int `yaml:"snapshot-count"`
EnableV2 bool `yaml:"enable-v2"`
QuotaBackendBytes int64 `yaml:"quota-backend-bytes"`
InitialClusterToken string `yaml:"initial-cluster-token"`
InitialClusterState string `yaml:"initial-cluster-state"`
InitialCluster string `yaml:"initial-cluster"`
AutoCompactionMode string `yaml:"auto-compaction-mode"`
AutoCompactionRetention string `yaml:"auto-compaction-retention"`
ListenPeerUrls string `yaml:"listen-peer-urls"`
ListenClientUrls string `yaml:"listen-client-urls"`
AdvertisePeerUrls string `yaml:"initial-advertise-peer-urls"`
AdvertiseClientUrls string `yaml:"advertise-client-urls"`
ClientSecurity securityConfig `yaml:"client-transport-security,omitempty"`
PeerSecurity securityConfig `yaml:"peer-transport-security,omitempty"`
}
seshachalam-yv marked this conversation as resolved.
Show resolved Hide resolved

func getOwnerReferences(val *Values) []metav1.OwnerReference {
return []metav1.OwnerReference{
{
APIVersion: druidv1alpha1.GroupVersion.String(),
Kind: "Etcd",
Name: val.EtcdName,
UID: val.EtcdUID,
Controller: pointer.Bool(true),
BlockOwnerDeletion: pointer.Bool(true),
},
type securityConfig struct {
seshachalam-yv marked this conversation as resolved.
Show resolved Hide resolved
CertFile string `yaml:"cert-file,omitempty"`
KeyFile string `yaml:"key-file,omitempty"`
ClientCertAuth bool `yaml:"client-cert-auth,omitempty"`
TrustedCAFile string `yaml:"trusted-ca-file,omitempty"`
AutoTLS bool `yaml:"auto-tls"`
}

func getSchemeAndSecurityConfig(tlsConfig *druidv1alpha1.TLSConfig, tlsTarget etcdTLSTarget) (string, *securityConfig) {
if tlsConfig != nil {
tlsCASecretKey := "ca.crt"
if dataKey := tlsConfig.TLSCASecretRef.DataKey; dataKey != nil {
tlsCASecretKey = *dataKey
}
return "https", &securityConfig{
CertFile: fmt.Sprintf("/var/etcd/ssl/%s/server/tls.crt", tlsTarget),
KeyFile: fmt.Sprintf("/var/etcd/ssl/%s/server/tls.key", tlsTarget),
ClientCertAuth: true,
TrustedCAFile: fmt.Sprintf("/var/etcd/ssl/%s/ca/%s", tlsTarget, tlsCASecretKey),
AutoTLS: false,
}
}
return "http", nil
}
2 changes: 1 addition & 1 deletion pkg/component/etcd/configmap/configmap_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
. "github.com/onsi/gomega"
)

func TestService(t *testing.T) {
func TestConfigMap(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Configmap Component Suite")
}
Loading