Skip to content

Commit

Permalink
Manage the local cluster (elastic#18)
Browse files Browse the repository at this point in the history
* Create stub for CLI

* Run make check

* Add README file

* Fix: README

* Fix make check

* Stub for manage cluster

* Install static resources

* Remove empty line

* Shellinit

* Extract docker-compose config for volume

* Use configDir

* Write .env file

* Boot up and tear down the cluster

* Fix: write empty env file

* Fix: go mod vendor
  • Loading branch information
mtojek authored Jun 10, 2020
1 parent f277876 commit 07c536d
Show file tree
Hide file tree
Showing 42 changed files with 11,179 additions and 6 deletions.
54 changes: 49 additions & 5 deletions cmd/elastic-package/cluster.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,58 @@
package main

import "github.com/spf13/cobra"
import (
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/elastic/elastic-package/internal/cluster"
)

func setupClusterCommand() *cobra.Command {
return &cobra.Command{
Use: "cluster",
Short: "Manage the testing environment",
Long: "Use cluster command to boot up and take down the local testing cluster.",
upCommand := &cobra.Command{
Use: "up",
Short: "Boot up the testing cluster",
RunE: func(cmd *cobra.Command, args []string) error {
err := cluster.BootUp()
if err != nil {
return errors.Wrap(err, "booting up the cluster failed")
}
return nil
},
}

downCommand := &cobra.Command{
Use: "down",
Short: "Take down the testing cluster",
RunE: func(cmd *cobra.Command, args []string) error {
err := cluster.TearDown()
if err != nil {
return errors.Wrap(err, "tearing down the cluster failed")
}
return nil
},
}

shellInitCommand := &cobra.Command{
Use: "shellinit",
Short: "Initiate environment variables",
RunE: func(cmd *cobra.Command, args []string) error {
shell, err := cluster.ShellInit()
if err != nil {
return errors.Wrap(err, "shellinit failed")
}
cmd.Println(shell)
return nil
},
}

cmd := &cobra.Command{
Use: "cluster",
Short: "Manage the testing environment",
Long: "Use cluster command to boot up and take down the local testing cluster.",
}
cmd.AddCommand(
upCommand,
downCommand,
shellInitCommand)
return cmd
}
10 changes: 10 additions & 0 deletions cmd/elastic-package/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,23 @@ package main
import (
"log"

"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/elastic/elastic-package/internal/install"
)

func main() {
rootCmd := &cobra.Command{
Use: "elastic-package",
Short: "elastic-package - Command line tool for developing Elastic Integrations",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
err := install.EnsureInstalled()
if err != nil {
return errors.Wrap(err, "checking installation failed")
}
return nil
},
}
rootCmd.AddCommand(
setupClusterCommand(),
Expand Down
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ module github.com/elastic/elastic-package

go 1.14

require github.com/spf13/cobra v1.0.0
require (
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.0.0
gopkg.in/yaml.v2 v2.3.0
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
Expand Down Expand Up @@ -124,4 +126,6 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Empty file removed internal/cluster/.empty
Empty file.
100 changes: 100 additions & 0 deletions internal/cluster/boot_up.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package cluster

import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"

"github.com/pkg/errors"

"github.com/elastic/elastic-package/internal/install"
)

const envFile = ".env"

func BootUp() error {
buildPublicPath, found, err := findBuildPublicDirectory()
if err != nil {
return errors.Wrap(err, "finding build packages directory failed")
}

var envFileContent string
if found {
fmt.Printf("Custom build/public directory found: %s\n", buildPublicPath)
envFileContent = fmt.Sprintf("PACKAGES_PATH=%s\n", buildPublicPath)
}
err = writeEnvFile(buildPublicPath, envFileContent)
if err != nil {
return errors.Wrapf(err, "writing .env file failed (packagesPath: %s)", buildPublicPath)
}

err = dockerComposeUp(found)
if err != nil {
return errors.Wrap(err, "running docker-compose failed")
}
return nil
}

func findBuildPublicDirectory() (string, bool, error) {
workDir, err := os.Getwd()
if err != nil {
return "", false, errors.Wrap(err, "locating working directory failed")
}

dir := workDir
for dir != "." {
path := filepath.Join(dir, "build", "public")
fileInfo, err := os.Stat(path)
if err == nil && fileInfo.IsDir() {
return path, true, nil
}

if dir == "/" {
break
}
dir = filepath.Dir(dir)
}
return "", false, nil
}

func writeEnvFile(buildPublicPath, content string) error {
clusterDir, err := install.ClusterDir()
if err != nil {
return errors.Wrap(err, "locating cluster directory failed")
}
envFilePath := filepath.Join(clusterDir, envFile)
err = ioutil.WriteFile(envFilePath, []byte(content), 0644)
if err != nil {
return errors.Wrapf(err, "writing file failed (path: %s)", envFilePath)
}
return nil
}

func dockerComposeUp(useCustomPackagesPath bool) error {
clusterDir, err := install.ClusterDir()
if err != nil {
return errors.Wrap(err, "locating cluster directory failed")
}

var args []string
args = append(args, "-f", filepath.Join(clusterDir, "snapshot.yml"),
"-f", filepath.Join(clusterDir, "local.yml"))

if useCustomPackagesPath {
args = append(args, "-f", filepath.Join(clusterDir, "package-registry-volume.yml"))
}

args = append(args, "--project-directory", clusterDir,
"up", "-d")

cmd := exec.Command("docker-compose", args...)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
err = cmd.Run()
if err != nil {
return errors.Wrap(err, "running command failed")
}
return nil
}
52 changes: 52 additions & 0 deletions internal/cluster/shellinit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cluster

import (
"fmt"
"io/ioutil"
"path/filepath"

"github.com/pkg/errors"
yaml "gopkg.in/yaml.v2"

"github.com/elastic/elastic-package/internal/install"
)

const shellInitFormat = `ELASTIC_PACKAGE_ELASTICSEARCH_HOST=%s
ELASTIC_PACKAGE_ELASTICSEARCH_USERNAME=%s
ELASTIC_PACKAGE_ELASTICSEARCH_PASSWORD=%s
ELASTIC_PACKAGE_KIBANA_HOST=%s`

type kibanaConfiguration struct {
ElasticsearchHosts []string `yaml:"elasticsearch.hosts"`
ElasticsearchUsername string `yaml:"elasticsearch.username"`
ElasticsearchPassword string `yaml:"elasticsearch.password"`
KibanaHost string `yaml:"xpack.ingestManager.fleet.kibana.host"`
}

func ShellInit() (string, error) {
clusterDir, err := install.ClusterDir()
if err != nil {
return "", errors.Wrap(err, "location cluster directory failed")
}

kibanaConfigurationPath := filepath.Join(clusterDir, "kibana.config.yml")
body, err := ioutil.ReadFile(kibanaConfigurationPath)
if err != nil {
return "", errors.Wrap(err, "reading Kibana configuration file failed")
}

var kibanaCfg kibanaConfiguration
err = yaml.Unmarshal(body, &kibanaCfg)
if err != nil {
return "", errors.Wrap(err, "unmarshalling Kibana configuration failed")
}

if len(kibanaCfg.ElasticsearchHosts) == 0 {
return "", errors.New("expected at least one Elasticsearch defined")
}
return fmt.Sprintf(shellInitFormat,
kibanaCfg.ElasticsearchHosts[0],
kibanaCfg.ElasticsearchUsername,
kibanaCfg.ElasticsearchPassword,
kibanaCfg.KibanaHost), nil
}
30 changes: 30 additions & 0 deletions internal/cluster/tear_down.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package cluster

import (
"os"
"os/exec"
"path/filepath"

"github.com/pkg/errors"

"github.com/elastic/elastic-package/internal/install"
)

func TearDown() error {
clusterDir, err := install.ClusterDir()
if err != nil {
return errors.Wrap(err, "locating cluster directory failed")
}

cmd := exec.Command("docker-compose",
"-f", filepath.Join(clusterDir, "snapshot.yml"),
"--project-directory", clusterDir,
"down")
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
err = cmd.Run()
if err != nil {
return errors.Wrap(err, "running command failed")
}
return nil
}
Loading

0 comments on commit 07c536d

Please sign in to comment.