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

[RAC][Rule Registry] Fix bug where namespaces with dashes could cause conflicts #107991

Merged
merged 4 commits into from
Aug 17, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -241,59 +241,72 @@ export class ResourceInstaller {

logger.debug(`Creating write target for ${primaryNamespacedAlias}`);

const { body: indicesExist } = await clusterClient.indices.exists({
index: primaryNamespacedPattern,
allow_no_indices: false,
});

if (!indicesExist) {
await this.installNamespacedIndexTemplate(indexInfo, namespace);

try {
await clusterClient.indices.create({
index: initialIndexName,
body: {
aliases: {
[primaryNamespacedAlias]: {
is_write_index: true,
},
},
},
});
} catch (err) {
// If the index already exists and it's the write index for the alias,
// something else created it so suppress the error. If it's not the write
// index, that's bad, throw an error.
if (err?.meta?.body?.error?.type === 'resource_already_exists_exception') {
const { body: existingIndices } = await clusterClient.indices.get({
index: initialIndexName,
});
if (
!existingIndices[initialIndexName]?.aliases?.[primaryNamespacedAlias]?.is_write_index
) {
throw Error(
`Attempted to create index: ${initialIndexName} as the write index for alias: ${primaryNamespacedAlias}, but the index already exists and is not the write index for the alias`
);
}
} else {
throw err;
}
}
} else {
// If we find indices matching the pattern, then we expect one of them to be the write index for the alias.
// Throw an error if none of them are the write index.
const { body: aliasesResponse } = await clusterClient.indices.getAlias({
try {
// When a new namespace is created we expect getAlias to return a 404 error,
// we'll catch it below and continue on. A non-404 error is a real problem so we throw.

// It's critical that we specify *both* the index pattern and alias in this request. The alias prevents the
// request from finding other namespaces that could match the -* part of the index pattern
// (see https://github.com/elastic/kibana/issues/107704). The index pattern prevents the request from
// finding legacy .siem-signals indices that we add the alias to for backwards compatibility reasons. Together,
// the index pattern and alias should ensure that we retrieve only the "new" backing indices for this
// particular alias.
const { body: aliases } = await clusterClient.indices.getAlias({
Comment on lines +244 to +254
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are awesome comments in the code 👍 👍

index: primaryNamespacedPattern,
name: primaryNamespacedAlias,
});

// If we find backing indices for the alias here, we shouldn't be making a new concrete index -
// either one of the indices is the write index so we return early because we don't need a new write target,
// or none of them are the write index so we'll throw an error because one of the existing indices should have
// been the write target
if (
!Object.entries(aliasesResponse).some(
([_, aliasesObject]) => aliasesObject.aliases[primaryNamespacedAlias]?.is_write_index
Object.values(aliases).some(
(aliasesObject) => aliasesObject.aliases[primaryNamespacedAlias].is_write_index
)
) {
throw Error(
return;
} else {
throw new Error(
`Indices matching pattern ${primaryNamespacedPattern} exist but none are set as the write index for alias ${primaryNamespacedAlias}`
);
}
} catch (err) {
// 404 is expected if the alerts-as-data index hasn't been created yet
if (err.statusCode !== 404) {
throw err;
}
}

await this.installNamespacedIndexTemplate(indexInfo, namespace);

try {
await clusterClient.indices.create({
index: initialIndexName,
body: {
aliases: {
[primaryNamespacedAlias]: {
is_write_index: true,
},
},
},
});
} catch (err) {
// If the index already exists and it's the write index for the alias,
// something else created it so suppress the error. If it's not the write
// index, that's bad, throw an error.
if (err?.meta?.body?.error?.type === 'resource_already_exists_exception') {
const { body: existingIndices } = await clusterClient.indices.get({
index: initialIndexName,
});
if (!existingIndices[initialIndexName]?.aliases?.[primaryNamespacedAlias]?.is_write_index) {
throw Error(
`Attempted to create index: ${initialIndexName} as the write index for alias: ${primaryNamespacedAlias}, but the index already exists and is not the write index for the alias`
);
}
} else {
throw err;
}
}
}

Expand Down