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

Fix 8.0.0 related issues in E2E #4931

Merged
merged 5 commits into from
Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
13 changes: 10 additions & 3 deletions pkg/apis/apm/v1/apmserver_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ package v1

import (
"fmt"
"strings"

"github.com/blang/semver/v4"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

Expand Down Expand Up @@ -120,9 +120,16 @@ func (as *ApmServer) ServiceAccountName() string {
return as.Spec.ServiceAccountName
}

// EffectiveVersion returns the version reported by APM server. For development builds APM server does not use the SNAPSHOT suffix.
// EffectiveVersion returns the version as it would be reported by APM server. For development builds
// APM server does not use prerelease or build suffixes.
func (as *ApmServer) EffectiveVersion() string {
return strings.TrimSuffix(as.Spec.Version, "-SNAPSHOT")
ver, err := semver.FinalizeVersion(as.Spec.Version)
if err != nil {
// just pass it back if it's malformed
return as.Spec.Version
}

return ver
}

func (as *ApmServer) GetAssociations() []commonv1.Association {
Expand Down
45 changes: 45 additions & 0 deletions pkg/apis/apm/v1/apmserver_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,48 @@ func TestApmKibanaAssociation_AssociationConfAnnotationName(t *testing.T) {
aka := ApmKibanaAssociation{}
require.Equal(t, "association.k8s.elastic.co/kb-conf", aka.AssociationConfAnnotationName())
}

func TestEffectiveVersion(t *testing.T) {
for _, tt := range []struct {
name string
version string
wantVersion string
}{
{
name: "no suffix",
version: "7.16.0",
wantVersion: "7.16.0",
},
{
name: "prerelase suffix",
version: "7.16.0-alpha1",
wantVersion: "7.16.0",
},
{
name: "SNAPSHOT prerelease suffix",
version: "8.0.0-SNAPSHOT",
wantVersion: "8.0.0",
},
{
name: "build suffix",
version: "8.0.0+3fae3fc",
wantVersion: "8.0.0",
},
{
name: "build and prerelease suffix",
version: "8.0.0+3fae3fc-SNAPSHOT",
wantVersion: "8.0.0",
},
{
name: "malformed version",
version: "7.8.bad",
wantVersion: "7.8.bad",
},
} {
t.Run(tt.name, func(t *testing.T) {
apm := ApmServer{Spec: ApmServerSpec{Version: tt.version}}
gotVersion := apm.EffectiveVersion()
require.Equal(t, tt.wantVersion, gotVersion)
})
}
}
20 changes: 20 additions & 0 deletions pkg/controller/common/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ var (
// Due to bugfixes present in 7.14 that ECK depends on, this is the lowest version we support in Fleet mode.
SupportedFleetModeAgentVersions = MinMaxVersion{Min: MustParse("7.14.0-SNAPSHOT"), Max: From(8, 99, 99)}
SupportedMapsVersions = MinMaxVersion{Min: From(7, 11, 0), Max: From(8, 99, 99)}

// minPreReleaseVersion is the lowest prerelease identifier as numeric prerelease takes precedence before
// alphanumeric ones and it can't have leading zeros.
minPreReleaseVersion = mustNewPRVersion("1")
)

// MinMaxVersion holds the minimum and maximum supported versions.
Expand Down Expand Up @@ -80,6 +84,13 @@ func From(major, minor, patch int) Version {
return Version{Major: uint64(major), Minor: uint64(minor), Patch: uint64(patch)}
}

// MinFrom creates a new version from the given major, minor, patch numbers with lowest PreRelease version, ie.
// the returned Version is the lowest possible version with those major, minor and patch numbers.
// See https://semver.org/#spec-item-11.
func MinFrom(major, minor, patch uint64) Version {
david-kow marked this conversation as resolved.
Show resolved Hide resolved
return Version{Major: major, Minor: minor, Patch: patch, Pre: []semver.PRVersion{minPreReleaseVersion}}
}

// MinInPods returns the lowest version parsed from labels in the given Pods.
func MinInPods(pods []corev1.Pod, labelName string) (*Version, error) {
var min *Version
Expand Down Expand Up @@ -127,3 +138,12 @@ func FromLabels(labels map[string]string, labelName string) (Version, error) {

return v, nil
}

func mustNewPRVersion(s string) semver.PRVersion {
ver, err := semver.NewPRVersion(s)
if err != nil {
panic(`version: mustNewPRVersion(` + s + `): ` + err.Error())
}

return ver
}
27 changes: 27 additions & 0 deletions pkg/controller/common/version/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package version

import (
"fmt"
"reflect"
"testing"

Expand Down Expand Up @@ -298,3 +299,29 @@ func TestMinMaxVersion_WithMin(t *testing.T) {
})
}
}

func TestMinFrom(t *testing.T) {
for _, tt := range []struct {
name string
major, minor, patch uint64
}{
{
name: "8.0.0",
major: 8,
minor: 0,
patch: 0,
},
{
name: "7.99.99",
major: 7,
minor: 99,
patch: 99,
},
} {
t.Run(tt.name, func(t *testing.T) {
gotVer := MinFrom(tt.major, tt.minor, tt.patch)
require.True(t, gotVer.LT(From(int(tt.major), int(tt.minor), int(tt.patch))))
require.True(t, gotVer.EQ(MustParse(fmt.Sprintf("%d.%d.%d-1", tt.major, tt.minor, tt.patch))))
})
}
}
13 changes: 5 additions & 8 deletions pkg/controller/enterprisesearch/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,18 +268,15 @@ func associationConfig(c k8s.Client, ent entv1.EnterpriseSearch) (*settings.Cano
return settings.NewCanonicalConfig(), nil
}

cfg := settings.MustCanonicalConfig(map[string]string{
"ent_search.auth.source": "elasticsearch-native",
})
ver, err := version.Parse(ent.Spec.Version)
if err != nil {
return nil, err
}
// origin of authenticated ent users setting changed starting 8.x
if ver.Major >= uint64(8) {
cfg = settings.MustCanonicalConfig(map[string]interface{}{
"ent_search.auth.native1.source": "elasticsearch-native",
"ent_search.auth.native1.order": -100,

cfg := settings.NewCanonicalConfig()
if ver.LT(version.MinFrom(8, 0, 0)) {
cfg = settings.MustCanonicalConfig(map[string]string{
"ent_search.auth.source": "elasticsearch-native",
})
}

Expand Down
4 changes: 0 additions & 4 deletions pkg/controller/enterprisesearch/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,10 +389,6 @@ func TestReconcileConfig(t *testing.T) {
"enabled: true",
"username: ns-sample-ent-user",
"ent_search:",
"auth:",
"native1:",
"source: elasticsearch-native",
"order: -100",
"external_url: https://localhost:3002",
"filebeat_log_directory: /var/log/enterprise-search",
"listen_host: 0.0.0.0",
Expand Down
28 changes: 22 additions & 6 deletions pkg/controller/kibana/config_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ const (
const (
ServerName = "server.name"
ServerHost = "server.host"
XpackMonitoringUIContainerElasticsearchEnabled = "xpack.monitoring.ui.container.elasticsearch.enabled"
XpackLicenseManagementUIEnabled = "xpack.license_management.ui.enabled" // >= 7.6
XpackMonitoringUIContainerElasticsearchEnabled = "xpack.monitoring.ui.container.elasticsearch.enabled" // <= 7.15
MonitoringUIContainerElasticsearchEnabled = "monitoring.ui.container.elasticsearch.enabled" // >= 7.16
XpackLicenseManagementUIEnabled = "xpack.license_management.ui.enabled" // >= 7.6
XpackSecurityEncryptionKey = "xpack.security.encryptionKey"
XpackReportingEncryptionKey = "xpack.reporting.encryptionKey"
XpackEncryptedSavedObjects = "xpack.encryptedSavedObjects"
Expand Down Expand Up @@ -101,7 +102,12 @@ func NewConfigSettings(ctx context.Context, client k8s.Client, kb kbv1.Kibana, v
return CanonicalConfig{}, err
}

cfg := settings.MustCanonicalConfig(baseSettings(&kb, ipFamily))
baseSettingsMap, err := baseSettings(&kb, ipFamily)
if err != nil {
return CanonicalConfig{}, err
}

cfg := settings.MustCanonicalConfig(baseSettingsMap)
kibanaTLSCfg := settings.MustCanonicalConfig(kibanaTLSSettings(kb))
versionSpecificCfg := VersionDefaults(&kb, v)
entSearchCfg := settings.MustCanonicalConfig(enterpriseSearchSettings(kb))
Expand Down Expand Up @@ -239,19 +245,29 @@ func getOrCreateReusableSettings(c k8s.Client, kb kbv1.Kibana) (*settings.Canoni
return settings.MustCanonicalConfig(r), nil
}

func baseSettings(kb *kbv1.Kibana, ipFamily corev1.IPFamily) map[string]interface{} {
func baseSettings(kb *kbv1.Kibana, ipFamily corev1.IPFamily) (map[string]interface{}, error) {
ver, err := version.Parse(kb.Spec.Version)
if err != nil {
return nil, err
}

conf := map[string]interface{}{
ServerName: kb.Name,
ServerHost: net.InAddrAnyFor(ipFamily).String(),
XpackMonitoringUIContainerElasticsearchEnabled: true,
}

if ver.GTE(version.MinFrom(7, 16, 0)) {
conf[MonitoringUIContainerElasticsearchEnabled] = true
} else {
conf[XpackMonitoringUIContainerElasticsearchEnabled] = true
}

assocConf := kb.EsAssociation().AssociationConf()
if assocConf.URLIsConfigured() {
conf[ElasticsearchHosts] = []string{assocConf.GetURL()}
}

return conf
return conf, nil
}

func kibanaTLSSettings(kb kbv1.Kibana) map[string]interface{} {
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/es/certs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ func TestCustomTransportCA(t *testing.T) {

func TestUpdateHTTPCertSAN(t *testing.T) {
b := elasticsearch.NewBuilder("test-http-cert-san").
WithESMasterNodes(1, elasticsearch.DefaultResources)
WithESMasterDataNodes(1, elasticsearch.DefaultResources)

var caCert []byte
var podIP string
Expand Down
41 changes: 26 additions & 15 deletions test/e2e/es/reversal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,31 @@ func TestReversalStatefulSetRename(t *testing.T) {

func TestRiskyMasterReconfiguration(t *testing.T) {
b := elasticsearch.NewBuilder("test-sset-reconfig-reversal").
WithESMasterDataNodes(1, elasticsearch.DefaultResources).
WithNodeSet(esv1.NodeSet{
Name: "other-master",
Count: 1,
Config: &commonv1.Config{
Data: map[string]interface{}{
esv1.NodeMaster: true,
esv1.NodeData: true,
},
},
PodTemplate: elasticsearch.ESPodTemplate(elasticsearch.DefaultResources),
WithESMasterDataNodes(1, elasticsearch.DefaultResources)

cfg := elasticsearch.CreateRolesConfig(
b.Elasticsearch.Spec.Version,
[]esv1.NodeRole{esv1.MasterRole, esv1.DataRole},
map[string]bool{
esv1.NodeMaster: true,
esv1.NodeData: true,
})

b = b.WithNodeSet(esv1.NodeSet{
Name: "other-master",
Count: 1,
Config: &commonv1.Config{
Data: cfg,
},
PodTemplate: elasticsearch.ESPodTemplate(elasticsearch.DefaultResources),
})

noMasterCfg := elasticsearch.CreateRolesConfig(
b.Elasticsearch.Spec.Version,
[]esv1.NodeRole{esv1.DataRole},
map[string]bool{
esv1.NodeMaster: false,
esv1.NodeData: true,
})

// this currently breaks the cluster (something we might fix in the future at which point this just tests a temp downscale)
Expand All @@ -77,10 +91,7 @@ func TestRiskyMasterReconfiguration(t *testing.T) {
Name: "other-master",
Count: 1,
Config: &commonv1.Config{
Data: map[string]interface{}{
esv1.NodeMaster: false,
esv1.NodeData: true,
},
Data: noMasterCfg,
},
PodTemplate: elasticsearch.ESPodTemplate(elasticsearch.DefaultResources),
})
Expand Down
8 changes: 7 additions & 1 deletion test/e2e/es/volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

commonv1 "github.com/elastic/cloud-on-k8s/pkg/apis/common/v1"
esv1 "github.com/elastic/cloud-on-k8s/pkg/apis/elasticsearch/v1"
"github.com/elastic/cloud-on-k8s/pkg/controller/common/version"
"github.com/elastic/cloud-on-k8s/pkg/utils/k8s"
"github.com/elastic/cloud-on-k8s/test/e2e/test"
"github.com/elastic/cloud-on-k8s/test/e2e/test/elasticsearch"
Expand All @@ -29,7 +30,7 @@ import (
// TestVolumeEmptyDir tests a manual override of the default persistent storage with emptyDir.
func TestVolumeEmptyDir(t *testing.T) {
b := elasticsearch.NewBuilder("test-es-explicit-empty-dir").
WithESMasterNodes(1, elasticsearch.DefaultResources).
WithESMasterDataNodes(1, elasticsearch.DefaultResources).
WithEmptyDirVolumes()

// volume type will be checked in creation steps
Expand Down Expand Up @@ -75,6 +76,11 @@ func TestVolumeRetention(t *testing.T) {
}

func TestVolumeMultiDataPath(t *testing.T) {
// remove when https://github.com/elastic/elasticsearch/issues/78525 is resolved
if version.MustParse(test.Ctx().ElasticStackVersion).Major >= 8 {
david-kow marked this conversation as resolved.
Show resolved Hide resolved
t.SkipNow()
}

b := elasticsearch.NewBuilder("test-es-multi-data-path").
WithNodeSet(esv1.NodeSet{
Name: "default",
Expand Down
2 changes: 0 additions & 2 deletions test/e2e/kb/testdata/kibana_standalone.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ spec:
- count: 1
name: mdi
config:
node.master: true
node.data: true
node.store.allow_mmap: false
---
apiVersion: kibana.k8s.elastic.co/v1
Expand Down
3 changes: 2 additions & 1 deletion test/e2e/stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ func TestVersionUpgradeOrdering(t *testing.T) {
apmUpdated := apm.WithVersion(updatedVersion)
ent := enterprisesearch.NewBuilder("ent").
WithNodeCount(1).
WithVersion(initialVersion).
WithVersion(initialVersion). // pre 8.x doesn't require any config, but we change the version after calling
WithoutConfig(). // NewBuilder which relies on the version from test.Ctx(), so removing config here
WithElasticsearchRef(esRef).
WithRestrictedSecurityContext()
entUpdated := ent.WithVersion(updatedVersion)
Expand Down
Loading