diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 467ac47dce..0000000000 --- a/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM golang:1.12-stretch - -RUN apt-get install -y ca-certificates - -RUN apt-get update \ - && apt-get upgrade -y \ - && apt-get install -y git - - -RUN curl -kLo /usr/local/bin/dep \ - https://github.com/golang/dep/releases/download/v0.5.4/dep-linux-amd64 \ - && chmod +x /usr/local/bin/dep - -COPY ../. . - -RUN ls -la - diff --git a/api/event-source.html b/api/event-source.html index bf30584654..911d86e168 100644 --- a/api/event-source.html +++ b/api/event-source.html @@ -1114,24 +1114,24 @@

GitlabEventSource -projectId
+projectID
string -

ProjectId is the id of project for which integration needs to setup

+

ProjectID is the id of project for which integration needs to setup

-event
+events
-string +[]string -

Event is a gitlab event to listen to. +

Events are gitlab event to listen to. Refer https://github.com/xanzy/go-gitlab/blob/bf34eca5d13a9f4c3f501d8a97b8ac226d55e4d9/projects.go#L794.

@@ -1173,18 +1173,6 @@

GitlabEventSource -namespace
- -string - - - -(Optional) -

Namespace refers to Kubernetes namespace which is used to retrieve access token from.

- - - - deleteHookOnFinish
bool @@ -1195,18 +1183,6 @@

GitlabEventSource

DeleteHookOnFinish determines whether to delete the GitLab hook for the project once the event source is stopped.

- - -allowDuplicate
- -bool - - - -

AllowDuplicate allows the gateway to register the same webhook integrations for multiple event source configurations. -Defaults to false.

- -

HDFSEventSource diff --git a/api/event-source.md b/api/event-source.md index e6177428bc..21c273441e 100644 --- a/api/event-source.md +++ b/api/event-source.md @@ -2193,7 +2193,7 @@ Webhook holds configuration to run a http server -projectId
string +projectID
string @@ -2201,7 +2201,7 @@ Webhook holds configuration to run a http server

-ProjectId is the id of project for which integration needs to setup +ProjectID is the id of project for which integration needs to setup

@@ -2213,7 +2213,7 @@ ProjectId is the id of project for which integration needs to setup -event
string +events
\[\]string @@ -2221,7 +2221,7 @@ ProjectId is the id of project for which integration needs to setup

-Event is a gitlab event to listen to. Refer +Events are gitlab event to listen to. Refer https://github.com/xanzy/go-gitlab/blob/bf34eca5d13a9f4c3f501d8a97b8ac226d55e4d9/projects.go\#L794.

@@ -2299,29 +2299,6 @@ GitlabBaseURL is the base URL for API requests to a custom endpoint -namespace
string - - - - - -(Optional) - -

- -Namespace refers to Kubernetes namespace which is used to retrieve -access token from. - -

- - - - - - - - - deleteHookOnFinish
bool @@ -2341,28 +2318,6 @@ project once the event source is stopped. - - - - -allowDuplicate
bool - - - - - -

- -AllowDuplicate allows the gateway to register the same webhook -integrations for multiple event source configurations. Defaults to -false. - -

- - - - - diff --git a/examples/event-sources/gitlab.yaml b/examples/event-sources/gitlab.yaml index 1b7c47d11c..fd8b3e4104 100644 --- a/examples/event-sources/gitlab.yaml +++ b/examples/event-sources/gitlab.yaml @@ -8,7 +8,7 @@ spec: gitlab: example: # id of the project - projectId: "1" + projectID: "1" # Github will send events to following port and endpoint webhook: # endpoint to listen to events on @@ -21,14 +21,11 @@ spec: # This url must be reachable from outside the cluster. # The gateway pod is backed by the service defined in the gateway spec. So get the URL for that service Github can reach to. url: http://url-that-is-reachable-from-GitLab - # event to listen to + # events to listen to # Visit https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#events - event: PushEvents - -# # Namespace where the api token secret live. -# # +Optional. Default to gateway's namespace. -# namespace: "argo-events" - + events: + - PushEvents + - TagPushEvents # accessToken refers to K8s secret that stores the gitlab api token accessToken: # Key within the K8s secret whose corresponding value (must be base64 encoded) is access token @@ -52,7 +49,8 @@ spec: # serverCertPath: "some path in pod" # # path to file that is mounted in gateway pod which contains private key # serverKeyPath: "some path in pod" -# event: "PushEvents" +# events: +# - PushEvents # accessToken: # key: accesskey # name: gitlab-access diff --git a/gateways/server/gitlab/start.go b/gateways/server/gitlab/start.go index f26bd2b0fa..56e7a00bbc 100644 --- a/gateways/server/gitlab/start.go +++ b/gateways/server/gitlab/start.go @@ -125,12 +125,11 @@ func (router *Router) PostActivate() error { logger := route.Logger.WithFields(map[string]interface{}{ common.LabelEventSource: route.EventSource.Name, - "event-type": gitlabEventSource.Event, - "project-id": gitlabEventSource.ProjectId, + "project-id": gitlabEventSource.ProjectID, }) logger.Infoln("retrieving the access token credentials...") - c, err := router.getCredentials(gitlabEventSource.AccessToken, gitlabEventSource.Namespace) + c, err := router.getCredentials(gitlabEventSource.AccessToken, router.namespace) if err != nil { return errors.Errorf("failed to get gitlab credentials. err: %+v", err) } @@ -143,51 +142,96 @@ func (router *Router) PostActivate() error { formattedUrl := common.FormattedURL(gitlabEventSource.Webhook.URL, gitlabEventSource.Webhook.Endpoint) - // Get existing webhooks and check if the integration for same url and event type is already available - if !gitlabEventSource.AllowDuplicate { - hooks, _, err := router.gitlabClient.Projects.ListProjectHooks(router.gitlabEventSource.ProjectId, &gitlab.ListProjectHooksOptions{}) - if err != nil { - return errors.Wrapf(err, "failed to list existing hooks to check for duplicates for project id %s", router.gitlabEventSource.ProjectId) - } + hooks, _, err := router.gitlabClient.Projects.ListProjectHooks(gitlabEventSource.ProjectID, &gitlab.ListProjectHooksOptions{}) + if err != nil { + return errors.Wrapf(err, "failed to list existing hooks to check for duplicates for project id %s", router.gitlabEventSource.ProjectID) + } + + var existingHook *gitlab.ProjectHook + isAlreadyExists := false - for _, hook := range hooks { - elem := reflect.ValueOf(hook).Elem().FieldByName(router.gitlabEventSource.Event) - if ok := elem.IsValid(); !ok { - return errors.Errorf("unknown event %s", router.gitlabEventSource.Event) - } - value := elem.Bool() - - if value && hook.URL == formattedUrl { - logger.Infoln("webhook already exists, won't register it...") - return nil - } + for _, hook := range hooks { + if hook.URL == formattedUrl { + existingHook = hook + isAlreadyExists = true } } - opt := &gitlab.AddProjectHookOptions{ - URL: &formattedUrl, - Token: &c.token, - EnableSSLVerification: &router.gitlabEventSource.EnableSSLVerification, + defaultEventValue := false + + editOpt := &gitlab.EditProjectHookOptions{ + URL: &formattedUrl, + ConfidentialNoteEvents: &defaultEventValue, + PushEvents: &defaultEventValue, + IssuesEvents: &defaultEventValue, + ConfidentialIssuesEvents: &defaultEventValue, + MergeRequestsEvents: &defaultEventValue, + TagPushEvents: &defaultEventValue, + NoteEvents: &defaultEventValue, + JobEvents: &defaultEventValue, + PipelineEvents: &defaultEventValue, + WikiPageEvents: &defaultEventValue, + EnableSSLVerification: &router.gitlabEventSource.EnableSSLVerification, + Token: &c.token, } - logger.Infoln("configuring the type of the GitLab event the hook must register against...") - elem := reflect.ValueOf(opt).Elem().FieldByName(router.gitlabEventSource.Event) - if ok := elem.IsValid(); !ok { - return errors.Errorf("unknown event %s", router.gitlabEventSource.Event) + addOpt := &gitlab.AddProjectHookOptions{ + URL: &formattedUrl, + Token: &c.token, + EnableSSLVerification: &router.gitlabEventSource.EnableSSLVerification, + ConfidentialNoteEvents: &defaultEventValue, + PushEvents: &defaultEventValue, + IssuesEvents: &defaultEventValue, + ConfidentialIssuesEvents: &defaultEventValue, + MergeRequestsEvents: &defaultEventValue, + TagPushEvents: &defaultEventValue, + NoteEvents: &defaultEventValue, + JobEvents: &defaultEventValue, + PipelineEvents: &defaultEventValue, + WikiPageEvents: &defaultEventValue, } - iev := reflect.New(elem.Type().Elem()) - reflect.Indirect(iev).SetBool(true) - elem.Set(iev) + var opt interface{} - logger.Infoln("creating project hook...") - hook, _, err := router.gitlabClient.Projects.AddProjectHook(router.gitlabEventSource.ProjectId, opt) - if err != nil { - return errors.Errorf("failed to add project hook. err: %+v", err) + opt = addOpt + if isAlreadyExists { + opt = editOpt + } + + logger.Infoln("configuring the GitLab events for the hook...") + + for _, event := range gitlabEventSource.Events { + elem := reflect.ValueOf(opt).Elem().FieldByName(event) + if ok := elem.IsValid(); !ok { + return errors.Errorf("unknown event %s", event) + } + + iev := reflect.New(elem.Type().Elem()) + reflect.Indirect(iev).SetBool(true) + elem.Set(iev) } - router.hook = hook - logger.WithField("hook-id", hook.ID).Info("hook created for the project") + var newHook *gitlab.ProjectHook + + if !isAlreadyExists { + logger.Infoln("creating project hook...") + newHook, _, err = router.gitlabClient.Projects.AddProjectHook(router.gitlabEventSource.ProjectID, opt.(*gitlab.AddProjectHookOptions)) + if err != nil { + return errors.Errorf("failed to add project hook. err: %+v", err) + } + } else { + logger.Infoln("project hook already exists, updating it...") + if existingHook == nil { + return errors.Errorf("existing hook contents are empty, unable to edit existing webhook") + } + newHook, _, err = router.gitlabClient.Projects.EditProjectHook(router.gitlabEventSource.ProjectID, existingHook.ID, opt.(*gitlab.EditProjectHookOptions)) + if err != nil { + return errors.Errorf("failed to add project hook. err: %+v", err) + } + } + + router.hook = newHook + logger.WithField("hook-id", newHook.ID).Info("hook registered for the project") return nil } @@ -199,12 +243,12 @@ func (router *Router) PostInactivate() error { if gitlabEventSource.DeleteHookOnFinish { logger := route.Logger.WithFields(map[string]interface{}{ common.LabelEventSource: route.EventSource.Name, - "project-id": gitlabEventSource.ProjectId, + "project-id": gitlabEventSource.ProjectID, "hook-id": router.hook.ID, }) logger.Infoln("deleting project hook...") - if _, err := router.gitlabClient.Projects.DeleteProjectHook(router.gitlabEventSource.ProjectId, router.hook.ID); err != nil { + if _, err := router.gitlabClient.Projects.DeleteProjectHook(router.gitlabEventSource.ProjectID, router.hook.ID); err != nil { return errors.Errorf("failed to delete hook. err: %+v", err) } @@ -227,15 +271,12 @@ func (listener *EventListener) StartEventSource(eventSource *gateways.EventSourc return err } - if gitlabEventSource.Namespace == "" { - gitlabEventSource.Namespace = listener.Namespace - } - route := webhook.NewRoute(gitlabEventSource.Webhook, listener.Logger, eventSource) return webhook.ManageRoute(&Router{ route: route, k8sClient: listener.K8sClient, gitlabEventSource: gitlabEventSource, + namespace: listener.Namespace, }, controller, eventStream) } diff --git a/gateways/server/gitlab/types.go b/gateways/server/gitlab/types.go index a0ae700d7e..44114e77b6 100644 --- a/gateways/server/gitlab/types.go +++ b/gateways/server/gitlab/types.go @@ -46,6 +46,7 @@ type Router struct { hook *gitlab.ProjectHook // gitlabEventSource is the event source that contains configuration necessary to consume events from GitLab gitlabEventSource *v1alpha1.GitlabEventSource + namespace string } // cred stores the api access token diff --git a/gateways/server/gitlab/validate.go b/gateways/server/gitlab/validate.go index 0e5bdc05c2..4407c0822c 100644 --- a/gateways/server/gitlab/validate.go +++ b/gateways/server/gitlab/validate.go @@ -60,11 +60,11 @@ func validate(eventSource *v1alpha1.GitlabEventSource) error { if eventSource == nil { return common.ErrNilEventSource } - if eventSource.ProjectId == "" { + if eventSource.ProjectID == "" { return fmt.Errorf("project id can't be empty") } - if eventSource.Event == "" { - return fmt.Errorf("event type can't be empty") + if eventSource.Events == nil { + return fmt.Errorf("events can't be empty") } if eventSource.GitlabBaseURL == "" { return fmt.Errorf("gitlab base url can't be empty") diff --git a/pkg/apis/eventsource/v1alpha1/openapi_generated.go b/pkg/apis/eventsource/v1alpha1/openapi_generated.go index c1a60032ee..9e4b483b75 100644 --- a/pkg/apis/eventsource/v1alpha1/openapi_generated.go +++ b/pkg/apis/eventsource/v1alpha1/openapi_generated.go @@ -964,18 +964,25 @@ func schema_pkg_apis_eventsource_v1alpha1_GitlabEventSource(ref common.Reference Ref: ref("github.com/argoproj/argo-events/gateways/server/common/webhook.Context"), }, }, - "projectId": { + "projectID": { SchemaProps: spec.SchemaProps{ - Description: "ProjectId is the id of project for which integration needs to setup", + Description: "ProjectID is the id of project for which integration needs to setup", Type: []string{"string"}, Format: "", }, }, - "event": { + "events": { SchemaProps: spec.SchemaProps{ - Description: "Event is a gitlab event to listen to. Refer https://github.com/xanzy/go-gitlab/blob/bf34eca5d13a9f4c3f501d8a97b8ac226d55e4d9/projects.go#L794.", - Type: []string{"string"}, - Format: "", + Description: "Events are gitlab event to listen to. Refer https://github.com/xanzy/go-gitlab/blob/bf34eca5d13a9f4c3f501d8a97b8ac226d55e4d9/projects.go#L794.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, }, }, "accessToken": { @@ -998,13 +1005,6 @@ func schema_pkg_apis_eventsource_v1alpha1_GitlabEventSource(ref common.Reference Format: "", }, }, - "namespace": { - SchemaProps: spec.SchemaProps{ - Description: "Namespace refers to Kubernetes namespace which is used to retrieve access token from.", - Type: []string{"string"}, - Format: "", - }, - }, "deleteHookOnFinish": { SchemaProps: spec.SchemaProps{ Description: "DeleteHookOnFinish determines whether to delete the GitLab hook for the project once the event source is stopped.", @@ -1012,15 +1012,8 @@ func schema_pkg_apis_eventsource_v1alpha1_GitlabEventSource(ref common.Reference Format: "", }, }, - "allowDuplicate": { - SchemaProps: spec.SchemaProps{ - Description: "AllowDuplicate allows the gateway to register the same webhook integrations for multiple event source configurations. Defaults to false.", - Type: []string{"boolean"}, - Format: "", - }, - }, }, - Required: []string{"webhook", "projectId", "event", "accessToken", "gitlabBaseURL"}, + Required: []string{"webhook", "projectID", "events", "accessToken", "gitlabBaseURL"}, }, }, Dependencies: []string{ diff --git a/pkg/apis/eventsource/v1alpha1/types.go b/pkg/apis/eventsource/v1alpha1/types.go index dc17a20481..4a583be4eb 100644 --- a/pkg/apis/eventsource/v1alpha1/types.go +++ b/pkg/apis/eventsource/v1alpha1/types.go @@ -377,11 +377,11 @@ type GithubEventSource struct { type GitlabEventSource struct { // Webhook holds configuration to run a http server Webhook *webhook.Context `json:"webhook" protobuf:"bytes,1,name=webhook"` - // ProjectId is the id of project for which integration needs to setup - ProjectId string `json:"projectId" protobuf:"bytes,2,name=projectId"` - // Event is a gitlab event to listen to. + // ProjectID is the id of project for which integration needs to setup + ProjectID string `json:"projectID" protobuf:"bytes,2,name=projectID"` + // Events are gitlab event to listen to. // Refer https://github.com/xanzy/go-gitlab/blob/bf34eca5d13a9f4c3f501d8a97b8ac226d55e4d9/projects.go#L794. - Event string `json:"event" protobuf:"bytes,3,name=event"` + Events []string `json:"events" protobuf:"bytes,3,name=events"` // AccessToken is reference to k8 secret which holds the gitlab api access information AccessToken *corev1.SecretKeySelector `json:"accessToken" protobuf:"bytes,4,name=accessToken"` // EnableSSLVerification to enable ssl verification @@ -389,16 +389,9 @@ type GitlabEventSource struct { EnableSSLVerification bool `json:"enableSSLVerification,omitempty" protobuf:"bytes,5,opt,name=enableSSLVerification"` // GitlabBaseURL is the base URL for API requests to a custom endpoint GitlabBaseURL string `json:"gitlabBaseURL" protobuf:"bytes,6,name=gitlabBaseURL"` - // Namespace refers to Kubernetes namespace which is used to retrieve access token from. - // +optional - Namespace string `json:"namespace,omitempty" protobuf:"bytes,7,opt,name=namespace"` // DeleteHookOnFinish determines whether to delete the GitLab hook for the project once the event source is stopped. // +optional - DeleteHookOnFinish bool `json:"deleteHookOnFinish,omitempty" protobuf:"bytes,8,opt,name=deleteHookOnFinish"` - // AllowDuplicate allows the gateway to register the same webhook integrations for multiple event source configurations. - // Defaults to false. - // +optional. - AllowDuplicate bool `json:"allowDuplicate,omitempty" protobuf:"bytes,9,opt,name=allowDuplicate"` + DeleteHookOnFinish bool `json:"deleteHookOnFinish,omitempty" protobuf:"bytes,7,opt,name=deleteHookOnFinish"` } // HDFSEventSource refers to event-source for HDFS related events diff --git a/pkg/apis/eventsource/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/eventsource/v1alpha1/zz_generated.deepcopy.go index ff4b89b0e9..ad004cbbd9 100644 --- a/pkg/apis/eventsource/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/eventsource/v1alpha1/zz_generated.deepcopy.go @@ -484,6 +484,11 @@ func (in *GitlabEventSource) DeepCopyInto(out *GitlabEventSource) { *out = new(webhook.Context) **out = **in } + if in.Events != nil { + in, out := &in.Events, &out.Events + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.AccessToken != nil { in, out := &in.AccessToken, &out.AccessToken *out = new(v1.SecretKeySelector)