Skip to content

Commit 84049a5

Browse files
add demo github pipeline to runtime installation (#119)
* added github demo pipeline to runtime install
1 parent 5de06c1 commit 84049a5

File tree

7 files changed

+368
-118
lines changed

7 files changed

+368
-118
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION=v0.0.111
1+
VERSION=v0.0.112
22
OUT_DIR=dist
33
YEAR?=$(shell date +"%Y")
44

cmd/commands/git-source.go

Lines changed: 224 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,36 @@ import (
1818
"context"
1919
"fmt"
2020
"os"
21+
"strings"
2122
"time"
2223

23-
apicommon "github.com/argoproj/argo-events/pkg/apis/common"
24-
sensorreg "github.com/argoproj/argo-events/pkg/apis/sensor"
2524
"github.com/codefresh-io/cli-v2/pkg/log"
2625
"github.com/codefresh-io/cli-v2/pkg/runtime"
2726
"github.com/codefresh-io/cli-v2/pkg/store"
2827
"github.com/codefresh-io/cli-v2/pkg/util"
2928
apu "github.com/codefresh-io/cli-v2/pkg/util/aputil"
29+
ingressutil "github.com/codefresh-io/cli-v2/pkg/util/ingress"
3030
wfutil "github.com/codefresh-io/cli-v2/pkg/util/workflow"
31-
"github.com/juju/ansiterm"
3231

3332
apcmd "github.com/argoproj-labs/argocd-autopilot/cmd/commands"
3433
"github.com/argoproj-labs/argocd-autopilot/pkg/application"
3534
"github.com/argoproj-labs/argocd-autopilot/pkg/fs"
3635
"github.com/argoproj-labs/argocd-autopilot/pkg/git"
3736
apstore "github.com/argoproj-labs/argocd-autopilot/pkg/store"
3837
aputil "github.com/argoproj-labs/argocd-autopilot/pkg/util"
38+
apicommon "github.com/argoproj/argo-events/pkg/apis/common"
3939
eventsourcereg "github.com/argoproj/argo-events/pkg/apis/eventsource"
4040
eventsourcev1alpha1 "github.com/argoproj/argo-events/pkg/apis/eventsource/v1alpha1"
41+
sensorreg "github.com/argoproj/argo-events/pkg/apis/sensor"
4142
sensorsv1alpha1 "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1"
4243
wf "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow"
4344
wfv1alpha1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
45+
"github.com/juju/ansiterm"
4446
"github.com/spf13/cobra"
45-
v1 "k8s.io/api/core/v1"
47+
corev1 "k8s.io/api/core/v1"
48+
netv1 "k8s.io/api/networking/v1"
4649
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
50+
"k8s.io/apimachinery/pkg/util/intstr"
4751
)
4852

4953
type (
@@ -74,6 +78,12 @@ type (
7478
gsCloneOpts *git.CloneOptions
7579
gsFs fs.FS
7680
}
81+
82+
gitSourceGithubExampleOptions struct {
83+
runtimeName string
84+
gsCloneOpts *git.CloneOptions
85+
gsFs fs.FS
86+
}
7787
)
7888

7989
func NewGitSourceCommand() *cobra.Command {
@@ -184,11 +194,20 @@ func RunGitSourceCreate(ctx context.Context, opts *GitSourceCreateOptions) error
184194
return fmt.Errorf("failed to create cron example pipeline. Error: %w", err)
185195
}
186196

187-
commitMsg := fmt.Sprintf("Created demo workflow template in %s Directory", opts.GsCloneOpts.Path())
197+
err = createGithubExamplePipeline(&gitSourceGithubExampleOptions{
198+
runtimeName: opts.RuntimeName,
199+
gsCloneOpts: opts.GsCloneOpts,
200+
gsFs: gsFs,
201+
})
202+
if err != nil {
203+
return fmt.Errorf("failed to create github example pipeline. Error: %w", err)
204+
}
205+
206+
commitMsg := fmt.Sprintf("Created demo pipelines in %s Directory", opts.GsCloneOpts.Path())
188207

189-
log.G(ctx).Info("Pushing a demo workflow-template to the new git-source repo")
208+
log.G(ctx).Info("Pushing demo pipelines to the new git-source repo")
190209
if err := apu.PushWithMessage(ctx, gsRepo, commitMsg); err != nil {
191-
return fmt.Errorf("failed to push demo workflow-template to git-source repo: %w", err)
210+
return fmt.Errorf("failed to push demo pipelines to git-source repo: %w", err)
192211
}
193212
}
194213

@@ -215,24 +234,7 @@ func createCronExamplePipeline(opts *gitSourceCronExampleOptions) error {
215234
eventSourceFilePath := opts.gsFs.Join(opts.gsCloneOpts.Path(), store.Get().CronExampleEventSourceFileName)
216235
sensorFilePath := opts.gsFs.Join(opts.gsCloneOpts.Path(), store.Get().CronExampleSensorFileName)
217236

218-
eventSource := &eventsourcev1alpha1.EventSource{
219-
TypeMeta: metav1.TypeMeta{
220-
Kind: eventsourcereg.Kind,
221-
APIVersion: eventsourcereg.Group + "/v1alpha1",
222-
},
223-
ObjectMeta: metav1.ObjectMeta{
224-
Name: store.Get().CronExampleEventSourceName,
225-
},
226-
Spec: eventsourcev1alpha1.EventSourceSpec{
227-
EventBusName: store.Get().EventBusName,
228-
Calendar: map[string]eventsourcev1alpha1.CalendarEventSource{
229-
store.Get().CronExampleEventName: {
230-
Interval: "5m",
231-
},
232-
},
233-
},
234-
}
235-
237+
eventSource := createCronExampleEventSource()
236238
err = opts.gsCloneOpts.FS.WriteYamls(eventSourceFilePath, eventSource)
237239
if err != nil {
238240
return fmt.Errorf("failed to write yaml of eventsource. Error: %w", err)
@@ -257,6 +259,26 @@ func createCronExamplePipeline(opts *gitSourceCronExampleOptions) error {
257259
return nil
258260
}
259261

262+
func createCronExampleEventSource() *eventsourcev1alpha1.EventSource {
263+
return &eventsourcev1alpha1.EventSource{
264+
TypeMeta: metav1.TypeMeta{
265+
Kind: eventsourcereg.Kind,
266+
APIVersion: eventsourcereg.Group + "/v1alpha1",
267+
},
268+
ObjectMeta: metav1.ObjectMeta{
269+
Name: store.Get().CronExampleEventSourceName,
270+
},
271+
Spec: eventsourcev1alpha1.EventSourceSpec{
272+
EventBusName: store.Get().EventBusName,
273+
Calendar: map[string]eventsourcev1alpha1.CalendarEventSource{
274+
store.Get().CronExampleEventName: {
275+
Interval: "5m",
276+
},
277+
},
278+
},
279+
}
280+
}
281+
260282
func createCronExampleSensor(triggers []sensorsv1alpha1.Trigger, runtimeName string) (*sensorsv1alpha1.Sensor, error) {
261283
dependencies := []sensorsv1alpha1.EventDependency{
262284
{
@@ -557,7 +579,7 @@ func createDemoWorkflowTemplate(gsFs fs.FS, runtimeName string) error {
557579
Parameters: []wfv1alpha1.Parameter{{Name: "message", Value: wfv1alpha1.AnyStringPtr("hello world")}},
558580
Artifacts: wfv1alpha1.Artifacts{},
559581
},
560-
Container: &v1.Container{
582+
Container: &corev1.Container{
561583
Image: "docker/whalesay:latest",
562584
Command: []string{"cowsay"},
563585
Args: []string{"{{inputs.parameters.message}}"},
@@ -570,3 +592,179 @@ func createDemoWorkflowTemplate(gsFs fs.FS, runtimeName string) error {
570592

571593
return gsFs.WriteYamls(store.Get().CronExampleWfTemplateFileName, wfTemplate)
572594
}
595+
596+
func createGithubExamplePipeline(opts *gitSourceGithubExampleOptions) error {
597+
// Create an ingress that will manage external access to the github eventsource service
598+
ingress := createGithubExampleIngress()
599+
ingressFilePath := opts.gsFs.Join(opts.gsCloneOpts.Path(), store.Get().GithubExampleIngressFileName)
600+
err := opts.gsCloneOpts.FS.WriteYamls(ingressFilePath, ingress)
601+
if err != nil {
602+
return fmt.Errorf("failed to write yaml of github example ingress. Error: %w", err)
603+
}
604+
605+
// Create a github eventsource that will listen to push events in the git source repo
606+
gsRepoURL := opts.gsCloneOpts.URL()
607+
eventSource := createGithubExampleEventSource(gsRepoURL)
608+
eventSourceFilePath := opts.gsFs.Join(opts.gsCloneOpts.Path(), store.Get().GithubExampleEventSourceFileName)
609+
err = opts.gsCloneOpts.FS.WriteYamls(eventSourceFilePath, eventSource)
610+
if err != nil {
611+
return fmt.Errorf("failed to write yaml of secret. Error: %w", err)
612+
}
613+
614+
// Create a sensor that will listen to the events published by the github eventsource, and trigger workflows
615+
sensor := createGithubExampleSensor()
616+
sensorFilePath := opts.gsFs.Join(opts.gsCloneOpts.Path(), store.Get().GithubExampleSensorFileName)
617+
err = opts.gsCloneOpts.FS.WriteYamls(sensorFilePath, sensor)
618+
if err != nil {
619+
return fmt.Errorf("failed to write yaml of github example sensor. Error: %w", err)
620+
}
621+
622+
return nil
623+
}
624+
625+
func createGithubExampleIngress() *netv1.Ingress {
626+
return ingressutil.CreateIngress(&ingressutil.CreateIngressOptions{
627+
Name: store.Get().GithubExampleIngressObjectName,
628+
Paths: []ingressutil.IngressPath{
629+
{
630+
Path: store.Get().GithubExampleEventSourceEndpointPath,
631+
PathType: netv1.PathTypeImplementationSpecific,
632+
ServiceName: store.Get().GithubExampleEventSourceObjectName + "-eventsource-svc",
633+
ServicePort: store.Get().GithubExampleEventSourceServicePort,
634+
},
635+
},
636+
})
637+
}
638+
639+
func getRepoOwnerAndNameFromRepoURL(repoURL string) (owner string, name string) {
640+
_, repoRef, _, _, _, _, _ := aputil.ParseGitUrl(repoURL)
641+
splitRepoRef := strings.Split(repoRef, "/")
642+
owner = splitRepoRef[0]
643+
name = splitRepoRef[1]
644+
return owner, name
645+
}
646+
647+
func createGithubExampleEventSource(repoURL string) *eventsourcev1alpha1.EventSource {
648+
repoOwner, repoName := getRepoOwnerAndNameFromRepoURL(repoURL)
649+
650+
return &eventsourcev1alpha1.EventSource{
651+
TypeMeta: metav1.TypeMeta{
652+
Kind: eventsourcereg.Kind,
653+
APIVersion: eventsourcereg.Group + "/v1alpha1",
654+
},
655+
ObjectMeta: metav1.ObjectMeta{
656+
Name: store.Get().GithubExampleEventSourceObjectName,
657+
},
658+
Spec: eventsourcev1alpha1.EventSourceSpec{
659+
EventBusName: store.Get().EventBusName,
660+
Service: &eventsourcev1alpha1.Service{
661+
Ports: []corev1.ServicePort{
662+
{
663+
Port: store.Get().GithubExampleEventSourceServicePort,
664+
TargetPort: intstr.IntOrString{StrVal: store.Get().GithubExampleEventSourceTargetPort},
665+
},
666+
},
667+
},
668+
Github: map[string]eventsourcev1alpha1.GithubEventSource{
669+
store.Get().GithubExampleEventName: {
670+
Webhook: &eventsourcev1alpha1.WebhookContext{
671+
Endpoint: store.Get().GithubExampleEventSourceEndpointPath,
672+
URL: "http://replace-with-real-public-url",
673+
Port: store.Get().GithubExampleEventSourceTargetPort,
674+
Method: "POST",
675+
},
676+
Repositories: []eventsourcev1alpha1.OwnedRepositories{
677+
{
678+
Owner: repoOwner,
679+
Names: []string{
680+
repoName,
681+
},
682+
},
683+
},
684+
Events: []string{
685+
"push",
686+
},
687+
APIToken: &corev1.SecretKeySelector{
688+
Key: store.Get().GithubAccessTokenSecretKey,
689+
LocalObjectReference: corev1.LocalObjectReference{
690+
Name: store.Get().GithubAccessTokenSecretObjectName,
691+
},
692+
},
693+
ContentType: "json",
694+
Active: true,
695+
Insecure: true,
696+
},
697+
},
698+
},
699+
}
700+
}
701+
702+
func createGithubExampleTrigger() sensorsv1alpha1.Trigger {
703+
workflow := wfutil.CreateWorkflow(&wfutil.CreateWorkflowOptions{
704+
GenerateName: "github-",
705+
SpecWfTemplateRefName: store.Get().GithubExampleTriggerTemplateName,
706+
Parameters: []string{
707+
"message",
708+
},
709+
})
710+
711+
workflowResource := apicommon.NewResource(workflow)
712+
713+
return sensorsv1alpha1.Trigger{
714+
Template: &sensorsv1alpha1.TriggerTemplate{
715+
Name: store.Get().CronExampleTriggerTemplateName,
716+
ArgoWorkflow: &sensorsv1alpha1.ArgoWorkflowTrigger{
717+
GroupVersionResource: metav1.GroupVersionResource{
718+
Group: "argoproj.io",
719+
Version: "v1alpha1",
720+
Resource: "workflows",
721+
},
722+
Operation: sensorsv1alpha1.Submit,
723+
Source: &sensorsv1alpha1.ArtifactLocation{
724+
Resource: &workflowResource,
725+
},
726+
Parameters: []sensorsv1alpha1.TriggerParameter{
727+
{
728+
Src: &sensorsv1alpha1.TriggerParameterSource{
729+
DependencyName: store.Get().GithubExampleDependencyName,
730+
DataKey: "body.hook_id",
731+
},
732+
Dest: "spec.arguments.parameters.0.value",
733+
},
734+
},
735+
},
736+
},
737+
RetryStrategy: &apicommon.Backoff{Steps: 3},
738+
}
739+
}
740+
741+
func createGithubExampleSensor() *sensorsv1alpha1.Sensor {
742+
triggers := []sensorsv1alpha1.Trigger{
743+
createGithubExampleTrigger(),
744+
}
745+
dependencies := []sensorsv1alpha1.EventDependency{
746+
{
747+
Name: store.Get().GithubExampleDependencyName,
748+
EventSourceName: store.Get().GithubExampleEventSourceObjectName,
749+
EventName: store.Get().GithubExampleEventName,
750+
},
751+
}
752+
753+
return &sensorsv1alpha1.Sensor{
754+
TypeMeta: metav1.TypeMeta{
755+
Kind: sensorreg.Kind,
756+
APIVersion: sensorreg.Group + "/v1alpha1",
757+
},
758+
ObjectMeta: metav1.ObjectMeta{
759+
Name: store.Get().GithubExampleSensorObjectName,
760+
},
761+
Spec: sensorsv1alpha1.SensorSpec{
762+
EventBusName: store.Get().EventBusName,
763+
Template: &sensorsv1alpha1.Template{
764+
ServiceAccountName: store.Get().WorkflowTriggerServiceAccount,
765+
},
766+
Dependencies: dependencies,
767+
Triggers: triggers,
768+
},
769+
}
770+
}

cmd/commands/runtime.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import (
5252
"github.com/spf13/cobra"
5353
appsv1 "k8s.io/api/apps/v1"
5454
v1 "k8s.io/api/core/v1"
55+
netv1 "k8s.io/api/networking/v1"
5556
rbacv1 "k8s.io/api/rbac/v1"
5657
kerrors "k8s.io/apimachinery/pkg/api/errors"
5758
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -257,19 +258,17 @@ func RunRuntimeInstall(ctx context.Context, opts *RuntimeInstallOptions) error {
257258
componentNames := getComponents(rt, opts)
258259

259260
token, err := createRuntimeOnPlatform(ctx, &model.RuntimeInstallationArgs{
260-
RuntimeName: opts.RuntimeName,
261-
Cluster: server,
261+
RuntimeName: opts.RuntimeName,
262+
Cluster: server,
262263
RuntimeVersion: runtimeVersion,
263-
IngressHost: &opts.IngressHost,
264+
IngressHost: &opts.IngressHost,
264265
ComponentNames: componentNames,
265266
})
266-
267267
if err != nil {
268268
return fmt.Errorf("failed to create a new runtime: %w", err)
269269
}
270270

271271
opts.RuntimeToken = token
272-
273272
rt.Spec.Cluster = server
274273
rt.Spec.IngressHost = opts.IngressHost
275274

@@ -743,11 +742,21 @@ func createWorkflowsIngress(ctx context.Context, cloneOpts *git.CloneOptions, rt
743742

744743
overlaysDir := fs.Join(apstore.Default.AppsDir, "workflows", apstore.Default.OverlaysDir, rt.Name)
745744
ingress := ingressutil.CreateIngress(&ingressutil.CreateIngressOptions{
746-
Name: rt.Name + store.Get().IngressName,
747-
Namespace: rt.Namespace,
748-
Path: store.Get().IngressPath,
749-
ServiceName: store.Get().ArgoWFServiceName,
750-
ServicePort: store.Get().ArgoWFServicePort,
745+
Name: rt.Name + store.Get().IngressName,
746+
Namespace: rt.Namespace,
747+
Annotations: map[string]string{
748+
"kubernetes.io/ingress.class": "nginx",
749+
"nginx.ingress.kubernetes.io/rewrite-target": "/$2",
750+
"nginx.ingress.kubernetes.io/backend-protocol": "https",
751+
},
752+
Paths: []ingressutil.IngressPath{
753+
{
754+
Path: fmt.Sprintf("/%s(/|$)(.*)", store.Get().IngressPath),
755+
PathType: netv1.PathTypePrefix,
756+
ServiceName: store.Get().ArgoWFServiceName,
757+
ServicePort: store.Get().ArgoWFServicePort,
758+
},
759+
},
751760
})
752761
if err = fs.WriteYamls(fs.Join(overlaysDir, "ingress.yaml"), ingress); err != nil {
753762
return err

0 commit comments

Comments
 (0)