Skip to content
Open
Show file tree
Hide file tree
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
75 changes: 75 additions & 0 deletions shell/assets/translations/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ generic:
externalIps: External IPs
internalIps: Internal IPs
opensInNewTab: Opens in a new tab
autogeneratedCreated:
title: "{resource} created"
message: "{id} has been created."

tabs:
addItem: Add a new tab item
Expand Down Expand Up @@ -3599,6 +3602,73 @@ import:
other {# Resources}
}

auditPolicy:
description: Define rules for what events should be logged.
enabled: Enabled
disabled: Disabled
active: Active
inactive: Inactive
action:
enable: Enable
disable: Disable
reasons:
PolicyNotYetActivated: Not yet activated
PolicyIsActive: Active
PolicyIsInvalid: Invalid
PolicyWasDisabled: Disabled
general:
title: General
enabled:
label: Enabled
title: Enabled
checkbox: Enables the audit log
verbosity:
label: Log Verbosity
title: Log Verbosity
level:
0: 0 - Log request and response metadata
1: 1 - Log request and response headers
2: 2 - Log request body
3: 3 - Log response body
title: Log Levels
label: Level
tooltip: Each log level is cumulative and each subsequent level logs the previous level data. Each log transaction for a request/response pair uses the same auditID value.
request:
title: Request
requestHeaders: Request Headers
requestBody: Request Body
response:
title: Response
responseHeaders: Response Headers
responseBody: Response Body
filters:
add: Add Filter
title: Filters
action:
title: Action
label: Action
allow: Allow
deny: Deny
placeholder: Allow/Deny
requestURI:
title: Request URI
label: Request URI
placeholder: e.g. /foo/.*
additionalRedactions:
title: Additional Redactions
headers:
title: Headers
label: Headers
placeholder: e.g. Cache.*
add: Add Header
paths:
title: Paths
label: Paths
placeholder: e.g. $.gitCommit
add: Add Path
error:
enableOrDisable: "{flag, select, enable {Error when enabling - {id}} disable {Error when disabling - {id}} other {Error - {id}}}"

ingress:
description: Ingresses route incoming traffic from the internet to Services within the cluster based on the hostname and path specified in the request. You can expose multiple Services on the same external IP address and port.
certificates:
Expand Down Expand Up @@ -7965,6 +8035,11 @@ typeLabel:
one { Resource Quota }
other { Resource Quotas }
}
auditlog.cattle.io.auditpolicy: |-
{count, plural,
one { Audit Log Policy }
other { Audit Log Policies }
}
# pruh-mee-thee-eyes https://www.prometheus.io/docs/introduction/faq/#what-is-the-plural-of-prometheus
monitoring.coreos.com.prometheus: |-
{count, plural,
Expand Down
5 changes: 4 additions & 1 deletion shell/config/product/explorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
CONFIG_MAP,
EVENT,
NODE, SECRET, INGRESS,
WORKLOAD, WORKLOAD_TYPES, SERVICE, HPA, NETWORK_POLICY, PV, PVC, STORAGE_CLASS, POD, POD_DISRUPTION_BUDGET, LIMIT_RANGE, RESOURCE_QUOTA,
WORKLOAD, WORKLOAD_TYPES, SERVICE, HPA, NETWORK_POLICY, PV, PVC, STORAGE_CLASS, POD, POD_DISRUPTION_BUDGET, LIMIT_RANGE, RESOURCE_QUOTA, AUDIT_POLICY,
MANAGEMENT,
NAMESPACE,
NORMAN,
Expand Down Expand Up @@ -83,6 +83,7 @@ export function init(store) {
NETWORK_POLICY,
POD_DISRUPTION_BUDGET,
RESOURCE_QUOTA,
AUDIT_POLICY,
], 'policy');

basicType([
Expand Down Expand Up @@ -118,6 +119,7 @@ export function init(store) {
weightGroup('storage', 95, true);
weightGroup('policy', 94, true);
weightType(POD, -1, true);
weightType(AUDIT_POLICY, -1, true);

// here is where we define the usage of the WORKLOAD custom list view for
// all the workload types (ex: deployments, cron jobs, daemonsets, etc)
Expand Down Expand Up @@ -152,6 +154,7 @@ export function init(store) {
mapGroup('autoscaling', 'Autoscaling');
mapGroup('policy', 'Policy');
mapGroup('networking.k8s.io', 'Networking');
mapGroup('auditlog.cattle.io', 'Policy');
mapGroup(/^(.+\.)?api(server)?.*\.k8s\.io$/, 'API');
mapGroup('rbac.authorization.k8s.io', 'RBAC');
mapGroup('admissionregistration.k8s.io', 'admission');
Expand Down
1 change: 1 addition & 0 deletions shell/config/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const POD_DISRUPTION_BUDGET = 'policy.poddisruptionbudget';
export const PV = 'persistentvolume';
export const PVC = 'persistentvolumeclaim';
export const RESOURCE_QUOTA = 'resourcequota';
export const AUDIT_POLICY = 'auditlog.cattle.io.auditpolicy';
export const SCHEMA = 'schema';
export const SERVICE = 'service';
export const SECRET = 'secret';
Expand Down
106 changes: 106 additions & 0 deletions shell/edit/auditlog.cattle.io.auditpolicy/AdditionalRedactions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import Tab from '@shell/components/Tabbed/Tab.vue';
import Tabbed from '@shell/components/Tabbed/index.vue';
import ArrayList from '@shell/components/form/ArrayList.vue';
import { AuditPolicy } from '@shell/edit/auditlog.cattle.io.auditpolicy/types';

// Component Props & Emits
const props = defineProps({
value: {
type: Object,
default: () => ({})
},
mode: {
type: String,
default: 'create'
},
});

const emit = defineEmits<{
'update:value': [value: AuditPolicy];
}>();

// Default Values & Reactive Spec
const defaults: AuditPolicy = { additionalRedactions: [] };
const spec = ref<AuditPolicy>({ ...defaults, ...props.value });

// Methods
function addRedaction() {
const valueToEmit = { ...props.value, ...spec.value };

valueToEmit.additionalRedactions?.push({
headers: [],
paths: [],
});
emit('update:value', valueToEmit);
}

function removeRedaction(tab: number) {
const valueToEmit = { ...props.value, ...spec.value };

valueToEmit.additionalRedactions?.splice(tab, 1);
emit('update:value', valueToEmit);
}

const redactionLabel = computed(() => {
return (i: number) => `Rule ${ i + 1 }`;
});
</script>

<template>
<div>
<div class="row mb-40">
<div class="col span-12">
<Tabbed
:side-tabs="true"
:show-tabs-add-remove="mode !== 'view'"
:use-hash="true"
@addTab="addRedaction"
@removeTab="removeRedaction"
>
<Tab
v-for="(redaction, idx) in spec.additionalRedactions"
:key="idx"
:name="`rule-${idx}`"
:label="redactionLabel(idx)"
:show-header="false"
class="container-group"
>
<fieldset>
<h2>{{ t("auditPolicy.additionalRedactions.headers.title") }}</h2>
<div class="row">
<div class="col span-12">
<ArrayList
key="headers"
v-model:value="redaction.headers"
:value-placeholder="t('auditPolicy.additionalRedactions.headers.placeholder')"
:add-label="t('auditPolicy.additionalRedactions.headers.add')"
:mode="mode"
:protip="false"
/>
</div>
</div>
</fieldset>
<div class="spacer" />
<fieldset>
<h2>{{ t("auditPolicy.additionalRedactions.paths.title") }}</h2>
<div class="row">
<div class="col span-12">
<ArrayList
key="paths"
v-model:value="redaction.paths"
:value-placeholder="t('auditPolicy.additionalRedactions.paths.placeholder')"
:add-label="t('auditPolicy.additionalRedactions.paths.add')"
:mode="mode"
:protip="false"
/>
</div>
</div>
</fieldset>
</Tab>
</Tabbed>
</div>
</div>
</div>
</template>
134 changes: 134 additions & 0 deletions shell/edit/auditlog.cattle.io.auditpolicy/Filters.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<script setup lang="ts">
import { ref } from 'vue';
import LabeledInput from '@components/Form/LabeledInput/LabeledInput.vue';
import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
import ArrayList from '@shell/components/form/ArrayList.vue';
import { AuditPolicy, FilterRule } from '@shell/edit/auditlog.cattle.io.auditpolicy/types';

// Component Props & Emits
const props = defineProps({
value: {
type: Object,
default: () => ({})
},
mode: {
type: String,
default: 'create'
},
});

const emit = defineEmits<{
'update:value': [value: AuditPolicy];
}>();

// Default Values & Reactive Spec
const defaults: AuditPolicy = { filters: [] };
const spec = ref<AuditPolicy>({ ...defaults, ...props.value });
const defaultAddValue: FilterRule = {
action: 'allow',
requestURI: '',
};

// Methods
function addRow(key: 'action' | 'requestURI', filters: FilterRule[]) {
const valueToEmit = { ...props.value, ...spec.value };

valueToEmit.filters = filters;

emit('update:value', valueToEmit);
}

function updateRow(key: 'action' | 'requestURI', index: number, value: string) {
const valueToEmit = { ...props.value, ...spec.value };

if (!valueToEmit.filters) {
valueToEmit.filters = [];
}

// Ensure the filter exists at the given index
if (!valueToEmit.filters[index]) {
valueToEmit.filters[index] = { action: '', requestURI: '' };
}

valueToEmit.filters[index][key] = value;
emit('update:value', valueToEmit);
}
</script>

<template>
<div>
<div class="row mb-40">
<div class="col span-12">
<ArrayList
key="headers"
v-model:value="spec.filters"
:value-placeholder="t('auditPolicy.filters.placeholder')"
:add-label="t('auditPolicy.filters.add')"
:mode="mode"
:protip="false"
:defaultAddValue="defaultAddValue"
:show-header="true"
@update:value="addRow('action', $event)"
>
<template v-slot:column-headers>
<div class="responders-heading mb-10">
<div
class="row"
>
<div class="col span-6">
<span class="text-label">{{ t('auditPolicy.filters.action.title') }}</span>
</div>
<div class="col span-6 send-to">
<span class="text-label">{{ t('auditPolicy.filters.requestURI.title') }}</span>
</div>
</div>
</div>
</template>
<template v-slot:columns="scope">
<div class="row">
<div class="col span-6">
<LabeledSelect
v-model:value="scope.row.value.action"
:options="[{ value: 'allow', label: t('auditPolicy.filters.action.allow')},{ value: 'deny', label: t('auditPolicy.filters.action.deny') }]"
:mode="mode"
:placeholder="t('auditPolicy.filters.action.placeholder')"
@update:value="updateRow('action', scope.i, $event)"
/>
</div>
<div class="col span-6">
<LabeledInput
v-model:value="scope.row.value.requestURI"
:mode="mode"
:placeholder="t('auditPolicy.filters.requestURI.placeholder')"
@update:value="updateRow('requestURI', scope.i, $event, )"
/>
</div>
</div>
</template>
</ArrayList>
</div>
</div>
</div>
</template>

<style lang="scss" scoped>
.responders-heading {
display: grid;
grid-template-columns: auto $array-list-remove-margin;
}

.responder {
&, .target-container {
width: 100%;
}

.target-container :deep() .unlabeled-select {
min-width: 35%;
height: 100%;
}

.target {
height: 100%;
}
}
</style>
Loading
Loading