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

Bug 1923939: add missing trigger types and update the optional fields - 4.6 #8015

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -9,6 +9,7 @@ export interface EventListenerDetailsProps {
}

const EventListenerDetails: React.FC<EventListenerDetailsProps> = ({ obj: eventListener }) => {
const triggers = eventListener.spec.triggers?.filter((trigger) => trigger.template?.name) || [];
return (
<div className="co-m-pane__body">
<SectionHeading text="Event Listener Details" />
Expand All @@ -21,10 +22,12 @@ const EventListenerDetails: React.FC<EventListenerDetailsProps> = ({ obj: eventL
eventListener={eventListener}
namespace={eventListener.metadata.namespace}
/>
<EventListenerTriggers
namespace={eventListener.metadata.namespace}
triggers={eventListener.spec.triggers}
/>
{triggers.length > 0 && (
<EventListenerTriggers
namespace={eventListener.metadata.namespace}
triggers={triggers}
/>
)}
</div>
</div>
</div>
Expand Down
Expand Up @@ -16,11 +16,15 @@ interface EventListenerTriggersProps {
}

const EventListenerTriggers: React.FC<EventListenerTriggersProps> = ({ namespace, triggers }) => {
const triggerTemplates = triggers.filter((tr) => tr.template?.name);
if (triggerTemplates.length === 0) {
return null;
}
return (
<dl>
<dt>Triggers</dt>
<dd>
{triggers.map((trigger) => {
{triggerTemplates.map((trigger) => {
const triggerTemplateKind = referenceForModel(TriggerTemplateModel);
const triggerTemplateName = trigger.template.name;
const bindings: ResourceModelLink[] = getEventListenerTriggerBindingNames(
Expand Down
@@ -0,0 +1,29 @@
import * as React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import EventListenerDetails from '../EventListenerDetails';
import { EventlistenerTestData, EventlistenerTypes } from '../../../../test/event-listener-data';
import EventListenerTriggers from '../EventListenerTriggers';

type EventListenerDetailsProps = React.ComponentProps<typeof EventListenerDetails>;

describe('EventListener Details', () => {
let wrapper: ShallowWrapper<EventListenerDetailsProps>;

beforeEach(() => {
wrapper = shallow(
<EventListenerDetails
obj={EventlistenerTestData[EventlistenerTypes.BINDINGS_TEMPLATE_NAME]}
/>,
);
});

it('should not render EventListenerTriggers section if the trigger contains binding ref', () => {
wrapper.setProps({ obj: EventlistenerTestData[EventlistenerTypes.BINDINGS_TEMPLATE_REF] });
expect(wrapper.find(EventListenerTriggers).exists()).toBe(false);
});

it('should not render EventListenerTriggers section if triggers contains triggerRef', () => {
wrapper.setProps({ obj: EventlistenerTestData[EventlistenerTypes.TRIGGER_REF] });
expect(wrapper.find(EventListenerTriggers).exists()).toBe(false);
});
});
@@ -1,4 +1,4 @@
import { K8sResourceCommon } from '@console/internal/module/k8s';
import { K8sResourceCommon, K8sResourceKind, Toleration } from '@console/internal/module/k8s';
import { PipelineRun } from '../../../utils/pipeline-augment';

export type TriggerBindingParam = {
Expand Down Expand Up @@ -28,29 +28,79 @@ export type TriggerTemplateKind = K8sResourceCommon & {

export type EventListenerKindBindingReference = {
// TriggerBinding / ClusterTriggerBinding reference
kind: string;
// Kind can only be provided if Ref is also provided. Defaults to TriggerBinding
kind?: string;
// Ref is used since Tekton Triggers 0.5 (part of OpenShift Pipeline Operator 1.1)
ref: string;
// Mutually exclusive with Name
ref?: string;
// We also support older operators, so need to show & save the old field as well.
// https://github.com/tektoncd/triggers/pull/603/files
// https://github.com/tektoncd/triggers/releases/tag/v0.5.0 and
// https://github.com/tektoncd/triggers/releases/tag/v0.6.0
/** @deprecated use ref instead */
// name of the binding param
name?: string;
// value for the binding param
value?: string;
};
export type WebhookHeader = {
name: string;
value: string | string[];
};

export type VCSInterceptor = {
secretRef: {
secretKey: string;
secretName: string;
};
eventTypes: string[];
};
export type TriggerInterceptor = {
gitlab: VCSInterceptor;
github: VCSInterceptor;
bitbucket: VCSInterceptor;
webhook: {
header: WebhookHeader[];
objectRef: K8sResourceKind;
};
cel: {
filter?: string;
overlays: {
key: string;
expression: string;
}[];
};
};
export type EventListenerKindTrigger = {
bindings: EventListenerKindBindingReference[];
template: {
name?: string;
bindings?: EventListenerKindBindingReference[];
interceptors?: TriggerInterceptor;
template?: {
// Ref is used since Tekton Triggers 0.10.x (part of OpenShift Pipeline Operator 1.3)
ref?: string;
// We also support older operators, so need to show & save the old field as well.
// TriggerTemplateKind name reference
name: string;
// https://github.com/tektoncd/triggers/pull/898/files
// name will be deprecated in TP1.4
name?: string;
};
triggerRef?: string;
};

export type EventListenerKind = K8sResourceCommon & {
spec: {
serviceAccountName: string;
triggers: EventListenerKindTrigger[];
// optional fields
replicas?: number;
serviceType?: string;
namespaceSelector?: {
matchNames: string[];
};
podTemplate?: {
nodeSelector: { [key: string]: string };
tolerations: Toleration[];
};
};
status?: {
configuration: {
Expand Down
Expand Up @@ -28,7 +28,7 @@ type TriggerTemplateMapping = { [key: string]: TriggerTemplateKind };

const getResourceName = (resource: K8sResourceCommon): string => resource.metadata.name;
const getEventListenerTemplateNames = (el: EventListenerKind): string[] =>
el.spec.triggers.map((elTrigger: EventListenerKindTrigger) => elTrigger.template.name);
el.spec.triggers?.map((elTrigger: EventListenerKindTrigger) => elTrigger.template.name);
const getEventListenerGeneratedName = (eventListener: EventListenerKind) =>
eventListener.status?.configuration.generatedName;

Expand Down Expand Up @@ -186,7 +186,7 @@ export const useTriggerTemplateEventListenerNames = (triggerTemplate: TriggerTem
return eventListenerResources
.filter((eventListener: EventListenerKind) =>
eventListener.spec.triggers.find(
({ template: { name } }) => name === getResourceName(triggerTemplate),
(trigger) => trigger.template?.name === getResourceName(triggerTemplate),
),
)
.map(getResourceName);
Expand All @@ -196,8 +196,8 @@ export const useTriggerBindingEventListenerNames = (triggerBinding: TriggerBindi
const eventListenerResources = useAllEventListeners(triggerBinding.metadata.namespace) || [];
return eventListenerResources
.filter((eventListener: EventListenerKind) =>
eventListener.spec.triggers.find(({ bindings }) =>
bindings.find(
eventListener.spec.triggers?.find(({ bindings }) =>
bindings?.find(
({ kind, name }) =>
getResourceName(triggerBinding) === name &&
getResourceModelFromBindingKind(kind).kind === triggerBinding.kind,
Expand Down
88 changes: 88 additions & 0 deletions frontend/packages/dev-console/src/test/event-listener-data.ts
@@ -0,0 +1,88 @@
import {
EventListenerKind,
EventListenerKindTrigger,
} from '../components/pipelines/resource-types/triggers';

export enum TriggerTypes {
BINDING_TEMPLATE_NAME = 'bindings-and-template-name',
BINDING_TEMPLATE_REF = 'bindings-and-template-ref',
TRIGGER_REF = 'trigger-ref',
}

export enum EventlistenerTypes {
BINDINGS_TEMPLATE_REF = 'el-with-bindings-template-ref',
BINDINGS_TEMPLATE_NAME = 'el-with-bindings-template-name',
TRIGGER_REF = 'el-with-triggerRef',
}

type TriggerTestData = { [key in TriggerTypes]?: EventListenerKindTrigger };
type EventListenerTestData = { [key in EventlistenerTypes]?: EventListenerKind };
export const TriggerTestData = {
[TriggerTypes.BINDING_TEMPLATE_REF]: {
name: 'foo-trig',
bindings: [
{
ref: 'pipeline-binding',
},
{
ref: 'message-binding',
},
],
template: {
ref: 'pipeline-template',
},
},
[TriggerTypes.BINDING_TEMPLATE_NAME]: {
name: 'foo-trig',
bindings: [
{
ref: 'pipeline-binding',
},
{
ref: 'message-binding',
},
],
template: {
name: 'pipeline-template',
},
},
[TriggerTypes.TRIGGER_REF]: {
triggerRef: 'vote-trigger',
},
};
export const EventlistenerTestData: EventListenerTestData = {
[EventlistenerTypes.BINDINGS_TEMPLATE_REF]: {
apiVersion: 'triggers.tekton.dev/v1alpha1',
kind: 'EventListener',
metadata: {
name: 'listener',
},
spec: {
serviceAccountName: 'trigger-sa',
triggers: [TriggerTestData[TriggerTypes.BINDING_TEMPLATE_REF]],
},
},
[EventlistenerTypes.BINDINGS_TEMPLATE_NAME]: {
apiVersion: 'triggers.tekton.dev/v1alpha1',
kind: 'EventListener',
metadata: {
name: 'listener',
},
spec: {
serviceAccountName: 'trigger-sa',
triggers: [TriggerTestData[TriggerTypes.BINDING_TEMPLATE_NAME]],
},
},

[EventlistenerTypes.TRIGGER_REF]: {
apiVersion: 'triggers.tekton.dev/v1alpha1',
kind: 'EventListener',
metadata: {
name: 'vote-app',
},
spec: {
serviceAccountName: 'trigger-sa',
triggers: [TriggerTestData[TriggerTypes.TRIGGER_REF]],
},
},
};