Skip to content
This repository has been archived by the owner on Sep 17, 2024. It is now read-only.

feat: sync Docker Compose files with Beats Integrations #84

Merged
merged 42 commits into from
Feb 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
10388e0
feat: support cloning git repositories
mdelapenya Feb 11, 2020
71dac4d
feat: add a subcommand to download elastic/beats using its master branch
mdelapenya Feb 11, 2020
0e720cb
chore: add a VSCode configuration for debugging new command
mdelapenya Feb 11, 2020
a840bbd
feat: support using another remote different than upstream
mdelapenya Feb 11, 2020
0792353
feat: support removing the existing repository before cloning
mdelapenya Feb 11, 2020
eed2d4b
feat: copy integrations compose file into the workspace
mdelapenya Feb 11, 2020
0c40b76
chore: migrate existing services and stacks to the new format
mdelapenya Feb 12, 2020
b00d92c
chore: add compose files for all integrations from Beats
mdelapenya Feb 12, 2020
7cd468f
feat: store new compose and related files into the packr box
mdelapenya Feb 12, 2020
dfdb525
chore: sync docker-compose version with Beats
mdelapenya Feb 12, 2020
9429684
fix: add services and stacks that are present at tool's workspace
mdelapenya Feb 12, 2020
d4c7b69
chore: do not bundle the tool with any service
mdelapenya Feb 12, 2020
30370f8
docs: update CLI docs
mdelapenya Feb 12, 2020
1782e10
chore: sync integration services using the build
mdelapenya Feb 12, 2020
9176313
chore: run go mod tidy
mdelapenya Feb 12, 2020
8ee8a1d
feat: support calculating a service's environment variables from CLI …
mdelapenya Feb 13, 2020
68c57e1
chore: do not pollute io file with compose business logic
mdelapenya Feb 13, 2020
a2d490c
fix: only copy services including a supported-versions.yml file
mdelapenya Feb 13, 2020
7920118
fix: simplify calculating service environment variables
mdelapenya Feb 13, 2020
f44ec0b
chore: move exists method to io file
mdelapenya Feb 13, 2020
d70a5c4
chore: rename method to be more descriptive
mdelapenya Feb 13, 2020
57a9dd4
chore: use io's mkdirall everywhere
mdelapenya Feb 13, 2020
3e2bc59
chore: move writeFile to io
mdelapenya Feb 13, 2020
b06ce15
chore: move readDir to io
mdelapenya Feb 13, 2020
55d042c
chore: move func close to its struct
mdelapenya Feb 13, 2020
b740aa2
chore: update vscode debug configurations
mdelapenya Feb 13, 2020
c2f4d1a
feat: support persisting the state of each run in a file
mdelapenya Feb 14, 2020
715174a
fix: retrieve service environment when running or deploying a service
mdelapenya Feb 14, 2020
464a947
feat: support updating state after docker-compose execution
mdelapenya Feb 14, 2020
e67d92a
chore: use same compose version in existing services
mdelapenya Feb 14, 2020
d37757d
chore: bump stack version to 7.6.0
mdelapenya Feb 14, 2020
754cb68
fix: use same credentials for MySQL than in the Beats image
mdelapenya Feb 17, 2020
7bcfe7a
feat: support adding the environment variables coming from the suppor…
mdelapenya Feb 17, 2020
eae1881
feat: create specific steps for service variants
mdelapenya Feb 17, 2020
a181898
fix: remove duplicated test
mdelapenya Feb 17, 2020
244540e
fix: mkdirall must create the dirs for a path, not its parent
mdelapenya Feb 17, 2020
5dc4cb0
fix: handle errors for mkdirall when needed
mdelapenya Feb 17, 2020
96f571c
fix: do not capitalise variable (gocritic)
mdelapenya Feb 17, 2020
9121592
chore: excludes from golint
mdelapenya Feb 18, 2020
330d262
fix: rename flag to a more descriptive name
mdelapenya Feb 18, 2020
fc79996
fix: typos in docs
mdelapenya Feb 18, 2020
83d192b
docs: document execute method
mdelapenya Feb 18, 2020
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
3 changes: 3 additions & 0 deletions .ci/scripts/functional-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ make -C metricbeat-tests fetch-binary
# Build runtime dependencies
STACK_VERSION=${STACK_VERSION} make -C metricbeat-tests run-elastic-stack

# Sync integrations
make -C metricbeat-tests sync-integrations
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is forcing the CI to get the compose files from Beats


rm -rf outputs || true
mkdir -p outputs
REPORT=outputs/junit-functional-tests
Expand Down
42 changes: 39 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@
},
"args": ["run", "-h"]
},
{
"name": "Debug cloning a repository",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cli",
"env": {
"GO111MODULE": "on",
"OP_LOG_LEVEL": "DEBUG",
},
"args": ["sync", "integrations", "--remote", "elastic:master"]
},
{
"name": "Debug Running Services",
"type": "go",
Expand All @@ -25,6 +37,18 @@
},
"args": ["run", "service", "mysql", "--version", "5.6"]
},
{
"name": "Debug Stopping Services",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cli",
"env": {
"GO111MODULE": "on",
"OP_LOG_LEVEL": "DEBUG",
},
"args": ["stop", "service", "mysql", "--version", "5.6"]
},
{
"name": "Debug Deploying a Service",
"type": "go",
Expand All @@ -35,7 +59,7 @@
"GO111MODULE": "on",
"OP_LOG_LEVEL": "DEBUG",
},
"args": ["deploy", "mysql", "--version", "5.6asda", "--stack", "metricbeat"]
"args": ["deploy", "redis", "--version", "4.0.11", "--stack", "metricbeat"]
},
{
"name": "Debug Undeploying a Service",
Expand All @@ -47,7 +71,7 @@
"GO111MODULE": "on",
"OP_LOG_LEVEL": "DEBUG",
},
"args": ["undeploy", "mysql", "--stack", "metricbeat"]
"args": ["undeploy", "redis", "--stack", "metricbeat"]
},
{
"name": "Debug Running Stacks",
Expand All @@ -59,7 +83,19 @@
"GO111MODULE": "on",
"OP_LOG_LEVEL": "DEBUG",
},
"args": ["run", "stack", "metricbeat", "--withServices", "apache:2.2,redis:latest"]
"args": ["run", "stack", "metricbeat", "-v", "7.5.0", "--withServices", "apache:2.2,redis:3.2.12"]
},
{
"name": "Debug Stopping Stacks",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cli",
"env": {
"GO111MODULE": "on",
"OP_LOG_LEVEL": "DEBUG",
},
"args": ["stop", "stack", "metricbeat"]
},
{
"name": "Godog Tests",
Expand Down
24 changes: 15 additions & 9 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,27 @@ $ ./op stop stack observability
>By the way, `op` comes from `Observability Provisioner`.

## Configuring the CLI
The CLI uses a set of YAML files where the configuration is stored, defining a precedence in those files so that it's possible to override or append new configurations to the CLI.
The **default configuration file** is located under `$HOME/.op`, which is the workspace for the tool. If this directory does not exist when the CLI is run, it will create it under the hood, populating the default services already bundled in the tool.

The **default configuration file** is located under `$HOME/.op`, which is the workspace for the tool. If this directory does not exist when the CLI is run, it will create it under the hood, populating the configuration file (`config.yml`) with the default values.
>Those default services are defined at [config.go](./config/config.go).

>Those default values are defined at [config.go](./config/config.go).
### Updating services from Beats
The CLI includes a command to fetch Beats integrations from its GitHub repository, making it possible to add them to the list of available services. To run this command:

A **second layer for the configuration file** is defined by CLI's execution path, so if a `config.yml` exists at the location where the tool is executed, then the CLI will merge this file into the default one, with higher precedence over defaults.

**Last layer for the configuration file** is defined by the `OP_CONFIG_PATH` environment variable, so if a `config.yml` exists at the location defined by that environment variable, then the CLI will merge this file into the previous ones, with higher precedence over them.
```
$ ./op sync integrations -h
Sync services from Beats, checking out current version of the services from GitHub

This way, the configuration precedence is defined by:
Usage:
op sync integrations [flags]

`$HOME/.op/config.yml < $(pwd)/config.yml < $OP_CONFIG_PATH/config.yml`
Flags:
-h, --help help for integrations
-d, --delete Will delete the existing Beats repository before cloning it again (default false)
-r, --remote string Sets the remote for Beats, using 'user:branch' as format (i.e. elastic:master) (default "elastic:master")
```

A clear benefit of this layered configuration is to be able to define custom services/stacks at the higher layers of the configuration: the user could define a service or a stack just for that execution, which could be shared accross teams simply copying the configuration file in the proper path. If that configuration is valuable enough, it could be contributed to the tool.
It's possible to update the services from a different remote, using the `--remote` flag, as described above.

## Logging
The CLI uses [`Logrus`](https://github.com/sirupsen/logrus) as default Logger, so it's possible to configure the logger using [Logging levels](https://github.com/sirupsen/logrus#level-logging) to enrich the output of the tool.
Expand Down
10 changes: 6 additions & 4 deletions cli/cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ func buildDeployServiceCommand(srv string) *cobra.Command {
Run: func(cmd *cobra.Command, args []string) {
serviceManager := services.NewServiceManager()

env := map[string]string{
srv + "Tag": versionToRun,
}
env := map[string]string{}
env = config.PutServiceEnvironment(env, srv, versionToRun)

err := serviceManager.AddServicesToCompose(deployToStack, []string{srv}, env)
if err != nil {
Expand All @@ -82,7 +81,10 @@ func buildUndeployServiceCommand(srv string) *cobra.Command {
Run: func(cmd *cobra.Command, args []string) {
serviceManager := services.NewServiceManager()

err := serviceManager.RemoveServicesFromCompose(deployToStack, []string{srv})
env := map[string]string{}
env = config.PutServiceEnvironment(env, srv, versionToRun)

err := serviceManager.RemoveServicesFromCompose(deployToStack, []string{srv}, env)
if err != nil {
log.WithFields(log.Fields{
"stack": deployToStack,
Expand Down
7 changes: 2 additions & 5 deletions cli/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ func buildRunServiceCommand(srv string) *cobra.Command {
Run: func(cmd *cobra.Command, args []string) {
serviceManager := services.NewServiceManager()

env := map[string]string{
srv + "Tag": versionToRun,
}
env := config.PutServiceEnvironment(map[string]string{}, srv, versionToRun)

err := serviceManager.RunCompose(false, []string{srv}, env)
if err != nil {
Expand Down Expand Up @@ -91,7 +89,6 @@ func buildRunStackCommand(key string, stack config.Stack) *cobra.Command {
}

composeNames := []string{}
env = map[string]string{}
if servicesToRun != "" {
services := strings.Split(servicesToRun, ",")

Expand All @@ -100,7 +97,7 @@ func buildRunStackCommand(key string, stack config.Stack) *cobra.Command {
image := arr[0]
tag := arr[1]

env[image+"Tag"] = tag
env = config.PutServiceEnvironment(env, image, tag)
composeNames = append(composeNames, image)
}

Expand Down
117 changes: 117 additions & 0 deletions cli/cmd/sync.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package cmd

import (
"errors"
"os"
"path"
"path/filepath"
"strings"

"github.com/elastic/metricbeat-tests-poc/cli/config"
git "github.com/elastic/metricbeat-tests-poc/cli/internal"
io "github.com/elastic/metricbeat-tests-poc/cli/internal"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

var deleteRepository = false
var remote = "elastic:master"

func init() {
config.InitConfig()

syncIntegrationsCmd.Flags().BoolVarP(&deleteRepository, "delete", "d", false, "Will delete the existing Beats repository before cloning it again (default false)")
syncIntegrationsCmd.Flags().StringVarP(&remote, "remote", "r", "elastic:master", "Sets the remote for Beats, using 'user:branch' as format (i.e. elastic:master)")

syncCmd.AddCommand(syncIntegrationsCmd)
rootCmd.AddCommand(syncCmd)
}

var syncCmd = &cobra.Command{
Use: "sync",
Short: "Sync services from Beats",
Long: "Subcommands will allow synchronising services",
Run: func(cmd *cobra.Command, args []string) {
// NOOP
},
}

var syncIntegrationsCmd = &cobra.Command{
Use: "integrations",
Short: "Sync services from Beats",
Long: "Sync services from Beats, checking out current version of the services from GitHub",
Args: func(cmd *cobra.Command, args []string) error {
arr := strings.Split(remote, ":")
if len(arr) == 2 {
return nil
}
return errors.New("invalid 'user:branch' format: " + remote + ". Example: 'elastic:master'")
},
Run: func(cmd *cobra.Command, args []string) {
workspace := config.Op.Workspace

// BeatsRepo default object representing Beats project
var BeatsRepo = git.ProjectBuilder.
WithBaseWorkspace(path.Join(workspace, "git")).
WithGitProtocol().
WithDomain("github.com").
WithName("beats").
WithRemote(remote).
Build()

if deleteRepository {
repoDir := path.Join(workspace, "git", BeatsRepo.Name)

log.WithFields(log.Fields{
"path": repoDir,
}).Debug("Removing repository")
os.RemoveAll(repoDir)
log.WithFields(log.Fields{
"path": repoDir,
}).Debug("Repository removed")
}

git.Clone(BeatsRepo)
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved

copyIntegrationsComposeFiles(BeatsRepo, workspace)
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved
},
}

// CopyComposeFiles copies only those services that has a supported-versions.yml
// file from Beats integrations, and we will need to copy them into a directory
// named as the original service (i.e. aerospike) under this tool's workspace,
// alongside the services. Besides that, the method will copy the _meta directory
// for each service
func copyIntegrationsComposeFiles(beats git.Project, target string) {
pattern := path.Join(
beats.GetWorkspace(), "metricbeat", "module", "*", "_meta", "supported-versions.yml")

files := io.FindFiles(pattern)

for _, file := range files {
metaDir := filepath.Dir(file)
serviceDir := filepath.Dir(metaDir)
service := filepath.Base(serviceDir)

composeFile := filepath.Join(serviceDir, "docker-compose.yml")
targetFile := filepath.Join(
target, "compose", "services", service, "docker-compose.yml")

err := io.CopyFile(composeFile, targetFile, 10000)
if err != nil {
log.WithFields(log.Fields{
"error": err,
"file": file,
}).Warn("File was not copied")
}

targetMetaDir := filepath.Join(target, "compose", "services", service, "_meta")
err = io.CopyDir(metaDir, targetMetaDir)
if err != nil {
log.WithFields(log.Fields{
"error": err,
"_meta": metaDir,
}).Warn("Meta dir was not copied")
}
}
}
6 changes: 0 additions & 6 deletions cli/config/compose/services/apache.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '3'
version: '2.3'
services:
apm-server:
environment:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '3'
version: '2.3'
services:
elasticsearch:
environment:
Expand Down
6 changes: 0 additions & 6 deletions cli/config/compose/services/kafka.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '3'
version: '2.3'
services:
kibana:
environment:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '3'
version: '2.3'
services:
metricbeat:
command: [
Expand Down
6 changes: 0 additions & 6 deletions cli/config/compose/services/mongodb.yml

This file was deleted.

8 changes: 0 additions & 8 deletions cli/config/compose/services/mysql.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '3'
version: '2.3'
services:
opbeans-go:
environment:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '3'
version: '2.3'
services:
opbeans-java:
environment:
Expand Down
6 changes: 0 additions & 6 deletions cli/config/compose/services/redis.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '3'
version: '2.3'
services:
vsphere:
image: "nimmis/vcsim:${vsphereTag}"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '3'
version: '2.3'
services:
elasticsearch:
environment:
Expand Down
Loading