1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Feature] Add ClusterDomain config (#683)

This commit is contained in:
Adam Janikowski 2021-01-19 15:39:23 +01:00 committed by GitHub
parent d232d3dca9
commit 147ccdda48
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 237 additions and 79 deletions

View file

@ -1,6 +1,7 @@
# Change Log
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
- Add support for spec.ClusterDomain to be able to use FQDN in ArangoDB cluster communication
## [1.1.3](https://github.com/arangodb/kube-arangodb/tree/1.1.3) (2020-12-16)
- Add v2alpha1 API for ArangoDeployment and ArangoDeploymentReplication

View file

@ -116,6 +116,8 @@ type DeploymentSpec struct {
Bootstrap BootstrapSpec `json:"bootstrap,omitempty"`
Timeouts *Timeouts `json:"timeouts,omitempty"`
ClusterDomain *string `json:"ClusterDomain,omitempty"`
}
// GetRestoreFrom returns the restore from string or empty string if not set

View file

@ -71,6 +71,8 @@ type MemberStatus struct {
Image *ImageInfo `json:"image,omitempty"`
// Upgrade define if upgrade should be enforced during next execution
Upgrade bool `json:"upgrade,omitempty"`
// Endpoint definition how member should be reachable
Endpoint *string `json:"endpoint,omitempty"`
}
// Equal checks for equality
@ -87,7 +89,8 @@ func (s MemberStatus) Equal(other MemberStatus) bool {
s.ArangoVersion == other.ArangoVersion &&
s.ImageID == other.ImageID &&
s.Image.Equal(other.Image) &&
s.Upgrade == other.Upgrade
s.Upgrade == other.Upgrade &&
util.CompareStringPointers(s.Endpoint, other.Endpoint)
}
// Age returns the duration since the creation timestamp of this member.
@ -115,6 +118,14 @@ func (s *MemberStatus) RemoveTerminationsBefore(timestamp time.Time) int {
}
}
func (s *MemberStatus) GetEndpoint(defaultEndpoint string) string {
if s == nil || s.Endpoint == nil {
return defaultEndpoint
}
return *s.Endpoint
}
// RecentTerminationsSince returns the number of terminations since the given timestamp.
func (s MemberStatus) RecentTerminationsSince(timestamp time.Time) int {
count := 0

View file

@ -464,6 +464,11 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) {
*out = new(Timeouts)
(*in).DeepCopyInto(*out)
}
if in.ClusterDomain != nil {
in, out := &in.ClusterDomain, &out.ClusterDomain
*out = new(string)
**out = **in
}
return
}
@ -845,6 +850,11 @@ func (in *MemberStatus) DeepCopyInto(out *MemberStatus) {
*out = new(ImageInfo)
**out = **in
}
if in.Endpoint != nil {
in, out := &in.Endpoint, &out.Endpoint
*out = new(string)
**out = **in
}
return
}

View file

@ -116,6 +116,8 @@ type DeploymentSpec struct {
Bootstrap BootstrapSpec `json:"bootstrap,omitempty"`
Timeouts *Timeouts `json:"timeouts,omitempty"`
ClusterDomain *string `json:"ClusterDomain,omitempty"`
}
// GetRestoreFrom returns the restore from string or empty string if not set

View file

@ -24,6 +24,7 @@ package v2alpha1
import (
"github.com/arangodb/kube-arangodb/pkg/util/errors"
v1 "k8s.io/api/core/v1"
)

View file

@ -71,6 +71,8 @@ type MemberStatus struct {
Image *ImageInfo `json:"image,omitempty"`
// Upgrade define if upgrade should be enforced during next execution
Upgrade bool `json:"upgrade,omitempty"`
// Endpoint definition how member should be reachable
Endpoint *string `json:"endpoint,omitempty"`
}
// Equal checks for equality
@ -87,7 +89,8 @@ func (s MemberStatus) Equal(other MemberStatus) bool {
s.ArangoVersion == other.ArangoVersion &&
s.ImageID == other.ImageID &&
s.Image.Equal(other.Image) &&
s.Upgrade == other.Upgrade
s.Upgrade == other.Upgrade &&
util.CompareStringPointers(s.Endpoint, other.Endpoint)
}
// Age returns the duration since the creation timestamp of this member.
@ -115,6 +118,14 @@ func (s *MemberStatus) RemoveTerminationsBefore(timestamp time.Time) int {
}
}
func (s *MemberStatus) GetEndpoint(defaultEndpoint string) string {
if s == nil || s.Endpoint == nil {
return defaultEndpoint
}
return *s.Endpoint
}
// RecentTerminationsSince returns the number of terminations since the given timestamp.
func (s MemberStatus) RecentTerminationsSince(timestamp time.Time) int {
count := 0

View file

@ -464,6 +464,11 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) {
*out = new(Timeouts)
(*in).DeepCopyInto(*out)
}
if in.ClusterDomain != nil {
in, out := &in.ClusterDomain, &out.ClusterDomain
*out = new(string)
**out = **in
}
return
}
@ -845,6 +850,11 @@ func (in *MemberStatus) DeepCopyInto(out *MemberStatus) {
*out = new(ImageInfo)
**out = **in
}
if in.Endpoint != nil {
in, out := &in.Endpoint, &out.Endpoint
*out = new(string)
**out = **in
}
return
}

View file

@ -24,7 +24,6 @@ package client
import (
"context"
"fmt"
"net"
"strconv"
"sync"
@ -49,7 +48,6 @@ type Cache interface {
func NewClientCache(apiObjectGetter func() *api.ArangoDeployment, factory conn.Factory) Cache {
return &cache{
clients: make(map[string]driver.Client),
apiObjectGetter: apiObjectGetter,
factory: factory,
}
@ -57,11 +55,8 @@ func NewClientCache(apiObjectGetter func() *api.ArangoDeployment, factory conn.F
type cache struct {
mutex sync.Mutex
clients map[string]driver.Client
apiObjectGetter func() *api.ArangoDeployment
databaseClient driver.Client
factory conn.Factory
}
@ -75,18 +70,12 @@ func (cc *cache) extendHost(host string) string {
}
func (cc *cache) getClient(ctx context.Context, group api.ServerGroup, id string) (driver.Client, error) {
key := fmt.Sprintf("%d-%s", group, id)
c, found := cc.clients[key]
if found {
return c, nil
}
m, _, _ := cc.apiObjectGetter().Status.Members.ElementByID(id)
// Not found, create a new client
c, err := cc.factory.Client(cc.extendHost(k8sutil.CreatePodDNSName(cc.apiObjectGetter(), group.AsRole(), id)))
c, err := cc.factory.Client(cc.extendHost(m.GetEndpoint(k8sutil.CreatePodDNSName(cc.apiObjectGetter(), group.AsRole(), id))))
if err != nil {
return nil, errors.WithStack(err)
}
cc.clients[key] = c
return c, nil
}
@ -99,7 +88,6 @@ func (cc *cache) get(ctx context.Context, group api.ServerGroup, id string) (dri
if _, err := client.Version(ctx); err == nil {
return client, nil
} else if driver.IsUnauthorized(err) {
delete(cc.clients, fmt.Sprintf("%d-%s", group, id))
return cc.getClient(ctx, group, id)
} else {
return client, nil
@ -120,16 +108,10 @@ func (cc cache) GetAuth() conn.Auth {
}
func (cc *cache) getDatabaseClient() (driver.Client, error) {
if c := cc.databaseClient; c != nil {
return c, nil
}
// Not found, create a new client
c, err := cc.factory.Client(cc.extendHost(k8sutil.CreateDatabaseClientServiceDNSName(cc.apiObjectGetter())))
if err != nil {
return nil, errors.WithStack(err)
}
cc.databaseClient = c
return c, nil
}
@ -142,7 +124,6 @@ func (cc *cache) getDatabase(ctx context.Context) (driver.Client, error) {
if _, err := client.Version(ctx); err == nil {
return client, nil
} else if driver.IsUnauthorized(err) {
cc.databaseClient = nil
return cc.getDatabaseClient()
} else {
return client, nil
@ -162,7 +143,7 @@ func (cc *cache) getAgencyClient() (agency.Agency, error) {
// Not found, create a new client
var dnsNames []string
for _, m := range cc.apiObjectGetter().Status.Members.Agents {
dnsNames = append(dnsNames, cc.extendHost(k8sutil.CreatePodDNSName(cc.apiObjectGetter(), api.ServerGroupAgents.AsRole(), m.ID)))
dnsNames = append(dnsNames, cc.extendHost(m.GetEndpoint(k8sutil.CreatePodDNSName(cc.apiObjectGetter(), api.ServerGroupAgents.AsRole(), m.ID))))
}
if len(dnsNames) == 0 {

View file

@ -322,7 +322,7 @@ func (d *Deployment) GetSyncServerClient(ctx context.Context, group api.ServerGr
}
// Fetch server DNS name
dnsName := k8sutil.CreatePodDNSName(d.apiObject, group.AsRole(), id)
dnsName := k8sutil.CreatePodDNSNameWithDomain(d.apiObject, d.apiObject.Spec.ClusterDomain, group.AsRole(), id)
// Build client
port := k8sutil.ArangoSyncMasterPort

View file

@ -38,9 +38,9 @@ type Input struct {
GroupSpec deploymentApi.ServerGroupSpec
Group deploymentApi.ServerGroup
Version driver.Version
Member deploymentApi.MemberStatus
Enterprise bool
AutoUpgrade bool
ID string
}
type Builder interface {

View file

@ -46,7 +46,7 @@ func IsTLSEnabled(i Input) bool {
}
func GetTLSKeyfileSecretName(i Input) string {
return k8sutil.CreateTLSKeyfileSecretName(i.ApiObject.GetName(), i.Group.AsRole(), i.ID)
return k8sutil.CreateTLSKeyfileSecretName(i.ApiObject.GetName(), i.Group.AsRole(), i.Member.ID)
}
func TLS() Builder {

View file

@ -50,6 +50,10 @@ type cleanTLSKeyfileCertificateAction struct {
}
func (a *cleanTLSKeyfileCertificateAction) Start(ctx context.Context) (bool, error) {
if !a.actionCtx.GetSpec().TLS.IsSecure() {
return true, nil
}
member, exists := a.actionCtx.GetMemberStatusByID(a.action.MemberID)
if !exists {
a.log.Warn().Msgf("Member does not exist")

View file

@ -135,6 +135,10 @@ func (a *actionWaitForMemberUp) checkProgressAgent(ctx context.Context) (bool, b
return false, false, errors.WithStack(err)
}
for _, a := range clients {
a.Endpoints()
}
if err := agency.AreAgentsHealthy(ctx, clients); err != nil {
log.Debug().Err(err).Msg("Not all agents are ready")
return false, false, nil

View file

@ -300,6 +300,7 @@ func createRotateMemberPlan(log zerolog.Logger, member api.MemberStatus,
Str("reason", reason).
Msg("Creating rotation plan")
plan := api.Plan{
api.NewAction(api.ActionTypeCleanTLSKeyfileCertificate, group, member.ID, "Remove server keyfile and enforce renewal/recreation"),
api.NewAction(api.ActionTypeRotateMember, group, member.ID, reason),
api.NewAction(api.ActionTypeWaitForMemberUp, group, member.ID),
api.NewAction(api.ActionTypeWaitForMemberInSync, group, member.ID),

View file

@ -56,6 +56,8 @@ type PlanBuilderContext interface {
InvalidateSyncStatus()
// GetStatus returns the current status of the deployment
GetStatus() (api.DeploymentStatus, int32)
// GetStatus returns the current spec of the deployment
GetSpec() api.DeploymentSpec
// GetAgencyData object for key path
GetAgencyData(ctx context.Context, i interface{}, keyParts ...string) error
// Renders Pod definition for member

View file

@ -348,7 +348,9 @@ func createUpgradeMemberPlan(log zerolog.Logger, member api.MemberStatus,
Str("reason", reason).
Str("action", string(upgradeAction)).
Msg("Creating upgrade plan")
var plan api.Plan
var plan = api.Plan{
api.NewAction(api.ActionTypeCleanTLSKeyfileCertificate, group, member.ID, "Remove server keyfile and enforce renewal/recreation"),
}
if status.CurrentImage == nil || status.CurrentImage.Image != spec.GetImage() {
plan = append(plan,
api.NewAction(api.ActionTypeSetCurrentImage, group, "", reason).SetImage(spec.GetImage()),

View file

@ -719,6 +719,7 @@ func TestCreatePlan(t *testing.T) {
ad.Status.Members.Agents[0].PersistentVolumeClaimName = "pvc_test"
},
ExpectedPlan: []api.Action{
api.NewAction(api.ActionTypeCleanTLSKeyfileCertificate, api.ServerGroupAgents, "", "Remove server keyfile and enforce renewal/recreation"),
api.NewAction(api.ActionTypeRotateMember, api.ServerGroupAgents, ""),
api.NewAction(api.ActionTypeWaitForMemberUp, api.ServerGroupAgents, ""),
api.NewAction(api.ActionTypeWaitForMemberInSync, api.ServerGroupAgents, ""),

View file

@ -402,7 +402,7 @@ func createKeyfileRenewalPlanMode(
}
func checkServerValidCertRequest(ctx context.Context, context PlanBuilderContext, apiObject k8sutil.APIObject, group api.ServerGroup, member api.MemberStatus, ca resources.Certificates) (*tls.ConnectionState, error) {
endpoint := fmt.Sprintf("https://%s:%d", k8sutil.CreatePodDNSName(apiObject, group.AsRole(), member.ID), k8sutil.ArangoPort)
endpoint := fmt.Sprintf("https://%s:%d", k8sutil.CreatePodDNSNameWithDomain(apiObject, context.GetSpec().ClusterDomain, group.AsRole(), member.ID), k8sutil.ArangoPort)
tlsConfig := &tls.Config{
RootCAs: ca.AsCertPool(),

View file

@ -34,6 +34,8 @@ import (
"sync"
"time"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/deployment/features"
@ -108,11 +110,11 @@ func createArangodArgs(input pod.Input, additionalOptions ...k8sutil.OptionPair)
options = append(options,
k8sutil.OptionPair{"--log.level", "startup=trace"})
}*/
myTCPURL := scheme + "://" + net.JoinHostPort(k8sutil.CreatePodDNSName(input.ApiObject, input.Group.AsRole(), input.ID), strconv.Itoa(k8sutil.ArangoPort))
myTCPURL := scheme + "://" + net.JoinHostPort(k8sutil.CreatePodDNSNameWithDomain(input.ApiObject, input.Deployment.ClusterDomain, input.Group.AsRole(), input.Member.ID), strconv.Itoa(k8sutil.ArangoPort))
addAgentEndpoints := false
switch input.Group {
case api.ServerGroupAgents:
options.Add("--agency.disaster-recovery-id", input.ID)
options.Add("--agency.disaster-recovery-id", input.Member.ID)
options.Add("--agency.activate", "true")
options.Add("--agency.my-address", myTCPURL)
options.Addf("--agency.size", "%d", input.Deployment.Agents.GetCount())
@ -120,8 +122,8 @@ func createArangodArgs(input pod.Input, additionalOptions ...k8sutil.OptionPair)
options.Add("--foxx.queues", false)
options.Add("--server.statistics", "false")
for _, p := range input.Status.Members.Agents {
if p.ID != input.ID {
dnsName := k8sutil.CreatePodDNSName(input.ApiObject, api.ServerGroupAgents.AsRole(), p.ID)
if p.ID != input.Member.ID {
dnsName := p.GetEndpoint(k8sutil.CreatePodDNSNameWithDomain(input.ApiObject, input.Deployment.ClusterDomain, api.ServerGroupAgents.AsRole(), p.ID))
options.Addf("--agency.endpoint", "%s://%s", scheme, net.JoinHostPort(dnsName, strconv.Itoa(k8sutil.ArangoPort)))
}
}
@ -155,7 +157,7 @@ func createArangodArgs(input pod.Input, additionalOptions ...k8sutil.OptionPair)
}
if addAgentEndpoints {
for _, p := range input.Status.Members.Agents {
dnsName := k8sutil.CreatePodDNSName(input.ApiObject, api.ServerGroupAgents.AsRole(), p.ID)
dnsName := p.GetEndpoint(k8sutil.CreatePodDNSNameWithDomain(input.ApiObject, input.Deployment.ClusterDomain, api.ServerGroupAgents.AsRole(), p.ID))
options.Addf("--cluster.agency-endpoint", "%s://%s", scheme, net.JoinHostPort(dnsName, strconv.Itoa(k8sutil.ArangoPort)))
}
}
@ -174,7 +176,7 @@ func createArangodArgs(input pod.Input, additionalOptions ...k8sutil.OptionPair)
// createArangoSyncArgs creates command line arguments for an arangosync server in the given group.
func createArangoSyncArgs(apiObject metav1.Object, spec api.DeploymentSpec, group api.ServerGroup,
groupSpec api.ServerGroupSpec, id string) []string {
groupSpec api.ServerGroupSpec, member api.MemberStatus) []string {
options := k8sutil.CreateOptionPairs(64)
var runCmd string
var port int
@ -194,7 +196,7 @@ func createArangoSyncArgs(apiObject metav1.Object, spec api.DeploymentSpec, grou
case api.ServerGroupSyncMasters:
runCmd = "master"
port = k8sutil.ArangoSyncMasterPort
masterEndpoint = spec.Sync.ExternalAccess.ResolveMasterEndpoint(k8sutil.CreateSyncMasterClientServiceDNSName(apiObject), port)
masterEndpoint = spec.Sync.ExternalAccess.ResolveMasterEndpoint(k8sutil.CreateSyncMasterClientServiceDNSNameWithDomain(apiObject, spec.ClusterDomain), port)
keyPath := filepath.Join(k8sutil.TLSKeyfileVolumeMountDir, constants.SecretTLSKeyfile)
clientCAPath := filepath.Join(k8sutil.ClientAuthCAVolumeMountDir, constants.SecretCACertificate)
options.Add("--server.keyfile", keyPath)
@ -219,7 +221,7 @@ func createArangoSyncArgs(apiObject metav1.Object, spec api.DeploymentSpec, grou
for _, ep := range masterEndpoint {
options.Add("--master.endpoint", ep)
}
serverEndpoint := "https://" + net.JoinHostPort(k8sutil.CreatePodDNSName(apiObject, group.AsRole(), id), strconv.Itoa(port))
serverEndpoint := "https://" + net.JoinHostPort(k8sutil.CreatePodDNSNameWithDomain(apiObject, spec.ClusterDomain, group.AsRole(), member.ID), strconv.Itoa(port))
options.Add("--server.endpoint", serverEndpoint)
options.Add("--server.port", strconv.Itoa(port))
@ -374,7 +376,7 @@ func (r *Resources) RenderPodForMember(cachedStatus inspector.Inspector, spec ap
}
// Prepare arguments
args := createArangoSyncArgs(apiObject, spec, group, groupSpec, m.ID)
args := createArangoSyncArgs(apiObject, spec, group, groupSpec, m)
memberSyncPod := MemberSyncPod{
tlsKeyfileSecretName: tlsKeyfileSecretName,
@ -481,6 +483,7 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string,
m.PodUID = uid
m.PodSpecVersion = sha
m.Endpoint = util.NewString(k8sutil.CreatePodDNSNameWithDomain(apiObject, spec.ClusterDomain, role, m.ID))
m.ArangoVersion = status.CurrentImage.ArangoDBVersion
m.ImageID = status.CurrentImage.ImageID
@ -503,10 +506,10 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string,
tlsKeyfileSecretName := k8sutil.CreateTLSKeyfileSecretName(apiObject.GetName(), role, m.ID)
serverNames := []string{
k8sutil.CreateSyncMasterClientServiceName(apiObject.GetName()),
k8sutil.CreateSyncMasterClientServiceDNSName(apiObject),
k8sutil.CreatePodDNSName(apiObject, role, m.ID),
k8sutil.CreateSyncMasterClientServiceDNSNameWithDomain(apiObject, spec.ClusterDomain),
k8sutil.CreatePodDNSNameWithDomain(apiObject, spec.ClusterDomain, role, m.ID),
}
masterEndpoint := spec.Sync.ExternalAccess.ResolveMasterEndpoint(k8sutil.CreateSyncMasterClientServiceDNSName(apiObject), k8sutil.ArangoSyncMasterPort)
masterEndpoint := spec.Sync.ExternalAccess.ResolveMasterEndpoint(k8sutil.CreateSyncMasterClientServiceDNSNameWithDomain(apiObject, spec.ClusterDomain), k8sutil.ArangoSyncMasterPort)
for _, ep := range masterEndpoint {
if u, err := url.Parse(ep); err == nil {
serverNames = append(serverNames, u.Hostname())
@ -530,6 +533,7 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string,
log.Debug().Str("pod-name", m.PodName).Msg("Created pod")
m.PodUID = uid
m.Endpoint = util.NewString(k8sutil.CreateSyncMasterClientServiceDNSNameWithDomain(apiObject, spec.ClusterDomain))
m.PodSpecVersion = sha
}
// Record new member phase

View file

@ -62,7 +62,7 @@ func TestCreateArangodArgsAgent(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -117,7 +117,7 @@ func TestCreateArangodArgsAgent(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: true,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgsWithUpgrade(input)
assert.Equal(t,
@ -176,7 +176,7 @@ func TestCreateArangodArgsAgent(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -230,7 +230,7 @@ func TestCreateArangodArgsAgent(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -284,7 +284,7 @@ func TestCreateArangodArgsAgent(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,

View file

@ -215,7 +215,7 @@ func (m *MemberArangoDPod) AsInput() pod.Input {
Version: m.imageInfo.ArangoDBVersion,
Enterprise: m.imageInfo.Enterprise,
AutoUpgrade: m.autoUpgrade,
ID: m.id,
Member: m.status,
}
}

View file

@ -62,7 +62,7 @@ func TestCreateArangodArgsCoordinator(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -114,7 +114,7 @@ func TestCreateArangodArgsCoordinator(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: true,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgsWithUpgrade(input)
assert.Equal(t,
@ -167,7 +167,7 @@ func TestCreateArangodArgsCoordinator(t *testing.T) {
Version: "3.6.0",
Enterprise: false,
AutoUpgrade: true,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgsWithUpgrade(input)
assert.Equal(t,
@ -223,7 +223,7 @@ func TestCreateArangodArgsCoordinator(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -274,7 +274,7 @@ func TestCreateArangodArgsCoordinator(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -327,7 +327,7 @@ func TestCreateArangodArgsCoordinator(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,

View file

@ -62,7 +62,7 @@ func TestCreateArangodArgsDBServer(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -114,7 +114,7 @@ func TestCreateArangodArgsDBServer(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: true,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgsWithUpgrade(input)
assert.Equal(t,
@ -141,6 +141,60 @@ func TestCreateArangodArgsDBServer(t *testing.T) {
)
}
// Default+ClusterDomain deployment
{
apiObject := &api.ArangoDeployment{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "ns",
},
Spec: api.DeploymentSpec{
Mode: api.NewMode(api.DeploymentModeCluster),
ClusterDomain: util.NewString("cluster.local"),
},
}
apiObject.Spec.SetDefaults("test")
agents := api.MemberStatusList{
api.MemberStatus{ID: "a1"},
api.MemberStatus{ID: "a2"},
api.MemberStatus{ID: "a3"},
}
input := pod.Input{
ApiObject: apiObject,
Deployment: apiObject.Spec,
Status: api.DeploymentStatus{Members: api.DeploymentStatusMembers{Agents: agents}},
Group: api.ServerGroupDBServers,
GroupSpec: apiObject.Spec.DBServers,
Version: "",
Enterprise: false,
AutoUpgrade: true,
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgsWithUpgrade(input)
assert.Equal(t,
[]string{
"--cluster.agency-endpoint=ssl://name-agent-a1.name-int.ns.svc.cluster.local:8529",
"--cluster.agency-endpoint=ssl://name-agent-a2.name-int.ns.svc.cluster.local:8529",
"--cluster.agency-endpoint=ssl://name-agent-a3.name-int.ns.svc.cluster.local:8529",
"--cluster.my-address=ssl://name-dbserver-id1.name-int.ns.svc.cluster.local:8529",
"--cluster.my-role=PRIMARY",
"--database.auto-upgrade=true",
"--database.directory=/data",
"--foxx.queues=false",
"--log.level=INFO",
"--log.output=+",
"--server.authentication=true",
"--server.endpoint=ssl://[::]:8529",
"--server.jwt-secret=$(ARANGOD_JWT_SECRET)",
"--server.statistics=true",
"--server.storage-engine=rocksdb",
"--ssl.ecdh-curve=",
"--ssl.keyfile=/secrets/tls/tls.keyfile",
},
cmdline,
)
}
// Default+TLS disabled deployment
{
apiObject := &api.ArangoDeployment{
@ -170,7 +224,7 @@ func TestCreateArangodArgsDBServer(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -221,7 +275,7 @@ func TestCreateArangodArgsDBServer(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -274,7 +328,7 @@ func TestCreateArangodArgsDBServer(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,

View file

@ -52,7 +52,7 @@ func TestCreateArangodArgsSingle(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -89,7 +89,7 @@ func TestCreateArangodArgsSingle(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: true,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgsWithUpgrade(input)
assert.Equal(t,
@ -130,7 +130,7 @@ func TestCreateArangodArgsSingle(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -166,7 +166,7 @@ func TestCreateArangodArgsSingle(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -204,7 +204,7 @@ func TestCreateArangodArgsSingle(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -241,7 +241,7 @@ func TestCreateArangodArgsSingle(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "a1",
Member: api.MemberStatus{ID: "a1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,
@ -290,7 +290,7 @@ func TestCreateArangodArgsSingle(t *testing.T) {
Version: "",
Enterprise: false,
AutoUpgrade: false,
ID: "id1",
Member: api.MemberStatus{ID: "id1"},
}
cmdline := createArangodArgs(input)
assert.Equal(t,

View file

@ -135,6 +135,13 @@ func (r *Resources) EnsureSecrets(log zerolog.Logger, cachedStatus inspector.Ins
k8sutil.CreateDatabaseClientServiceDNSName(apiObject),
k8sutil.CreatePodDNSName(apiObject, role, m.ID),
}
if spec.ClusterDomain != nil {
serverNames = append(serverNames,
k8sutil.CreateDatabaseClientServiceDNSNameWithDomain(apiObject, spec.ClusterDomain),
k8sutil.CreatePodDNSNameWithDomain(apiObject, spec.ClusterDomain, role, m.ID))
}
if ip := spec.ExternalAccess.GetLoadBalancerIP(); ip != "" {
serverNames = append(serverNames, ip)
}

View file

@ -106,7 +106,7 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy
customResync: make(map[reflect.Type]time.Duration),
}
// Apply all options
// Collect all options
for _, opt := range options {
factory = opt(factory)
}

View file

@ -113,7 +113,7 @@ func (dr *DeploymentReplication) createArangoSyncEndpoint(epSpec api.EndpointSpe
dr.deps.Log.Debug().Err(err).Str("deployment", deploymentName).Msg("Failed to get deployment")
return nil, errors.WithStack(err)
}
dnsName := k8sutil.CreateSyncMasterClientServiceDNSName(depl)
dnsName := k8sutil.CreateSyncMasterClientServiceDNSNameWithDomain(depl, depl.Spec.ClusterDomain)
return client.Endpoint{"https://" + net.JoinHostPort(dnsName, strconv.Itoa(k8sutil.ArangoSyncMasterPort))}, nil
}
return client.Endpoint(epSpec.MasterEndpoint), nil

View file

@ -117,7 +117,7 @@ var (
// CreateArangodClient creates a go-driver client for a specific member in the given group.
func CreateArangodClient(ctx context.Context, cli corev1.CoreV1Interface, apiObject *api.ArangoDeployment, group api.ServerGroup, id string) (driver.Client, error) {
// Create connection
dnsName := k8sutil.CreatePodDNSName(apiObject, group.AsRole(), id)
dnsName := k8sutil.CreatePodDNSNameWithDomain(apiObject, apiObject.Spec.ClusterDomain, group.AsRole(), id)
c, err := createArangodClientForDNSName(ctx, cli, apiObject, dnsName, false)
if err != nil {
return nil, errors.WithStack(err)
@ -128,7 +128,7 @@ func CreateArangodClient(ctx context.Context, cli corev1.CoreV1Interface, apiObj
// CreateArangodDatabaseClient creates a go-driver client for accessing the entire cluster (or single server).
func CreateArangodDatabaseClient(ctx context.Context, cli corev1.CoreV1Interface, apiObject *api.ArangoDeployment, shortTimeout bool) (driver.Client, error) {
// Create connection
dnsName := k8sutil.CreateDatabaseClientServiceDNSName(apiObject)
dnsName := k8sutil.CreateDatabaseClientServiceDNSNameWithDomain(apiObject, apiObject.Spec.ClusterDomain)
c, err := createArangodClientForDNSName(ctx, cli, apiObject, dnsName, shortTimeout)
if err != nil {
return nil, errors.WithStack(err)
@ -139,7 +139,7 @@ func CreateArangodDatabaseClient(ctx context.Context, cli corev1.CoreV1Interface
func CreateArangodAgencyConnection(ctx context.Context, apiObject *api.ArangoDeployment) (driver.Connection, error) {
var dnsNames []string
for _, m := range apiObject.Status.Members.Agents {
dnsName := k8sutil.CreatePodDNSName(apiObject, api.ServerGroupAgents.AsRole(), m.ID)
dnsName := k8sutil.CreatePodDNSNameWithDomain(apiObject, apiObject.Spec.ClusterDomain, api.ServerGroupAgents.AsRole(), m.ID)
dnsNames = append(dnsNames, dnsName)
}
shortTimeout := false
@ -158,7 +158,7 @@ func CreateArangodAgencyConnection(ctx context.Context, apiObject *api.ArangoDep
func CreateArangodAgencyClient(ctx context.Context, cli corev1.CoreV1Interface, apiObject *api.ArangoDeployment) (agency.Agency, error) {
var dnsNames []string
for _, m := range apiObject.Status.Members.Agents {
dnsName := k8sutil.CreatePodDNSName(apiObject, api.ServerGroupAgents.AsRole(), m.ID)
dnsName := k8sutil.CreatePodDNSNameWithDomain(apiObject, apiObject.Spec.ClusterDomain, api.ServerGroupAgents.AsRole(), m.ID)
dnsNames = append(dnsNames, dnsName)
}
shortTimeout := false
@ -191,7 +191,7 @@ func CreateArangodAgencyClient(ctx context.Context, cli corev1.CoreV1Interface,
// running in an Image-ID pod.
func CreateArangodImageIDClient(ctx context.Context, deployment k8sutil.APIObject, role, id string) (driver.Client, error) {
// Create connection
dnsName := k8sutil.CreatePodDNSName(deployment, role, id)
dnsName := k8sutil.CreatePodDNSNameWithDomain(deployment, nil, role, id)
c, err := createArangodClientForDNSName(ctx, nil, nil, dnsName, false)
if err != nil {
return nil, errors.WithStack(err)

View file

@ -23,25 +23,47 @@
package k8sutil
import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func appendDeploymentClusterDomain(dns string, domain *string) string {
if domain == nil || *domain == "" {
return dns
}
return fmt.Sprintf("%s.%s", dns, *domain)
}
// CreatePodDNSName returns the DNS of a pod with a given role & id in
// a given deployment.
func CreatePodDNSName(deployment metav1.Object, role, id string) string {
return CreatePodHostName(deployment.GetName(), role, id) + "." +
CreateHeadlessServiceName(deployment.GetName()) + "." +
deployment.GetNamespace() + ".svc"
return fmt.Sprintf("%s.%s.%s.svc", CreatePodHostName(deployment.GetName(), role, id), CreateHeadlessServiceName(deployment.GetName()), deployment.GetNamespace())
}
// CreatePodDNSName returns the DNS of a pod with a given role & id in
// a given deployment.
func CreatePodDNSNameWithDomain(deployment metav1.Object, domain *string, role, id string) string {
return appendDeploymentClusterDomain(CreatePodDNSName(deployment, role, id), domain)
}
// CreateDatabaseClientServiceDNSNameWithDomain returns the DNS of the database client service.
func CreateDatabaseClientServiceDNSNameWithDomain(deployment metav1.Object, domain *string) string {
return appendDeploymentClusterDomain(CreateDatabaseClientServiceDNSName(deployment), domain)
}
// CreateDatabaseClientServiceDNSName returns the DNS of the database client service.
func CreateDatabaseClientServiceDNSName(deployment metav1.Object) string {
return CreateDatabaseClientServiceName(deployment.GetName()) + "." +
deployment.GetNamespace() + ".svc"
return fmt.Sprintf("%s.%s.svc", CreateDatabaseClientServiceName(deployment.GetName()), deployment.GetNamespace())
}
// CreateSyncMasterClientServiceDNSNameWithDomain returns the DNS of the syncmaster client service.
func CreateSyncMasterClientServiceDNSNameWithDomain(deployment metav1.Object, domain *string) string {
return appendDeploymentClusterDomain(CreateSyncMasterClientServiceDNSName(deployment), domain)
}
// CreateSyncMasterClientServiceDNSName returns the DNS of the syncmaster client service.
func CreateSyncMasterClientServiceDNSName(deployment metav1.Object) string {
return CreateSyncMasterClientServiceName(deployment.GetName()) + "." +
deployment.GetNamespace() + ".svc"
return fmt.Sprintf("%s.%s.svc", CreateSyncMasterClientServiceName(deployment.GetName()), deployment.GetNamespace())
}

View file

@ -25,6 +25,8 @@ package k8sutil
import (
"testing"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -49,3 +51,13 @@ func TestCreateDatabaseClientServiceDNSName(t *testing.T) {
n := CreateDatabaseClientServiceDNSName(depl)
assert.Equal(t, "test.ns.svc", n)
}
func TestCreatePodDNSNameWithDomain(t *testing.T) {
depl := &metav1.ObjectMeta{
Name: "test",
Namespace: "ns",
}
assert.Equal(t, "test-agent-id1.test-int.ns.svc", CreatePodDNSNameWithDomain(depl, nil, "agent", "id1"))
assert.Equal(t, "test-agent-id1.test-int.ns.svc.cluster.local", CreatePodDNSNameWithDomain(depl, util.NewString("cluster.local"), "agent", "id1"))
}

View file

@ -24,6 +24,22 @@ package util
import "fmt"
func CompareStrings(a, b string) bool {
return a == b
}
func CompareStringPointers(a, b *string) bool {
if a == nil && b == nil {
return true
}
if a == nil || b == nil {
return false
}
return CompareStrings(*a, *b)
}
func CompareStringArray(a, b []string) bool {
if len(a) != len(b) {
return false