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

Get elastic-agent-managed-daemonset.yaml from upstream 7.x instead of using a local static file #452

Merged
8 changes: 1 addition & 7 deletions internal/configuration/locations/locations.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ const (

fieldsCachedDir = "cache/fields"

kubernetesDeployerElasticAgentYmlFile = "elastic-agent.yml"
terraformDeployerYmlFile = "terraform-deployer.yml"
terraformDeployerYmlFile = "terraform-deployer.yml"
)

var (
Expand Down Expand Up @@ -84,11 +83,6 @@ func (loc LocationManager) KubernetesDeployerDir() string {
return filepath.Join(loc.stackPath, kubernetesDeployerDir)
}

// KubernetesDeployerAgentYml returns the Kubernetes Deployer Elastic Agent yml
func (loc LocationManager) KubernetesDeployerAgentYml() string {
return filepath.Join(loc.stackPath, kubernetesDeployerDir, kubernetesDeployerElasticAgentYmlFile)
}

// TerraformDeployerDir returns the Terraform Directory
func (loc LocationManager) TerraformDeployerDir() string {
return filepath.Join(loc.stackPath, terraformDeployerDir)
Expand Down
26 changes: 0 additions & 26 deletions internal/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"

"github.com/pkg/errors"
Expand Down Expand Up @@ -61,11 +60,6 @@ func EnsureInstalled() error {
return errors.Wrap(err, "writing stack resources failed")
}

err = writeKubernetesDeployerResources(elasticPackagePath)
if err != nil {
return errors.Wrap(err, "writing Kubernetes deployer resources failed")
}

err = writeTerraformDeployerResources(elasticPackagePath)
if err != nil {
return errors.Wrap(err, "writing Terraform deployer resources failed")
Expand Down Expand Up @@ -173,26 +167,6 @@ func writeStackResources(elasticPackagePath *locations.LocationManager) error {

}

func writeKubernetesDeployerResources(elasticPackagePath *locations.LocationManager) error {
err := os.MkdirAll(elasticPackagePath.KubernetesDeployerDir(), 0755)
if err != nil {
return errors.Wrapf(err, "creating directory failed (path: %s)", elasticPackagePath.KubernetesDeployerDir())
}

appConfig, err := Configuration()
if err != nil {
return errors.Wrap(err, "can't read application configuration")
}

err = writeStaticResource(err, elasticPackagePath.KubernetesDeployerAgentYml(),
strings.ReplaceAll(kubernetesDeployerElasticAgentYml, "{{ ELASTIC_AGENT_IMAGE_REF }}",
appConfig.DefaultStackImageRefs().ElasticAgent))
if err != nil {
return errors.Wrap(err, "writing static resource failed")
}
return nil
}

func writeTerraformDeployerResources(elasticPackagePath *locations.LocationManager) error {
terraformDeployer := elasticPackagePath.TerraformDeployerDir()
err := os.MkdirAll(terraformDeployer, 0755)
Expand Down
19 changes: 19 additions & 0 deletions internal/kubectl/kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package kubectl
import (
"bytes"
"os/exec"
"strings"

"github.com/pkg/errors"

Expand Down Expand Up @@ -49,3 +50,21 @@ func modifyKubernetesResources(action string, definitionPaths ...string) ([]byte
}
return output, nil
}

// applyKubernetesResourcesStdin applies a kubernetes manifest provided as stdin.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: a Kubernetes manifest

// It returns the resources created as output and an error
func applyKubernetesResourcesStdin(input string) ([]byte, error) {
// create kubectl apply command
kubectlCmd := exec.Command("kubectl", "apply", "-f", "-", "-o", "yaml")
//Stdin of kubectl command is the manifest provided
kubectlCmd.Stdin = strings.NewReader(input)
errOutput := new(bytes.Buffer)
kubectlCmd.Stderr = errOutput

logger.Debugf("run command: %s", kubectlCmd)
output, err := kubectlCmd.Output()
if err != nil {
return nil, errors.Wrapf(err, "kubectl apply failed (stderr=%q)", errOutput.String())
}
return output, nil
}
16 changes: 16 additions & 0 deletions internal/kubectl/kubectl_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,22 @@ func Apply(definitionPaths ...string) error {
return nil
}

// ApplyStdin function adds resources to the Kubernetes cluster based on provided stdin.
func ApplyStdin(input string) error {
logger.Debugf("Apply Kubernetes stdin")
out, err := applyKubernetesResourcesStdin(input)
if err != nil {
return errors.Wrap(err, "can't modify Kubernetes resources (apply from stdin)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think you're right in L89, "apply stdin"

}

logger.Debugf("Handle \"apply\" command output")
err = handleApplyCommandOutput(out)
if err != nil {
return errors.Wrap(err, "can't handle command output")
}
return nil
}

func handleApplyCommandOutput(out []byte) error {
logger.Debugf("Extract resources from command output")
resources, err := extractResources(out)
Expand Down
55 changes: 51 additions & 4 deletions internal/testrunner/runners/system/servicedeployer/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@
package servicedeployer

import (
"io"
"io/ioutil"
"net/http"
"path/filepath"
"regexp"
"strings"

"github.com/pkg/errors"

"github.com/elastic/elastic-package/internal/configuration/locations"
"github.com/elastic/elastic-package/internal/install"
"github.com/elastic/elastic-package/internal/kind"
"github.com/elastic/elastic-package/internal/kubectl"
"github.com/elastic/elastic-package/internal/logger"
)

const elasticAgentManagedYamlURL = "https://raw.githubusercontent.com/elastic/beats/7.x/deploy/kubernetes/elastic-agent-managed-kubernetes.yaml"

// KubernetesServiceDeployer is responsible for deploying resources in the Kubernetes cluster.
type KubernetesServiceDeployer struct {
definitionsDir string
Expand Down Expand Up @@ -144,14 +149,56 @@ func findKubernetesDefinitions(definitionsDir string) ([]string, error) {
func installElasticAgentInCluster() error {
logger.Debug("install Elastic Agent in the Kubernetes cluster")

locationManager, err := locations.NewLocationManager()
elasticAgentManagedYaml, err := getElasticAgentYaml()
if err != nil {
return errors.Wrap(err, "can't locate Kubernetes file for Elastic Agent in ")
return errors.Wrap(err, "can't retrieve Kubernetes file for Elastic Agent")
}

err = kubectl.Apply(locationManager.KubernetesDeployerAgentYml())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: logger debug: downloaded N bytes

err = kubectl.ApplyStdin(elasticAgentManagedYaml)
if err != nil {
return errors.Wrap(err, "can't install Elastic-Agent in Kubernetes cluster")
}
return nil
}

// downloadElasticAgentManagedYAML will download a url from a path and return the response body as a string.
func downloadElasticAgentManagedYAML(url string) (string, error) {
// Get the data
resp, err := http.Get(url)
if err != nil {
return "", errors.Wrapf(err, "failed to get file from url %s", url)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: from URL

}
defer resp.Body.Close()

// Convert to string
b, err := io.ReadAll(resp.Body)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it necessary to go with string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not necessary. I did that in order to use it later in Regexp ReplaceAllString.
But I can instead use ReplaceAll that takes a slice of bytes as input.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I can instead use ReplaceAll that takes a slice of bytes as input.

Sounds good to me

if err != nil {
return "", errors.Wrap(err, "failed to read response body")
}
return string(b), nil
}

// getElasticAgentYaml retrieves elastic-agent-managed.yaml from upstream and modifies the file as needed
// to run locally.
func getElasticAgentYaml() (string, error) {
appConfig, err := install.Configuration()
if err != nil {
return "", errors.Wrap(err, "can't read application configuration")
}
elasticAgentManagedYaml, err := downloadElasticAgentManagedYAML(elasticAgentManagedYamlURL)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: YAML comes as bytes. Did you check if we can skip converting to string? It seems that byte-body will fit well here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please add a logger debug indicating the download from upstream

if err != nil {
return "", errors.Wrapf(err, "downloading failed for file from source %s", elasticAgentManagedYamlURL)
}

// Set regex to match fleet url from yaml file
fleetURLRegex := regexp.MustCompile("http(s){0,1}:\\/\\/fleet-server:(\\d+)")
// Replace fleet url
elasticAgentManagedYaml = fleetURLRegex.ReplaceAllString(elasticAgentManagedYaml, "http://fleet-server:8220")

// Set regex to match image name from yaml file
imageRegex := regexp.MustCompile("docker.elastic.co/beats/elastic-agent:\\d.+")
// Replace image name
elasticAgentManagedYaml = imageRegex.ReplaceAllString(elasticAgentManagedYaml, appConfig.DefaultStackImageRefs().ElasticAgent)

return elasticAgentManagedYaml, nil
}
3 changes: 3 additions & 0 deletions test/packages/kubernetes/_dev/build/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies:
ecs:
reference: [email protected]
4 changes: 4 additions & 0 deletions test/packages/kubernetes/data_stream/pod/fields/ecs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@
- name: service.type
type: keyword
description: Service type
- name: orchestrator.cluster.name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To enable dependency management here, you need to include build.yaml file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I will just add this file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to format it with elastic-package format:

[2021-07-30T13:08:28.902Z] Error: checking package failed: formatting the integration failed (path: /var/lib/jenkins/workspace/t-manager_elastic-package_PR-452/src/github.com/elastic/elastic-package/test/packages/kubernetes, failFast: true): walking through the integration files failed: formatting file failed (path: /var/lib/jenkins/workspace/t-manager_elastic-package_PR-452/src/github.com/elastic/elastic-package/test/packages/kubernetes/_dev/build/build.yml): file is not formatted (path: /var/lib/jenkins/workspace/t-manager_elastic-package_PR-452/src/github.com/elastic/elastic-package/test/packages/kubernetes/_dev/build/build.yml)

external: ecs
- name: orchestrator.cluster.url
external: ecs