Commit 42e1042c authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '321258-remove-frontend-portion' into 'master'

Remove frontend for security orchestration feature flag

See merge request gitlab-org/gitlab!71515
parents c26f6221 26e042ca
...@@ -2,10 +2,8 @@ ...@@ -2,10 +2,8 @@
import { GlIcon, GlLink, GlPopover, GlTabs, GlTab } from '@gitlab/ui'; import { GlIcon, GlLink, GlPopover, GlTabs, GlTab } from '@gitlab/ui';
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import Alerts from './alerts/alerts.vue'; import Alerts from './alerts/alerts.vue';
import NoEnvironmentEmptyState from './no_environment_empty_state.vue'; import NoEnvironmentEmptyState from './no_environment_empty_state.vue';
import PolicyList from './policy_list.vue';
import ThreatMonitoringFilters from './threat_monitoring_filters.vue'; import ThreatMonitoringFilters from './threat_monitoring_filters.vue';
import ThreatMonitoringSection from './threat_monitoring_section.vue'; import ThreatMonitoringSection from './threat_monitoring_section.vue';
...@@ -20,10 +18,8 @@ export default { ...@@ -20,10 +18,8 @@ export default {
Alerts, Alerts,
ThreatMonitoringFilters, ThreatMonitoringFilters,
ThreatMonitoringSection, ThreatMonitoringSection,
PolicyList,
NoEnvironmentEmptyState, NoEnvironmentEmptyState,
}, },
mixins: [glFeatureFlagMixin()],
inject: ['documentationPath'], inject: ['documentationPath'],
props: { props: {
defaultEnvironmentId: { defaultEnvironmentId: {
...@@ -48,11 +44,6 @@ export default { ...@@ -48,11 +44,6 @@ export default {
isSetUpMaybe: this.isValidEnvironmentId(this.defaultEnvironmentId), isSetUpMaybe: this.isValidEnvironmentId(this.defaultEnvironmentId),
}; };
}, },
computed: {
shouldShowPolicies() {
return !this.glFeatures.securityOrchestrationPoliciesConfiguration;
},
},
created() { created() {
if (this.isSetUpMaybe) { if (this.isSetUpMaybe) {
this.setCurrentEnvironmentId(this.defaultEnvironmentId); this.setCurrentEnvironmentId(this.defaultEnvironmentId);
...@@ -101,19 +92,6 @@ export default { ...@@ -101,19 +92,6 @@ export default {
> >
<alerts /> <alerts />
</gl-tab> </gl-tab>
<gl-tab
v-if="shouldShowPolicies"
ref="policyTab"
:title="s__('ThreatMonitoring|Policies')"
data-qa-selector="policies_tab"
>
<no-environment-empty-state v-if="!isSetUpMaybe" />
<policy-list
v-else
:documentation-path="documentationPath"
:new-policy-path="newPolicyPath"
/>
</gl-tab>
<gl-tab <gl-tab
:title="s__('ThreatMonitoring|Statistics')" :title="s__('ThreatMonitoring|Statistics')"
data-testid="threat-monitoring-statistics-tab" data-testid="threat-monitoring-statistics-tab"
...@@ -123,7 +101,7 @@ export default { ...@@ -123,7 +101,7 @@ export default {
<threat-monitoring-filters /> <threat-monitoring-filters />
<threat-monitoring-section <threat-monitoring-section
ref="policySection" data-testid="threat-monitoring-statistics-section"
store-namespace="threatMonitoringNetworkPolicy" store-namespace="threatMonitoringNetworkPolicy"
:title="s__('ThreatMonitoring|Container Network Policy')" :title="s__('ThreatMonitoring|Container Network Policy')"
:subtitle="s__('ThreatMonitoring|Packet Activity')" :subtitle="s__('ThreatMonitoring|Packet Activity')"
......
<script> <script>
import { GlAlert, GlFormGroup, GlFormSelect } from '@gitlab/ui'; import { GlAlert, GlFormGroup, GlFormSelect } from '@gitlab/ui';
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { POLICY_TYPE_COMPONENT_OPTIONS } from '../constants'; import { POLICY_TYPE_COMPONENT_OPTIONS } from '../constants';
import EnvironmentPicker from '../environment_picker.vue'; import EnvironmentPicker from '../environment_picker.vue';
import NetworkPolicyEditor from './network_policy/network_policy_editor.vue'; import NetworkPolicyEditor from './network_policy/network_policy_editor.vue';
...@@ -16,7 +15,6 @@ export default { ...@@ -16,7 +15,6 @@ export default {
NetworkPolicyEditor, NetworkPolicyEditor,
ScanExecutionPolicyEditor, ScanExecutionPolicyEditor,
}, },
mixins: [glFeatureFlagMixin()],
inject: ['policyType'], inject: ['policyType'],
props: { props: {
assignedPolicyProject: { assignedPolicyProject: {
...@@ -58,7 +56,7 @@ export default { ...@@ -58,7 +56,7 @@ export default {
); );
}, },
shouldAllowPolicyTypeSelection() { shouldAllowPolicyTypeSelection() {
return !this.existingPolicy && this.glFeatures.securityOrchestrationPoliciesConfiguration; return !this.existingPolicy;
}, },
}, },
created() { created() {
......
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ThreatMonitoringApp component given there is a default environment with data renders the network policy section 1`] = ` exports[`ThreatMonitoringApp component given there is a default environment with data renders the statistics section 1`] = `
<threat-monitoring-section-stub <threat-monitoring-section-stub
anomaloustitle="Dropped Packets" anomaloustitle="Dropped Packets"
chartemptystatesvgpath="/network-policy-no-data-svg" chartemptystatesvgpath="/network-policy-no-data-svg"
chartemptystatetext="Container Network Policies are not installed or have been disabled. To view this data, ensure your Network Policies are installed and enabled for your cluster." chartemptystatetext="Container Network Policies are not installed or have been disabled. To view this data, ensure your Network Policies are installed and enabled for your cluster."
chartemptystatetitle="Container NetworkPolicies not detected" chartemptystatetitle="Container NetworkPolicies not detected"
data-testid="threat-monitoring-statistics-section"
documentationanchor="container-network-policy" documentationanchor="container-network-policy"
documentationpath="/docs" documentationpath="/docs"
nominaltitle="Total Packets" nominaltitle="Total Packets"
...@@ -15,16 +16,3 @@ exports[`ThreatMonitoringApp component given there is a default environment with ...@@ -15,16 +16,3 @@ exports[`ThreatMonitoringApp component given there is a default environment with
ylegend="Operations Per Second" ylegend="Operations Per Second"
/> />
`; `;
exports[`ThreatMonitoringApp component given there is a default environment with data renders the network policy tab 1`] = `
<gl-tab-stub
data-qa-selector="policies_tab"
title="Policies"
titlelinkclass=""
>
<policy-list-stub
documentationpath="/docs"
newpolicypath="/policy/new"
/>
</gl-tab-stub>
`;
...@@ -2,7 +2,6 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -2,7 +2,6 @@ import { shallowMount } from '@vue/test-utils';
import ThreatMonitoringAlerts from 'ee/threat_monitoring/components/alerts/alerts.vue'; import ThreatMonitoringAlerts from 'ee/threat_monitoring/components/alerts/alerts.vue';
import ThreatMonitoringApp from 'ee/threat_monitoring/components/app.vue'; import ThreatMonitoringApp from 'ee/threat_monitoring/components/app.vue';
import NoEnvironmentEmptyState from 'ee/threat_monitoring/components/no_environment_empty_state.vue'; import NoEnvironmentEmptyState from 'ee/threat_monitoring/components/no_environment_empty_state.vue';
import PolicyList from 'ee/threat_monitoring/components/policy_list.vue';
import ThreatMonitoringFilters from 'ee/threat_monitoring/components/threat_monitoring_filters.vue'; import ThreatMonitoringFilters from 'ee/threat_monitoring/components/threat_monitoring_filters.vue';
import createStore from 'ee/threat_monitoring/store'; import createStore from 'ee/threat_monitoring/store';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
...@@ -49,12 +48,10 @@ describe('ThreatMonitoringApp component', () => { ...@@ -49,12 +48,10 @@ describe('ThreatMonitoringApp component', () => {
); );
}; };
const findAlertsView = () => wrapper.find(ThreatMonitoringAlerts); const findAlertsView = () => wrapper.findComponent(ThreatMonitoringAlerts);
const findPolicyList = () => wrapper.find(PolicyList); const findFilters = () => wrapper.findComponent(ThreatMonitoringFilters);
const findFilters = () => wrapper.find(ThreatMonitoringFilters); const findStatisticsSection = () => wrapper.findByTestId('threat-monitoring-statistics-section');
const findPolicySection = () => wrapper.find({ ref: 'policySection' }); const findNoEnvironmentEmptyState = () => wrapper.findComponent(NoEnvironmentEmptyState);
const findNoEnvironmentEmptyStates = () => wrapper.findAll(NoEnvironmentEmptyState);
const findPolicyTab = () => wrapper.find({ ref: 'policyTab' });
const findAlertTab = () => wrapper.findByTestId('threat-monitoring-alerts-tab'); const findAlertTab = () => wrapper.findByTestId('threat-monitoring-alerts-tab');
const findStatisticsTab = () => wrapper.findByTestId('threat-monitoring-statistics-tab'); const findStatisticsTab = () => wrapper.findByTestId('threat-monitoring-statistics-tab');
...@@ -80,20 +77,16 @@ describe('ThreatMonitoringApp component', () => { ...@@ -80,20 +77,16 @@ describe('ThreatMonitoringApp component', () => {
}); });
it('shows the "no environment" empty state', () => { it('shows the "no environment" empty state', () => {
expect(findNoEnvironmentEmptyStates().length).toBe(2); expect(findNoEnvironmentEmptyState().exists()).toBe(true);
}); });
it('shows the tabs', () => { it('shows the tabs', () => {
expect(findPolicyTab().exists()).toBe(true); expect(findAlertTab().exists()).toBe(true);
expect(findStatisticsTab().exists()).toBe(true); expect(findStatisticsTab().exists()).toBe(true);
}); });
it('does not show the network policy list', () => {
expect(findPolicyList().exists()).toBe(false);
});
it('does not show the threat monitoring section', () => { it('does not show the threat monitoring section', () => {
expect(findPolicySection().exists()).toBe(false); expect(findStatisticsSection().exists()).toBe(false);
}); });
}, },
); );
...@@ -114,12 +107,8 @@ describe('ThreatMonitoringApp component', () => { ...@@ -114,12 +107,8 @@ describe('ThreatMonitoringApp component', () => {
expect(findFilters().exists()).toBe(true); expect(findFilters().exists()).toBe(true);
}); });
it('renders the network policy section', () => { it('renders the statistics section', () => {
expect(findPolicySection().element).toMatchSnapshot(); expect(findStatisticsSection().element).toMatchSnapshot();
});
it('renders the network policy tab', () => {
expect(findPolicyTab().element).toMatchSnapshot();
}); });
}); });
...@@ -134,14 +123,4 @@ describe('ThreatMonitoringApp component', () => { ...@@ -134,14 +123,4 @@ describe('ThreatMonitoringApp component', () => {
expect(findAlertsView().exists()).toBe(true); expect(findAlertsView().exists()).toBe(true);
}); });
}); });
describe('with "securityOrchestrationPoliciesConfiguration" feature flag enabled', () => {
beforeEach(() => {
factory({ provide: { glFeatures: { securityOrchestrationPoliciesConfiguration: true } } });
});
it('does not render the Policies tab', () => {
expect(findPolicyTab().exists()).toBe(false);
});
});
}); });
...@@ -57,11 +57,10 @@ describe('PolicyEditor component', () => { ...@@ -57,11 +57,10 @@ describe('PolicyEditor component', () => {
expect(findNeworkPolicyEditor().props('existingPolicy')).toBe(null); expect(findNeworkPolicyEditor().props('existingPolicy')).toBe(null);
}); });
it('renders the disabled form select', () => { it('renders the form select', () => {
const formSelect = findFormSelect(); const formSelect = findFormSelect();
expect(formSelect.exists()).toBe(true);
expect(formSelect.attributes('value')).toBe(POLICY_TYPE_COMPONENT_OPTIONS.container.value); expect(formSelect.attributes('value')).toBe(POLICY_TYPE_COMPONENT_OPTIONS.container.value);
expect(formSelect.attributes('disabled')).toBe('true'); expect(formSelect.attributes('disabled')).toBe(undefined);
}); });
it('shows an alert when "error" is emitted from the component', async () => { it('shows an alert when "error" is emitted from the component', async () => {
...@@ -111,16 +110,4 @@ describe('PolicyEditor component', () => { ...@@ -111,16 +110,4 @@ describe('PolicyEditor component', () => {
}, },
); );
}); });
describe('with "securityOrchestrationPoliciesConfiguration" feature flag enabled', () => {
beforeEach(() => {
factory({ provide: { glFeatures: { securityOrchestrationPoliciesConfiguration: true } } });
});
it('renders the form select', () => {
const formSelect = findFormSelect();
expect(formSelect.exists()).toBe(true);
expect(formSelect.attributes('disabled')).toBe(undefined);
});
});
}); });
import { GlTable, GlDrawer } from '@gitlab/ui';
import { createLocalVue } from '@vue/test-utils';
import { merge } from 'lodash';
import VueApollo from 'vue-apollo';
import { POLICY_TYPE_OPTIONS } from 'ee/threat_monitoring/components/constants';
import PolicyDrawer from 'ee/threat_monitoring/components/policy_drawer/policy_drawer.vue';
import PolicyList from 'ee/threat_monitoring/components/policy_list.vue';
import networkPoliciesQuery from 'ee/threat_monitoring/graphql/queries/network_policies.query.graphql';
import scanExecutionPoliciesQuery from 'ee/threat_monitoring/graphql/queries/scan_execution_policies.query.graphql';
import createStore from 'ee/threat_monitoring/store';
import createMockApollo from 'helpers/mock_apollo_helper';
import { stubComponent } from 'helpers/stub_component';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { networkPolicies, scanExecutionPolicies } from '../mocks/mock_apollo';
import { mockNetworkPoliciesResponse, mockScanExecutionPoliciesResponse } from '../mocks/mock_data';
const localVue = createLocalVue();
localVue.use(VueApollo);
const fullPath = 'project/path';
const environments = [
{
id: 2,
global_id: 'gid://gitlab/Environment/2',
},
];
const defaultRequestHandlers = {
networkPolicies: networkPolicies(mockNetworkPoliciesResponse),
scanExecutionPolicies: scanExecutionPolicies(mockScanExecutionPoliciesResponse),
};
const pendingHandler = jest.fn(() => new Promise(() => {}));
describe('PolicyList component', () => {
let store;
let wrapper;
let requestHandlers;
const factory = (mountFn = mountExtended) => (options = {}) => {
store = createStore();
const { state, handlers, ...wrapperOptions } = options;
Object.assign(store.state.networkPolicies, {
...state,
});
store.state.threatMonitoring.environments = environments;
requestHandlers = {
...defaultRequestHandlers,
...handlers,
};
jest.spyOn(store, 'dispatch').mockImplementation(() => Promise.resolve());
wrapper = mountFn(
PolicyList,
merge(
{
propsData: {
documentationPath: 'documentation_path',
newPolicyPath: '/policies/new',
},
store,
provide: {
projectPath: fullPath,
},
apolloProvider: createMockApollo([
[networkPoliciesQuery, requestHandlers.networkPolicies],
[scanExecutionPoliciesQuery, requestHandlers.scanExecutionPolicies],
]),
stubs: {
PolicyDrawer: stubComponent(PolicyDrawer, {
props: {
...PolicyDrawer.props,
...GlDrawer.props,
},
}),
},
localVue,
},
wrapperOptions,
),
);
};
const mountShallowWrapper = factory(shallowMountExtended);
const mountWrapper = factory();
const findPolicyTypeFilter = () => wrapper.findByTestId('policy-type-filter');
const findEnvironmentsPicker = () => wrapper.find({ ref: 'environmentsPicker' });
const findPoliciesTable = () => wrapper.findComponent(GlTable);
const findPolicyStatusCells = () => wrapper.findAllByTestId('policy-status-cell');
const findPolicyDrawer = () => wrapper.findByTestId('policyDrawer');
const findAutodevopsAlert = () => wrapper.findByTestId('autodevopsAlert');
afterEach(() => {
wrapper.destroy();
});
describe('initial state', () => {
beforeEach(() => {
mountShallowWrapper({
handlers: {
networkPolicies: pendingHandler,
},
});
});
it('renders EnvironmentPicker', () => {
expect(findEnvironmentsPicker().exists()).toBe(true);
});
it('renders the new policy button', () => {
const button = wrapper.findByTestId('new-policy');
expect(button.exists()).toBe(true);
});
it('renders closed editor drawer', () => {
const editorDrawer = findPolicyDrawer();
expect(editorDrawer.exists()).toBe(true);
expect(editorDrawer.props('open')).toBe(false);
});
it('does not render autodevops alert', () => {
expect(findAutodevopsAlert().exists()).toBe(false);
});
it('fetches policies', () => {
expect(requestHandlers.networkPolicies).toHaveBeenCalledWith({
fullPath,
});
expect(requestHandlers.scanExecutionPolicies).toHaveBeenCalledWith({
fullPath,
});
});
it("sets table's loading state", () => {
expect(findPoliciesTable().attributes('busy')).toBe('true');
});
});
describe('given policies have been fetched', () => {
let rows;
beforeEach(async () => {
mountWrapper();
await waitForPromises();
rows = wrapper.findAll('tr');
});
it('fetches network policies on environment change', async () => {
store.dispatch.mockReset();
await store.commit('threatMonitoring/SET_CURRENT_ENVIRONMENT_ID', 2);
expect(requestHandlers.networkPolicies).toHaveBeenCalledTimes(2);
expect(requestHandlers.networkPolicies.mock.calls[1][0]).toEqual({
fullPath: 'project/path',
environmentId: environments[0].global_id,
});
});
it('if network policies are filtered out, changing the environment does not trigger a fetch', async () => {
store.dispatch.mockReset();
expect(requestHandlers.networkPolicies).toHaveBeenCalledTimes(1);
findPolicyTypeFilter().vm.$emit(
'input',
POLICY_TYPE_OPTIONS.POLICY_TYPE_SCAN_EXECUTION.value,
);
await store.commit('threatMonitoring/SET_CURRENT_ENVIRONMENT_ID', 2);
expect(requestHandlers.networkPolicies).toHaveBeenCalledTimes(1);
});
describe.each`
rowIndex | expectedPolicyName | expectedPolicyType
${1} | ${mockScanExecutionPoliciesResponse[0].name} | ${'Scan execution'}
${3} | ${mockNetworkPoliciesResponse[0].name} | ${'Network'}
${4} | ${'drop-outbound'} | ${'Network'}
${5} | ${'allow-inbound-http'} | ${'Network'}
`('policy in row #$rowIndex', ({ rowIndex, expectedPolicyName, expectedPolicyType }) => {
let row;
beforeEach(() => {
row = rows.at(rowIndex);
});
it(`renders ${expectedPolicyName} in the name cell`, () => {
expect(row.findAll('td').at(1).text()).toBe(expectedPolicyName);
});
it(`renders ${expectedPolicyType} in the policy type cell`, () => {
expect(row.findAll('td').at(2).text()).toBe(expectedPolicyType);
});
});
it.each`
description | filterBy | hiddenTypes
${'network'} | ${POLICY_TYPE_OPTIONS.POLICY_TYPE_NETWORK} | ${[POLICY_TYPE_OPTIONS.POLICY_TYPE_SCAN_EXECUTION]}
${'scan execution'} | ${POLICY_TYPE_OPTIONS.POLICY_TYPE_SCAN_EXECUTION} | ${[POLICY_TYPE_OPTIONS.POLICY_TYPE_NETWORK]}
`('policies filtered by $description type', async ({ filterBy, hiddenTypes }) => {
findPolicyTypeFilter().vm.$emit('input', filterBy.value);
await wrapper.vm.$nextTick();
expect(findPoliciesTable().text()).toContain(filterBy.text);
hiddenTypes.forEach((hiddenType) => {
expect(findPoliciesTable().text()).not.toContain(hiddenType.text);
});
});
});
describe('status column', () => {
beforeEach(() => {
mountWrapper();
});
it('renders a checkmark icon for enabled policies', () => {
const icon = findPolicyStatusCells().at(1).find('svg');
expect(icon.exists()).toBe(true);
expect(icon.props('name')).toBe('check-circle-filled');
expect(icon.props('ariaLabel')).toBe('Enabled');
});
it('renders a "Disabled" label for screen readers for disabled policies', () => {
const span = findPolicyStatusCells().at(3).find('span');
expect(span.exists()).toBe(true);
expect(span.attributes('class')).toBe('gl-sr-only');
expect(span.text()).toBe('Disabled');
});
});
describe('with allEnvironments enabled', () => {
beforeEach(() => {
mountWrapper();
wrapper.vm.$store.state.threatMonitoring.allEnvironments = true;
});
it('renders environments column', () => {
const environmentsHeader = findPoliciesTable().findAll('[role="columnheader"]').at(2);
expect(environmentsHeader.text()).toContain('Environment(s)');
});
});
describe.each`
description | policy
${'network'} | ${mockNetworkPoliciesResponse[0]}
${'scan execution'} | ${mockScanExecutionPoliciesResponse[0]}
`('given there is a $description policy selected', ({ policy }) => {
beforeEach(() => {
mountShallowWrapper();
findPoliciesTable().vm.$emit('row-selected', [policy]);
});
it('renders opened editor drawer', () => {
const editorDrawer = findPolicyDrawer();
expect(editorDrawer.exists()).toBe(true);
expect(editorDrawer.props('open')).toBe(true);
expect(editorDrawer.props('policy')).toBe(policy);
});
});
describe('given an autodevops policy', () => {
beforeEach(() => {
const autoDevOpsPolicy = {
...mockNetworkPoliciesResponse[0],
name: 'auto-devops',
fromAutoDevops: true,
};
mountShallowWrapper({
handlers: {
networkPolicies: networkPolicies([autoDevOpsPolicy]),
},
});
});
it('renders autodevops alert', () => {
expect(findAutodevopsAlert().exists()).toBe(true);
});
});
});
...@@ -22499,9 +22499,6 @@ msgstr "" ...@@ -22499,9 +22499,6 @@ msgstr ""
msgid "NetworkPolicies|IP/subnet" msgid "NetworkPolicies|IP/subnet"
msgstr "" msgstr ""
msgid "NetworkPolicies|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
msgstr ""
msgid "NetworkPolicies|Invalid or empty policy" msgid "NetworkPolicies|Invalid or empty policy"
msgstr "" msgstr ""
...@@ -22526,18 +22523,12 @@ msgstr "" ...@@ -22526,18 +22523,12 @@ msgstr ""
msgid "NetworkPolicies|New policy" msgid "NetworkPolicies|New policy"
msgstr "" msgstr ""
msgid "NetworkPolicies|No policies detected"
msgstr ""
msgid "NetworkPolicies|None selected" msgid "NetworkPolicies|None selected"
msgstr "" msgstr ""
msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts." msgid "NetworkPolicies|Please %{installLinkStart}install%{installLinkEnd} and %{configureLinkStart}configure a Kubernetes Agent for this project%{configureLinkEnd} to enable alerts."
msgstr "" msgstr ""
msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
msgstr ""
msgid "NetworkPolicies|Policy %{policyName} was successfully changed" msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
msgstr "" msgstr ""
...@@ -35078,9 +35069,6 @@ msgstr "" ...@@ -35078,9 +35069,6 @@ msgstr ""
msgid "ThreatMonitoring|Packet Activity" msgid "ThreatMonitoring|Packet Activity"
msgstr "" msgstr ""
msgid "ThreatMonitoring|Policies"
msgstr ""
msgid "ThreatMonitoring|Requests" msgid "ThreatMonitoring|Requests"
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment