Skip to content

Commit

Permalink
Add serverless provider (#1374)
Browse files Browse the repository at this point in the history
Add support to create serverless projects and test packages using
elastic-package with a new provider (--provider serverless).
Currently, supported serverless projects in elastic-package are
observability and security. For testing packages in serverless, geoIP
fields in documents are skipped when comparing with the expected
documents, since it could not be set a specific GeoIP database to make
the tests stable.
  • Loading branch information
mrodm authored Sep 7, 2023
1 parent ec2bd80 commit 9d80c6c
Show file tree
Hide file tree
Showing 17 changed files with 1,275 additions and 35 deletions.
4 changes: 2 additions & 2 deletions internal/kibana/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ func NewClient(opts ...ClientOption) (*Client, error) {
// Allow to initialize version from tests.
var zeroVersion VersionInfo
if c.semver == nil || c.versionInfo == zeroVersion {
v, err := c.requestVersion()
v, err := c.requestStatus()
if err != nil {
return nil, fmt.Errorf("failed to get Kibana version: %w", err)
}
c.versionInfo = v
c.versionInfo = v.Version

c.semver, err = semver.NewVersion(c.versionInfo.Number)
if err != nil {
Expand Down
45 changes: 45 additions & 0 deletions internal/kibana/fleet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// 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"
"errors"
"fmt"
"net/http"
)

// DefaultFleetServerURL returns the default Fleet server configured in Kibana
func (c *Client) DefaultFleetServerURL() (string, error) {
path := fmt.Sprintf("%s/fleet_server_hosts", FleetAPI)

statusCode, respBody, err := c.get(path)
if err != nil {
return "", fmt.Errorf("could not reach fleet server hosts endpoint: %w", err)
}

if statusCode != http.StatusOK {
return "", fmt.Errorf("could not get status data; API status code = %d; response body = %s", statusCode, respBody)
}

var hosts struct {
Items []struct {
IsDefault bool `json:"is_default"`
HostURLs []string `json:"host_urls"`
} `json:"items"`
}
err = json.Unmarshal(respBody, &hosts)
if err != nil {
return "", fmt.Errorf("failed to decode response: %w", err)
}

for _, server := range hosts.Items {
if server.IsDefault && len(server.HostURLs) > 0 {
return server.HostURLs[0], nil
}
}

return "", errors.New("could not find the fleet server URL for this project")
}
31 changes: 24 additions & 7 deletions internal/kibana/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,46 @@ func (v VersionInfo) IsSnapshot() bool {

type statusType struct {
Version VersionInfo `json:"version"`
Status struct {
Overall struct {
Level string `json:"level"`
} `json:"overall"`
} `json:"status"`
}

// Version method returns the version of Kibana (Elastic stack)
func (c *Client) Version() (VersionInfo, error) {
return c.versionInfo, nil
}

func (c *Client) requestVersion() (VersionInfo, error) {
var version VersionInfo
func (c *Client) requestStatus() (statusType, error) {
var status statusType
statusCode, respBody, err := c.get(StatusAPI)
if err != nil {
return version, fmt.Errorf("could not reach status endpoint: %w", err)
return status, fmt.Errorf("could not reach status endpoint: %w", err)
}

if statusCode != http.StatusOK {
return version, fmt.Errorf("could not get status data; API status code = %d; response body = %s", statusCode, respBody)
return status, fmt.Errorf("could not get status data; API status code = %d; response body = %s", statusCode, respBody)
}

var status statusType
err = json.Unmarshal(respBody, &status)
if err != nil {
return version, fmt.Errorf("unmarshalling response failed (body: \n%s): %w", respBody, err)
return status, fmt.Errorf("unmarshalling response failed (body: \n%s): %w", respBody, err)
}

return status, nil
}

// CheckHealth checks the Kibana health
func (c *Client) CheckHealth() error {
status, err := c.requestStatus()
if err != nil {
return fmt.Errorf("could not reach status endpoint: %w", err)
}

return status.Version, nil
if status.Status.Overall.Level != "available" {
return fmt.Errorf("kibana in unhealthy state: %s", status.Status.Overall.Level)
}
return nil
}
10 changes: 10 additions & 0 deletions internal/profile/_static/config.yml.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
# Directory containing GeoIP databases for stacks managed by elastic-agent.
# stack.geoip_dir: "/path/to/geoip_dir/"
## Elastic Cloud
# Host URL
# stack.elastic_cloud.host: https://cloud.elastic.co

## Serverless stack provider
# Project type
# stack.serverless.type: observability
# Region where the Serverless project is going to be created
# stack.serverless.region: aws-us-east-1

Loading

0 comments on commit 9d80c6c

Please sign in to comment.