Skip to content

Commit 1dcbe0a

Browse files
committed
Draft for serverless
1 parent d19bfff commit 1dcbe0a

File tree

4 files changed

+526
-2
lines changed

4 files changed

+526
-2
lines changed

internal/stack/providers.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ import (
1212
)
1313

1414
const (
15-
ProviderCompose = "compose"
15+
ProviderCompose = "compose"
16+
ProviderServerless = "serverless"
1617
)
1718

1819
var (
1920
DefaultProvider = ProviderCompose
2021
SupportedProviders = []string{
2122
ProviderCompose,
23+
ProviderServerless,
2224
}
2325
)
2426

@@ -50,8 +52,10 @@ type Provider interface {
5052
// BuildProvider returns the provider for the given name.
5153
func BuildProvider(name string, profile *profile.Profile) (Provider, error) {
5254
switch name {
53-
case "compose":
55+
case ProviderCompose:
5456
return &composeProvider{}, nil
57+
case ProviderServerless:
58+
return newServerlessProvider(profile)
5559
}
5660
return nil, fmt.Errorf("unknown provider %q, supported providers: %s", name, strings.Join(SupportedProviders, ", "))
5761
}

internal/stack/serverless.go

+244
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
package stack
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
7+
"github.com/elastic/elastic-package/internal/logger"
8+
"github.com/elastic/elastic-package/internal/profile"
9+
"github.com/elastic/elastic-package/internal/stack/serverless"
10+
)
11+
12+
const (
13+
paramServerlessProjectID = "serverless_project_id"
14+
paramServerlessProjectType = "serverless_project_type"
15+
16+
configRegion = "stack.serverless.region"
17+
configProjectType = "stack.serverless.type"
18+
19+
defaultRegion = "aws-eu-west-1"
20+
defaultProjectType = "observability"
21+
)
22+
23+
var (
24+
errProjectNotExist = errors.New("project does not exist")
25+
)
26+
27+
type serverlessProvider struct {
28+
profile *profile.Profile
29+
client *serverless.Client
30+
}
31+
32+
type projectSettings struct {
33+
Name string
34+
Region string
35+
Type string
36+
37+
StackVersion string
38+
}
39+
40+
func (sp *serverlessProvider) createProject(settings projectSettings, options Options) (Config, error) {
41+
project, err := sp.client.CreateProject(settings.Name, settings.Region, settings.Type)
42+
if err != nil {
43+
return Config{}, fmt.Errorf("failed to create %s project %s in %s: %w", settings.Type, settings.Name, settings.Region, err)
44+
}
45+
46+
var config Config
47+
config.Provider = ProviderServerless
48+
config.Parameters = map[string]string{
49+
paramServerlessProjectID: project.ID,
50+
paramServerlessProjectType: project.Type,
51+
}
52+
53+
config.ElasticsearchHost = project.Endpoints.Elasticsearch
54+
config.KibanaHost = project.Endpoints.Kibana
55+
56+
printUserConfig(options.Printer, config)
57+
58+
err = storeConfig(sp.profile, config)
59+
if err != nil {
60+
return Config{}, fmt.Errorf("failed to store config: %w", err)
61+
}
62+
63+
return config, nil
64+
}
65+
66+
func (sp *serverlessProvider) deleteProject(project *serverless.Project, options Options) error {
67+
return sp.client.DeleteProject(project)
68+
}
69+
70+
func (sp *serverlessProvider) currentProject(config Config) (*serverless.Project, error) {
71+
projectID, found := config.Parameters[paramServerlessProjectID]
72+
if !found {
73+
return nil, errProjectNotExist
74+
}
75+
76+
projectType, found := config.Parameters[paramServerlessProjectType]
77+
if !found {
78+
return nil, errProjectNotExist
79+
}
80+
81+
project, err := sp.client.GetProject(projectType, projectID)
82+
if err == serverless.ErrProjectNotExist {
83+
return nil, errProjectNotExist
84+
}
85+
if err != nil {
86+
return nil, fmt.Errorf("couldn't check project health: %w", err)
87+
}
88+
89+
return project, nil
90+
}
91+
92+
func getProjectSettings(options Options) (projectSettings, error) {
93+
s := projectSettings{
94+
Name: createProjectName(options),
95+
Type: options.Profile.Config(configProjectType, defaultProjectType),
96+
Region: options.Profile.Config(configRegion, defaultRegion),
97+
StackVersion: options.StackVersion,
98+
}
99+
100+
return s, nil
101+
}
102+
103+
func createProjectName(options Options) string {
104+
return fmt.Sprintf("elastic-package-test-%s", options.Profile.ProfileName)
105+
}
106+
107+
func newServerlessProvider(profile *profile.Profile) (*serverlessProvider, error) {
108+
client, err := serverless.NewClient()
109+
if err != nil {
110+
return nil, fmt.Errorf("can't create serverless provider: %w", err)
111+
}
112+
113+
return &serverlessProvider{profile, client}, nil
114+
}
115+
116+
func (sp *serverlessProvider) BootUp(options Options) error {
117+
logger.Warn("Elastic Serverless provider is in technical preview")
118+
119+
config, err := LoadConfig(sp.profile)
120+
if err != nil {
121+
return fmt.Errorf("failed to load configuration: %w", err)
122+
}
123+
124+
settings, err := getProjectSettings(options)
125+
if err != nil {
126+
return err
127+
}
128+
129+
var project *serverless.Project
130+
131+
project, err = sp.currentProject(config)
132+
switch err {
133+
default:
134+
return err
135+
case errProjectNotExist:
136+
logger.Infof("Creating project %q", settings.Name)
137+
config, err = sp.createProject(settings, options)
138+
if err != nil {
139+
return fmt.Errorf("failed to create deployment: %w", err)
140+
}
141+
142+
// logger.Infof("Creating agent policy")
143+
// err = sp.createAgentPolicy(config, options.StackVersion)
144+
// if err != nil {
145+
// return fmt.Errorf("failed to create agent policy: %w", err)
146+
// }
147+
148+
// logger.Infof("Replacing GeoIP databases")
149+
// err = cp.replaceGeoIPDatabases(config, options, settings.TemplateID, settings.Region, payload.Resources.Elasticsearch[0].Plan.ClusterTopology)
150+
// if err != nil {
151+
// return fmt.Errorf("failed to replace GeoIP databases: %w", err)
152+
// }
153+
case nil:
154+
logger.Debugf("Project existed: %s", project.Name)
155+
printUserConfig(options.Printer, config)
156+
logger.Infof("Updating project %s", project.Name)
157+
// err = sp.updateDeployment(project, settings)
158+
// if err != nil {
159+
// return fmt.Errorf("failed to update deployment: %w", err)
160+
// }
161+
}
162+
163+
// logger.Infof("Starting local agent")
164+
// err = sp.startLocalAgent(options, config)
165+
// if err != nil {
166+
// return fmt.Errorf("failed to start local agent: %w", err)
167+
// }
168+
169+
return nil
170+
}
171+
172+
// func (sp *serverlessProvider) startLocalAgent(options Options, config Config) error {
173+
// err := applyCloudResources(sp.profile, options.StackVersion, config)
174+
// if err != nil {
175+
// return fmt.Errorf("could not initialize compose files for local agent: %w", err)
176+
// }
177+
//
178+
// project, err := sp.localAgentComposeProject()
179+
// if err != nil {
180+
// return fmt.Errorf("could not initialize local agent compose project")
181+
// }
182+
//
183+
// err = project.Build(compose.CommandOptions{})
184+
// if err != nil {
185+
// return fmt.Errorf("failed to build images for local agent: %w", err)
186+
// }
187+
//
188+
// err = project.Up(compose.CommandOptions{ExtraArgs: []string{"-d"}})
189+
// if err != nil {
190+
// return fmt.Errorf("failed to start local agent: %w", err)
191+
// }
192+
//
193+
// return nil
194+
// }
195+
196+
func (sp *serverlessProvider) TearDown(options Options) error {
197+
config, err := LoadConfig(sp.profile)
198+
if err != nil {
199+
return fmt.Errorf("failed to load configuration: %w", err)
200+
}
201+
202+
// err = cp.destroyLocalAgent()
203+
// if err != nil {
204+
// return fmt.Errorf("failed to destroy local agent: %w", err)
205+
// }
206+
207+
project, err := sp.currentProject(config)
208+
if err != nil {
209+
return fmt.Errorf("failed to find current project: %w", err)
210+
}
211+
212+
logger.Debugf("Deleting project %q", project.ID)
213+
214+
err = sp.deleteProject(project, options)
215+
if err != nil {
216+
return fmt.Errorf("failed to delete project: %w", err)
217+
}
218+
219+
// logger.Debugf("Deleting GeoIP bundle.")
220+
// err = cp.deleteGeoIPExtension()
221+
// if err != nil {
222+
// return fmt.Errorf("failed to delete GeoIP extension: %w", err)
223+
// }
224+
225+
err = storeConfig(sp.profile, Config{})
226+
if err != nil {
227+
return fmt.Errorf("failed to store config: %w", err)
228+
}
229+
230+
return nil
231+
}
232+
233+
func (sp *serverlessProvider) Update(options Options) error {
234+
return fmt.Errorf("not implemented")
235+
}
236+
237+
func (sp *serverlessProvider) Dump(options DumpOptions) (string, error) {
238+
return "", fmt.Errorf("not implemented")
239+
}
240+
241+
func (sp *serverlessProvider) Status(options Options) ([]ServiceStatus, error) {
242+
logger.Warn("Elastic Serverless provider is in technical preview")
243+
return Status(options)
244+
}

0 commit comments

Comments
 (0)