Skip to content

Commit c79fae6

Browse files
ericywlendorama
andauthored
functionaltests: Add support for interacting with v7 fleet (#16519)
* Add support for interacting with v7 fleet * Update functionaltests/utils_test.go Co-authored-by: Edoardo Tenani <[email protected]> --------- Co-authored-by: Edoardo Tenani <[email protected]>
1 parent ef75a94 commit c79fae6

File tree

7 files changed

+50
-53
lines changed

7 files changed

+50
-53
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ jobs:
5757
- run: go test -v -race ./...
5858
- env:
5959
KIBANA_URL: "https://kibana.test"
60-
KIBANA_API_KEY: "dummy"
60+
KIBANA_USERNAME: "dummy"
61+
KIBANA_PASSWORD: "dummy"
6162
EC_URL: "https://elastic-cloud.test"
6263
EC_API_KEY: "dummy"
6364
EC_REGION: "gcp-us-west2"

functionaltests/internal/gen/generator.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func (g *Generator) RunBlockingWait(ctx context.Context, version ecclient.StackV
135135
}
136136

137137
// With standalone, we don't have Fleet, so simply just wait for some arbitrary time.
138-
time.Sleep(30 * time.Second)
138+
time.Sleep(60 * time.Second)
139139
return nil
140140
}
141141

@@ -158,17 +158,14 @@ func flushAPMMetrics(ctx context.Context, kbc *kbclient.Client, version string)
158158
// Sending an update with modifying the description is enough to trigger
159159
// final aggregations in APM Server and flush of in-flight metrics.
160160
policy.Description = fmt.Sprintf("Functional tests %s", version)
161-
if err = kbc.UpdatePackagePolicyByID(ctx, policyID, kbclient.UpdatePackagePolicyRequest{
162-
PackagePolicy: policy,
163-
Force: false,
164-
}); err != nil {
161+
if err = kbc.UpdatePackagePolicyByID(ctx, policyID, policy); err != nil {
165162
return fmt.Errorf("cannot update elastic-cloud-apm package policy: %w", err)
166163
}
167164

168165
// APM Server needs some time to flush all metrics, and we don't have any
169166
// visibility on when this completes.
170167
// NOTE: This value comes from empirical observations.
171-
time.Sleep(20 * time.Second)
168+
time.Sleep(40 * time.Second)
172169
return nil
173170
}
174171

functionaltests/internal/kbclient/client.go

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,13 @@ import (
3030
"time"
3131
)
3232

33-
func New(kibanaURL, apiKey string, username, password string) (*Client, error) {
33+
func New(kibanaURL, username, password string) (*Client, error) {
3434
if kibanaURL == "" {
3535
return nil, fmt.Errorf("kbclient.New kibanaURL must not be empty")
3636
}
37-
if apiKey == "" {
38-
return nil, fmt.Errorf("kbclient.New apiKey must not be empty")
39-
}
4037

4138
return &Client{
4239
url: kibanaURL,
43-
apiKey: apiKey,
4440
superUsername: username,
4541
superPassword: password,
4642
SupportedAPIVersion: "2023-10-31",
@@ -52,9 +48,8 @@ type Client struct {
5248
http.Client
5349
// url is the Kibana URL where requests will be directed to.
5450
url string
55-
// apiKey should be an Elasticsearch API key with appropriate privileges.
56-
apiKey string
5751

52+
// Fleet API access require superuser role before 8.1.0.
5853
// superUsername should be an Elasticsearch superuser username.
5954
superUsername string
6055
// superPassword should be an Elasticsearch superuser password.
@@ -64,7 +59,7 @@ type Client struct {
6459
}
6560

6661
// prepareRequest creates a http.Request with required headers for interacting with Kibana.
67-
func (c *Client) prepareRequest(method, path string, body any, super bool) (*http.Request, error) {
62+
func (c *Client) prepareRequest(method, path string, body any) (*http.Request, error) {
6863
b, err := json.Marshal(body)
6964
if err != nil {
7065
return nil, fmt.Errorf("cannot marshal body: %w", err)
@@ -79,13 +74,10 @@ func (c *Client) prepareRequest(method, path string, body any, super bool) (*htt
7974
req.Header.Add("kbn-xsrf", "true")
8075
req.Header.Add("Content-Type", "application/json")
8176
req.Header.Add("Elastic-Api-Version", c.SupportedAPIVersion)
82-
if super {
83-
userPass := fmt.Sprintf("%s:%s", c.superUsername, c.superPassword)
84-
basicAuth := base64.StdEncoding.EncodeToString([]byte(userPass))
85-
req.Header.Add("Authorization", fmt.Sprintf("Basic %s", basicAuth))
86-
} else {
87-
req.Header.Add("Authorization", fmt.Sprintf("ApiKey %s", c.apiKey))
88-
}
77+
78+
userPass := fmt.Sprintf("%s:%s", c.superUsername, c.superPassword)
79+
basicAuth := base64.StdEncoding.EncodeToString([]byte(userPass))
80+
req.Header.Add("Authorization", fmt.Sprintf("Basic %s", basicAuth))
8981

9082
return req, nil
9183
}
@@ -98,11 +90,10 @@ func (c *Client) sendRequest(
9890
method string,
9991
path string,
10092
body any,
101-
super bool,
10293
handleRespError func(statusCode int, body []byte) error,
10394
) ([]byte, error) {
10495
methodPath := fmt.Sprintf("%s %s", method, path)
105-
req, err := c.prepareRequest(method, path, body, super)
96+
req, err := c.prepareRequest(method, path, body)
10697
if err != nil {
10798
return nil, fmt.Errorf("cannot prepare request (%s): %w", methodPath, err)
10899
}
@@ -144,18 +135,33 @@ func (e ElasticAgentPolicyNotFoundError) Error() string {
144135
}
145136

146137
type PackagePolicy struct {
147-
Name string `json:"name"`
148-
Description string `json:"description"`
149-
Package PackagePolicyPkg `json:"package"`
150-
PolicyID string `json:"policy_id"`
151-
PolicyIDs []string `json:"policy_ids"`
138+
Name string `json:"name"`
139+
Description string `json:"description"`
140+
Package PackagePolicyPkg `json:"package"`
141+
Namespace string `json:"namespace"`
142+
Inputs []PackagePolicyInput `json:"inputs"`
143+
OutputID string `json:"output_id"`
144+
PolicyID string `json:"policy_id,omitempty"`
145+
PolicyIDs []string `json:"policy_ids,omitempty"`
146+
Enabled bool `json:"enabled"`
152147
}
153148

154149
type PackagePolicyPkg struct {
155150
Name string `json:"name"`
151+
Title string `json:"title"`
156152
Version string `json:"version"`
157153
}
158154

155+
type PackagePolicyInput struct {
156+
Config any `json:"config"`
157+
Enabled bool `json:"enabled"`
158+
Streams []any `json:"streams"`
159+
Type string `json:"type"`
160+
Vars map[string]any `json:"vars"`
161+
KeepEnabled bool `json:"keep_enabled"`
162+
PolicyTemplate string `json:"policy_template"`
163+
}
164+
159165
type getPackagePolicyResponse struct {
160166
Item PackagePolicy `json:"item"`
161167
}
@@ -174,7 +180,7 @@ func (c *Client) GetPackagePolicyByID(ctx context.Context, policyID string) (Pac
174180
return nil
175181
}
176182

177-
b, err := c.sendRequest(ctx, http.MethodGet, path, nil, false, handleRespError)
183+
b, err := c.sendRequest(ctx, http.MethodGet, path, nil, handleRespError)
178184
if err != nil {
179185
return PackagePolicy{}, err
180186
}
@@ -187,19 +193,14 @@ func (c *Client) GetPackagePolicyByID(ctx context.Context, policyID string) (Pac
187193
return policyResp.Item, nil
188194
}
189195

190-
type UpdatePackagePolicyRequest struct {
191-
PackagePolicy
192-
Force bool `json:"force"`
193-
}
194-
195196
// UpdatePackagePolicyByID performs a Package Policy update in Fleet through the Fleet Kibana APIs.
196197
// https://www.elastic.co/docs/api/doc/kibana/v8/operation/operation-update-package-policy
197-
func (c *Client) UpdatePackagePolicyByID(ctx context.Context, policyID string, request UpdatePackagePolicyRequest) error {
198+
func (c *Client) UpdatePackagePolicyByID(ctx context.Context, policyID string, policy PackagePolicy) error {
198199
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
199200
defer cancel()
200201

201202
path := fmt.Sprintf("/api/fleet/package_policies/%s", policyID)
202-
_, err := c.sendRequest(ctx, http.MethodPut, path, request, false, nil)
203+
_, err := c.sendRequest(ctx, http.MethodPut, path, policy, nil)
203204
return err
204205
}
205206

@@ -218,7 +219,7 @@ func (c *Client) EnableIntegrationsServer(ctx context.Context) error {
218219
// This is an internal API that is not publicly documented.
219220
// https://github.com/elastic/kibana/blob/12aa3fc/x-pack/solutions/observability/plugins/apm/server/routes/fleet/route.ts#L146
220221
path := "/internal/apm/fleet/cloud_apm_package_policy"
221-
b, err := c.sendRequest(ctx, http.MethodPost, path, nil, true, nil)
222+
b, err := c.sendRequest(ctx, http.MethodPost, path, nil, nil)
222223
if err != nil {
223224
return err
224225
}

functionaltests/internal/kbclient/client_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ func getHttpClient(t *testing.T) (*recorder.Recorder, *http.Client) {
110110

111111
func TestClient_GetPackagePolicyByID(t *testing.T) {
112112
kibanaURL := os.Getenv("KIBANA_URL")
113-
apikey := os.Getenv("KIBANA_API_KEY")
114-
kbc, err := kbclient.New(kibanaURL, apikey, "", "")
113+
username := os.Getenv("KIBANA_USERNAME")
114+
password := os.Getenv("KIBANA_PASSWORD")
115+
kbc, err := kbclient.New(kibanaURL, username, password)
115116
require.NoError(t, err)
116117
_, httpc := getHttpClient(t)
117118
kbc.Client = *httpc
@@ -123,25 +124,25 @@ func TestClient_GetPackagePolicyByID(t *testing.T) {
123124

124125
func TestClient_UpdatePackagePolicyByID(t *testing.T) {
125126
kibanaURL := os.Getenv("KIBANA_URL")
126-
apiKey := os.Getenv("KIBANA_API_KEY")
127-
kbc, err := kbclient.New(kibanaURL, apiKey, "", "")
127+
username := os.Getenv("KIBANA_USERNAME")
128+
password := os.Getenv("KIBANA_PASSWORD")
129+
kbc, err := kbclient.New(kibanaURL, username, password)
128130
require.NoError(t, err)
129131
_, httpc := getHttpClient(t)
130132
kbc.Client = *httpc
131133

132134
ctx := context.Background()
133135
policyID := "elastic-cloud-apm"
134-
err = kbc.UpdatePackagePolicyByID(ctx, policyID, kbclient.UpdatePackagePolicyRequest{
135-
PackagePolicy: kbclient.PackagePolicy{
136+
err = kbc.UpdatePackagePolicyByID(ctx, policyID,
137+
kbclient.PackagePolicy{
136138
Name: "Elastic APM",
137139
Description: "Hello World",
138140
Package: kbclient.PackagePolicyPkg{
139141
Name: "apm",
140142
Version: "9.1.0-SNAPSHOT",
141143
},
142144
},
143-
Force: false,
144-
})
145+
)
145146
require.NoError(t, err)
146147

147148
policy, err := kbc.GetPackagePolicyByID(ctx, policyID)

functionaltests/single_upgrade_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func (tt singleUpgradeTestCase) Run(t *testing.T) {
8080
t.Logf("time elapsed: %s", time.Since(start))
8181

8282
esc := createESClient(t, deployInfo)
83-
kbc := createKibanaClient(t, ctx, esc, deployInfo)
83+
kbc := createKibanaClient(t, deployInfo)
8484
g := createAPMGenerator(t, ctx, esc, kbc, deployInfo)
8585

8686
atStartCount := getDocCountPerDS(t, ctx, esc)

functionaltests/steps_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func (c createStep) Step(t *testing.T, ctx context.Context, e *testStepEnv, _ te
129129
integrations := c.APMDeploymentMode.enableIntegrations()
130130
deployInfo := createCluster(t, ctx, e.tf, *target, c.DeployVersion, integrations)
131131
e.esc = createESClient(t, deployInfo)
132-
e.kbc = createKibanaClient(t, ctx, e.esc, deployInfo)
132+
e.kbc = createKibanaClient(t, deployInfo)
133133
e.gen = createAPMGenerator(t, ctx, e.esc, e.kbc, deployInfo)
134134
// Update the environment version to the new one.
135135
e.version = c.DeployVersion

functionaltests/utils_test.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,10 @@ func createESClient(t *testing.T, deployInfo deploymentInfo) *esclient.Client {
169169
}
170170

171171
// createKibanaClient instantiate an HTTP API client with dedicated methods to query the Kibana API.
172-
// This function will also create an Elasticsearch API key with full permissions to be used by the HTTP client.
173-
func createKibanaClient(t *testing.T, ctx context.Context, esc *esclient.Client, deployInfo deploymentInfo) *kbclient.Client {
172+
func createKibanaClient(t *testing.T, deployInfo deploymentInfo) *kbclient.Client {
174173
t.Helper()
175174
t.Log("create kibana client")
176-
apiKey, err := esc.CreateAPIKey(ctx, "kbclient", -1, map[string]types.RoleDescriptor{})
177-
require.NoError(t, err)
178-
kbc, err := kbclient.New(deployInfo.KibanaURL, apiKey, deployInfo.Username, deployInfo.Password)
175+
kbc, err := kbclient.New(deployInfo.KibanaURL, deployInfo.Username, deployInfo.Password)
179176
require.NoError(t, err)
180177
return kbc
181178
}

0 commit comments

Comments
 (0)