Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 0 additions & 5 deletions internal/install/application_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,6 @@ func (ir ImageRefs) AsEnv() []string {
return vars
}

// DefaultStackImageRefs function selects the appropriate set of Docker image references for the default stack version.
func (ac *ApplicationConfiguration) DefaultStackImageRefs() ImageRefs {
return ac.StackImageRefs(DefaultStackVersion)
}

// StackImageRefs function selects the appropriate set of Docker image references for the given stack version.
func (ac *ApplicationConfiguration) StackImageRefs(version string) ImageRefs {
refs := ac.c.Stack.ImageRefOverridesForVersion(version)
Expand Down
62 changes: 62 additions & 0 deletions internal/kibana/injected_metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package kibana

import (
"encoding/json"
"fmt"
"html"
"net/http"
"regexp"

"github.com/pkg/errors"
)

var kbnInjectedMetadataRegexp = regexp.MustCompile(`<kbn-injected-metadata data="(.+)"></kbn-injected-metadata>`)

// injectedMetadata represents the Kibana metadata structure exposed in the web UI.
type injectedMetadata struct {
// Stack version
Version string `json:"version"`
}

// Version method returns the Kibana version.
func (c *Client) Version() (string, error) {
statusCode, respBody, err := c.get("/login")
if err != nil {
return "", errors.Wrap(err, "could not reach login endpoint")
}
if statusCode != http.StatusOK {
return "", fmt.Errorf("could not reach login endpoint; API status code = %d; response body = %s", statusCode, string(respBody))
}

im, err := extractInjectedMetadata(respBody)
if err != nil {
return "", errors.Wrap(err, "can't extract injected metadata")
}
return im.Version, nil
}

func extractInjectedMetadata(body []byte) (*injectedMetadata, error) {
rawInjectedMetadata, err := extractRawInjectedMetadata(body)
if err != nil {
return nil, errors.Wrap(err, "can't extract raw metadata")
}

var im injectedMetadata
err = json.Unmarshal(rawInjectedMetadata, &im)
if err != nil {
return nil, errors.Wrap(err, "can't unmarshal raw injected metadata")
}
return &im, nil
}

func extractRawInjectedMetadata(body []byte) ([]byte, error) {
matches := kbnInjectedMetadataRegexp.FindSubmatch(body)
if len(matches) < 2 { // index:0 - matched regexp, index:1 - matched data
return nil, errors.New("expected to find at least one <kbn-injected-metadata> tag")
}
return []byte(html.UnescapeString(string(matches[1]))), nil
}
36 changes: 36 additions & 0 deletions internal/kibana/injected_metadata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package kibana

import (
"testing"

"github.com/stretchr/testify/require"
)

// sampleLoginPage represents Kibana login page without redundant styles, fonts, noise in metadata, etc.
var sampleLoginPage = []byte(`<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><meta name="viewport" content="width=device-width"/><title>Elastic</title><style>
@keyframes kbnProgress {
0% {
transform: scaleX(1) translateX(-100%);
}

100% {
transform: scaleX(1) translateX(100%);
}
}
</style><link rel="stylesheet" type="text/css" href="/44185/bundles/kbn-ui-shared-deps/kbn-ui-shared-deps.css"/><link rel="stylesheet" type="text/css" href="/44185/bundles/kbn-ui-shared-deps/kbn-ui-shared-deps.v8.light.css"/><link rel="stylesheet" type="text/css" href="/node_modules/@kbn/ui-framework/dist/kui_light.css"/><link rel="stylesheet" type="text/css" href="/ui/legacy_light_theme.css"/><meta name="add-styles-here"/><meta name="add-scripts-here"/></head><body><kbn-csp data="{&quot;strictCsp&quot;:false}"></kbn-csp><kbn-injected-metadata data="{&quot;version&quot;:&quot;7.15.1&quot;,&quot;buildNumber&quot;:44185,&quot;branch&quot;:&quot;7.15&quot;,&quot;basePath&quot;:&quot;&quot;}"></kbn-injected-metadata><div class="kbnWelcomeView" id="kbn_loading_message" style="display:none" data-test-subj="kbnLoadingMessage"><div class="kbnLoaderWrap"><h2 class="kbnWelcomeTitle">Please upgrade your browser</h2><div class="kbnWelcomeText">This Elastic installation has strict security requirements enabled that your current browser does not meet.</div></div><script>
// Since this is an unsafe inline script, this code will not run
// in browsers that support content security policy(CSP). This is
// intentional as we check for the existence of __kbnCspNotEnforced__ in
// bootstrap.
window.__kbnCspNotEnforced__ = true;
</script><script src="/bootstrap.js"></script></body></html>`)

func TestExtractRawInjectedMetadata(t *testing.T) {
im, err := extractInjectedMetadata(sampleLoginPage)
require.NoError(t, err)
require.Equal(t, "7.15.1", im.Version)
}
19 changes: 16 additions & 3 deletions internal/testrunner/runners/system/servicedeployer/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/pkg/errors"

"github.com/elastic/elastic-package/internal/install"
"github.com/elastic/elastic-package/internal/kibana"
"github.com/elastic/elastic-package/internal/kind"
"github.com/elastic/elastic-package/internal/kubectl"
"github.com/elastic/elastic-package/internal/logger"
Expand Down Expand Up @@ -141,7 +142,17 @@ func findKubernetesDefinitions(definitionsDir string) ([]string, error) {
func installElasticAgentInCluster() error {
logger.Debug("install Elastic Agent in the Kubernetes cluster")

elasticAgentManagedYaml, err := getElasticAgentYAML()
kibanaClient, err := kibana.NewClient()
if err != nil {
return errors.Wrap(err, "can't create Kibana client")
}

stackVersion, err := kibanaClient.Version()
if err != nil {
return errors.Wrap(err, "can't read Kibana injected metadata")
}

elasticAgentManagedYaml, err := getElasticAgentYAML(stackVersion)
if err != nil {
return errors.Wrap(err, "can't retrieve Kubernetes file for Elastic Agent")
}
Expand All @@ -156,7 +167,9 @@ func installElasticAgentInCluster() error {
//go:embed elastic-agent-managed.yaml.tmpl
var elasticAgentManagedYamlTmpl string

func getElasticAgentYAML() ([]byte, error) {
func getElasticAgentYAML(stackVersion string) ([]byte, error) {
logger.Debugf("Prepare YAML definition for Elastic Agent running in stack v%s", stackVersion)

appConfig, err := install.Configuration()
if err != nil {
return nil, errors.Wrap(err, "can't read application configuration")
Expand All @@ -167,7 +180,7 @@ func getElasticAgentYAML() ([]byte, error) {
var elasticAgentYaml bytes.Buffer
err = tmpl.Execute(&elasticAgentYaml, map[string]string{
"fleetURL": "http://fleet-server:8220",
"elasticAgentImage": appConfig.DefaultStackImageRefs().ElasticAgent,
"elasticAgentImage": appConfig.StackImageRefs(stackVersion).ElasticAgent,
})
if err != nil {
return nil, errors.Wrap(err, "can't generate elastic agent manifest")
Expand Down