git.net

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GitHub] nicolaferraro closed pull request #24: initial code for integration context


nicolaferraro closed pull request #24: initial code for integration context
URL: https://github.com/apache/camel-k/pull/24
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/.gitignore b/.gitignore
index bd29699..2304de0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -123,5 +123,4 @@ tags
 !.vscode/extensions.json
 .history
 
-
 # End of https://www.gitignore.io/api/go,vim,emacs,visualstudiocode
diff --git a/build/Makefile b/build/Makefile
index ce662c1..4ff3d6e 100644
--- a/build/Makefile
+++ b/build/Makefile
@@ -1,8 +1,8 @@
 VERSION := $(shell ./build/get_version.sh)
 
-build: build-runtime build-embed-resources build-operator build-kamel
+build: build-runtime build-operator build-kamel
 
-build-operator:
+build-operator: build-embed-resources
 	go build -o camel-k-operator ./cmd/camel-k-operator/*.go
 
 build-kamel:
diff --git a/cmd/camel-k-operator/kamel_k_operator.go b/cmd/camel-k-operator/kamel_k_operator.go
index 7cd1f72..ff9e088 100644
--- a/cmd/camel-k-operator/kamel_k_operator.go
+++ b/cmd/camel-k-operator/kamel_k_operator.go
@@ -31,27 +31,35 @@ import (
 	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
 )
 
+const resyncPeriod = time.Duration(5) * time.Second
+
 func printVersion() {
 	logrus.Infof("Go Version: %s", runtime.Version())
 	logrus.Infof("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)
 	logrus.Infof("operator-sdk Version: %v", sdkVersion.Version)
 }
 
+func watch(resource string, kind string, namespace string, resyncPeriod time.Duration) {
+	logrus.Infof("Watching %s, %s, %s, %d", resource, kind, namespace, resyncPeriod)
+	sdk.Watch(resource, kind, namespace, resyncPeriod)
+}
+
 func main() {
 	printVersion()
 
 	sdk.ExposeMetricsPort()
 
 	resource := "camel.apache.org/v1alpha1"
-	kind := "Integration"
 	namespace, err := k8sutil.GetWatchNamespace()
 	if err != nil {
 		logrus.Fatalf("failed to get watch namespace: %v", err)
 	}
+
 	ctx := context.TODO()
-	resyncPeriod := time.Duration(5) * time.Second
-	logrus.Infof("Watching %s, %s, %s, %d", resource, kind, namespace, resyncPeriod)
-	sdk.Watch(resource, kind, namespace, resyncPeriod)
+
+	watch(resource, "Integration", namespace, resyncPeriod)
+	watch(resource, "IntegrationContext", namespace, resyncPeriod)
+
 	sdk.Handle(stub.NewHandler(ctx, namespace))
 	sdk.Run(ctx)
 }
diff --git a/deploy/crd-integration-context.yaml b/deploy/crd-integration-context.yaml
new file mode 100644
index 0000000..612c848
--- /dev/null
+++ b/deploy/crd-integration-context.yaml
@@ -0,0 +1,15 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: integrationcontexts.camel.apache.org
+  labels:
+    app: "camel-k"
+spec:
+  group: camel.apache.org
+  names:
+    kind: IntegrationContext
+    listKind: IntegrationContextList
+    plural: integrationcontexts
+    singular: integrationcontext
+  scope: Namespaced
+  version: v1alpha1
diff --git a/deploy/crd.yaml b/deploy/crd-integration.yaml
similarity index 100%
rename from deploy/crd.yaml
rename to deploy/crd-integration.yaml
diff --git a/deploy/resources.go b/deploy/resources.go
index e1b1bbb..02b58ba 100644
--- a/deploy/resources.go
+++ b/deploy/resources.go
@@ -24,7 +24,26 @@ var Resources map[string]string
 func init() {
 	Resources = make(map[string]string)
 
-	Resources["crd.yaml"] =
+	Resources["crd-integration-context.yaml"] =
+		`
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: integrationcontexts.camel.apache.org
+  labels:
+    app: "camel-k"
+spec:
+  group: camel.apache.org
+  names:
+    kind: IntegrationContext
+    listKind: IntegrationContextList
+    plural: integrationcontexts
+    singular: integrationcontext
+  scope: Namespaced
+  version: v1alpha1
+
+`
+	Resources["crd-integration.yaml"] =
 		`
 apiVersion: apiextensions.k8s.io/v1beta1
 kind: CustomResourceDefinition
diff --git a/pkg/apis/camel/v1alpha1/types.go b/pkg/apis/camel/v1alpha1/types.go
index f531052..efdd022 100644
--- a/pkg/apis/camel/v1alpha1/types.go
+++ b/pkg/apis/camel/v1alpha1/types.go
@@ -41,6 +41,7 @@ type Integration struct {
 type IntegrationSpec struct {
 	Replicas *int32     `json:"replicas,omitempty"`
 	Source   SourceSpec `json:"source,omitempty"`
+	Context  string     `json:"context,omitempty"`
 }
 
 type SourceSpec struct {
@@ -61,3 +62,53 @@ const (
 	IntegrationPhaseRunning   IntegrationPhase = "Running"
 	IntegrationPhaseError     IntegrationPhase = "Error"
 )
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+type IntegrationContextList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata"`
+	Items           []IntegrationContext `json:"items"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+type IntegrationContext struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata"`
+	Spec              IntegrationContextSpec   `json:"spec"`
+	Status            IntegrationContextStatus `json:"status,omitempty"`
+}
+
+type IntegrationContextSpec struct {
+	Dependencies []string          `json:"dependencies,omitempty"`
+	Properties   []PropertySpec    `json:"properties,omitempty"`
+	Environment  []EnvironmentSpec `json:"environment,omitempty"`
+}
+
+type PropertySpec struct {
+	Name  string
+	Value string
+}
+type EnvironmentSpec struct {
+	Name  string
+	Value string
+}
+
+type IntegrationContextStatus struct {
+	Phase  IntegrationContextPhase `json:"phase,omitempty"`
+	Digest string                  `json:"digest,omitempty"`
+	Image  string                  `json:"image,omitempty"`
+	From   int                     `json:"from,omitempty"`
+}
+
+type IntegrationContextPhase string
+
+const (
+	// IntegrationContextPhaseDraft --
+	IntegrationContextPhaseDraft IntegrationContextPhase = "Draft"
+	// IntegrationContextPhaseBuilding --
+	IntegrationContextPhaseBuilding IntegrationContextPhase = "Building"
+	// IntegrationContextPhaseReady --
+	IntegrationContextPhaseReady IntegrationContextPhase = "Ready"
+)
diff --git a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
index 213f57a..d29a234 100644
--- a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
@@ -25,6 +25,22 @@ import (
 	runtime "k8s.io/apimachinery/pkg/runtime"
 )
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EnvironmentSpec) DeepCopyInto(out *EnvironmentSpec) {
+	*out = *in
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvironmentSpec.
+func (in *EnvironmentSpec) DeepCopy() *EnvironmentSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(EnvironmentSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Integration) DeepCopyInto(out *Integration) {
 	*out = *in
@@ -53,6 +69,114 @@ func (in *Integration) DeepCopyObject() runtime.Object {
 	return nil
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationContext) DeepCopyInto(out *IntegrationContext) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+	out.Status = in.Status
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationContext.
+func (in *IntegrationContext) DeepCopy() *IntegrationContext {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationContext)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *IntegrationContext) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationContextList) DeepCopyInto(out *IntegrationContextList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	out.ListMeta = in.ListMeta
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]IntegrationContext, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationContextList.
+func (in *IntegrationContextList) DeepCopy() *IntegrationContextList {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationContextList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *IntegrationContextList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationContextSpec) DeepCopyInto(out *IntegrationContextSpec) {
+	*out = *in
+	if in.Dependencies != nil {
+		in, out := &in.Dependencies, &out.Dependencies
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.Properties != nil {
+		in, out := &in.Properties, &out.Properties
+		*out = make([]PropertySpec, len(*in))
+		copy(*out, *in)
+	}
+	if in.Environment != nil {
+		in, out := &in.Environment, &out.Environment
+		*out = make([]EnvironmentSpec, len(*in))
+		copy(*out, *in)
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationContextSpec.
+func (in *IntegrationContextSpec) DeepCopy() *IntegrationContextSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationContextSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationContextStatus) DeepCopyInto(out *IntegrationContextStatus) {
+	*out = *in
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationContextStatus.
+func (in *IntegrationContextStatus) DeepCopy() *IntegrationContextStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationContextStatus)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *IntegrationList) DeepCopyInto(out *IntegrationList) {
 	*out = *in
@@ -124,6 +248,22 @@ func (in *IntegrationStatus) DeepCopy() *IntegrationStatus {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PropertySpec) DeepCopyInto(out *PropertySpec) {
+	*out = *in
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PropertySpec.
+func (in *PropertySpec) DeepCopy() *PropertySpec {
+	if in == nil {
+		return nil
+	}
+	out := new(PropertySpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *SourceSpec) DeepCopyInto(out *SourceSpec) {
 	*out = *in
diff --git a/pkg/client/cmd/context.go b/pkg/client/cmd/context.go
new file mode 100644
index 0000000..6f1e502
--- /dev/null
+++ b/pkg/client/cmd/context.go
@@ -0,0 +1,36 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"github.com/spf13/cobra"
+)
+
+// NewCmdContext --
+func NewCmdContext(rootCmdOptions *RootCmdOptions) *cobra.Command {
+	cmd := cobra.Command{
+		Use:   "context",
+		Short: "Configure an Integration Context",
+		Long:  `Configure an Integration Context.`,
+	}
+
+	cmd.AddCommand(newContextEditCmd(rootCmdOptions))
+	cmd.AddCommand(newContextGetCmd(rootCmdOptions))
+
+	return &cmd
+}
diff --git a/pkg/client/cmd/context_edit.go b/pkg/client/cmd/context_edit.go
new file mode 100644
index 0000000..18879ed
--- /dev/null
+++ b/pkg/client/cmd/context_edit.go
@@ -0,0 +1,101 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"errors"
+	"log"
+	"strconv"
+
+	"github.com/spf13/cobra"
+)
+
+// NewCmdContext --
+func newContextEditCmd(rootCmdOptions *RootCmdOptions) *cobra.Command {
+	impl := &contextEditCommand{
+		RootCmdOptions: rootCmdOptions,
+		discard:        false,
+		save:           true,
+		dependencies: contextResource{
+			toAdd:    make([]string, 0),
+			toRemove: make([]string, 0),
+		},
+		env: contextResource{
+			toAdd:    make([]string, 0),
+			toRemove: make([]string, 0),
+		},
+		properties: contextResource{
+			toAdd:    make([]string, 0),
+			toRemove: make([]string, 0),
+		},
+	}
+
+	cmd := cobra.Command{
+		Use:   "edit",
+		Short: "Edit an Integration Context",
+		Long:  `Edit an Integration Context.`,
+		Args:  impl.validateArgs,
+		RunE:  impl.run,
+	}
+
+	cmd.Flags().BoolVarP(&impl.discard, "discard", "x", false, "Discard the draft")
+	cmd.Flags().BoolVarP(&impl.save, "save", "s", true, "Save the context")
+
+	cmd.Flags().StringSliceVarP(&impl.env.toAdd, "env", "e", nil, "Add an environment variable")
+	cmd.Flags().StringSliceVarP(&impl.env.toRemove, "env-rm", "E", nil, "Remove an environment variable")
+	cmd.Flags().StringSliceVarP(&impl.properties.toAdd, "property", "p", nil, "Add a system property")
+	cmd.Flags().StringSliceVarP(&impl.properties.toRemove, "property-rm", "P", nil, "Remove a system property")
+	cmd.Flags().StringSliceVarP(&impl.dependencies.toAdd, "dependency", "d", nil, "Add a dependency")
+	cmd.Flags().StringSliceVarP(&impl.dependencies.toRemove, "dependency-rm", "D", nil, "Remove a dependency")
+
+	return &cmd
+}
+
+type contextResource struct {
+	toAdd    []string
+	toRemove []string
+}
+
+type contextEditCommand struct {
+	*RootCmdOptions
+
+	env          contextResource
+	properties   contextResource
+	dependencies contextResource
+
+	// rollback the context to the state before it was edited
+	discard bool
+
+	// save the context then the operator should rebuild the image, this is
+	// set as true by default, if you want to mark a context as a draft,
+	// set it to false
+	save bool
+}
+
+func (command *contextEditCommand) validateArgs(cmd *cobra.Command, args []string) error {
+	if len(args) != 1 {
+		return errors.New("accepts 1 arg, received " + strconv.Itoa(len(args)))
+	}
+
+	return nil
+}
+
+func (command *contextEditCommand) run(cmd *cobra.Command, args []string) error {
+	log.Printf("context=%s, config=%+v", args[0], command)
+	return nil
+}
diff --git a/pkg/client/cmd/context_get.go b/pkg/client/cmd/context_get.go
new file mode 100644
index 0000000..36d16c1
--- /dev/null
+++ b/pkg/client/cmd/context_get.go
@@ -0,0 +1,74 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"fmt"
+	"os"
+	"text/tabwriter"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/operator-framework/operator-sdk/pkg/sdk"
+	"github.com/spf13/cobra"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func newContextGetCmd(rootCmdOptions *RootCmdOptions) *cobra.Command {
+	options := contextGetCommand{
+		RootCmdOptions: rootCmdOptions,
+	}
+
+	cmd := cobra.Command{
+		Use:   "get",
+		Short: "Get defined Integration Context",
+		Long:  `Get defined Integration Context.`,
+		RunE:  options.run,
+	}
+
+	return &cmd
+}
+
+type contextGetCommand struct {
+	*RootCmdOptions
+}
+
+func (command *contextGetCommand) run(cmd *cobra.Command, args []string) error {
+	ctxList := v1alpha1.IntegrationContextList{
+		TypeMeta: metav1.TypeMeta{
+			APIVersion: v1alpha1.SchemeGroupVersion.String(),
+			Kind:       "IntegrationContext",
+		},
+	}
+
+	namespace := command.Namespace
+
+	err := sdk.List(namespace, &ctxList)
+	if err != nil {
+		return err
+	}
+
+	w := tabwriter.NewWriter(os.Stdout, 0, 8, 0, '\t', 0)
+	fmt.Fprintln(w, "NAME\tSTATUS")
+	for _, ctx := range ctxList.Items {
+		fmt.Fprintf(w, "%s\t%s\n", ctx.Name, string(ctx.Status.Phase))
+	}
+	w.Flush()
+
+	return nil
+}
diff --git a/pkg/client/cmd/get.go b/pkg/client/cmd/get.go
index d5689b0..f2f4648 100644
--- a/pkg/client/cmd/get.go
+++ b/pkg/client/cmd/get.go
@@ -19,12 +19,13 @@ package cmd
 
 import (
 	"fmt"
+	"os"
+	"text/tabwriter"
+
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/operator-framework/operator-sdk/pkg/sdk"
 	"github.com/spf13/cobra"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"os"
-	"text/tabwriter"
 )
 
 type GetCmdOptions struct {
@@ -61,9 +62,9 @@ func (o *GetCmdOptions) run(cmd *cobra.Command, args []string) error {
 	}
 
 	w := tabwriter.NewWriter(os.Stdout, 0, 8, 0, '\t', 0)
-	fmt.Fprintln(w, "NAME\tSTATUS")
+	fmt.Fprintln(w, "NAME\tCONTEXT\tSTATUS")
 	for _, integration := range integrationList.Items {
-		fmt.Fprintln(w, integration.Name+"\t"+string(integration.Status.Phase))
+		fmt.Fprintf(w, "%s\t%s\t%s\n", integration.Name, integration.Context, string(integration.Status.Phase))
 	}
 	w.Flush()
 
diff --git a/pkg/client/cmd/root.go b/pkg/client/cmd/root.go
index 697fbf5..e0e2a08 100644
--- a/pkg/client/cmd/root.go
+++ b/pkg/client/cmd/root.go
@@ -63,6 +63,7 @@ func NewKamelCommand() (*cobra.Command, error) {
 	cmd.AddCommand(NewCmdRun(&options))
 	cmd.AddCommand(NewCmdGet(&options))
 	cmd.AddCommand(NewCmdInstall(&options))
+	cmd.AddCommand(NewCmdContext(&options))
 
 	return &cmd, nil
 }
diff --git a/pkg/install/cluster.go b/pkg/install/cluster.go
index 818db03..df807bb 100644
--- a/pkg/install/cluster.go
+++ b/pkg/install/cluster.go
@@ -30,15 +30,15 @@ import (
 )
 
 func SetupClusterwideResources() error {
-	// Installing CRD
-	crdInstalled, err := isCRDInstalled()
-	if err != nil {
+
+	// Install CRD for Integration Context (if needed)
+	if err := installCRD("IntegrationContext", "crd-integration-context.yaml"); err != nil {
 		return err
 	}
-	if !crdInstalled {
-		if err := installCRD(); err != nil {
-			return err
-		}
+
+	// Install CRD for Integration (if needed)
+	if err := installCRD("Integration", "crd-integration.yaml"); err != nil {
+		return err
 	}
 
 	// Installing ClusterRole
@@ -56,7 +56,7 @@ func SetupClusterwideResources() error {
 	return nil
 }
 
-func isCRDInstalled() (bool, error) {
+func isCRDInstalled(name string) (bool, error) {
 	lst, err := k8sclient.GetKubeClient().Discovery().ServerResourcesForGroupVersion("camel.apache.org/v1alpha1")
 	if err != nil && errors.IsNotFound(err) {
 		return false, nil
@@ -64,15 +64,24 @@ func isCRDInstalled() (bool, error) {
 		return false, err
 	}
 	for _, res := range lst.APIResources {
-		if res.Kind == "Integration" {
+		if res.Kind == name {
 			return true, nil
 		}
 	}
 	return false, nil
 }
 
-func installCRD() error {
-	crd := []byte(deploy.Resources["crd.yaml"])
+func installCRD(kind string, resourceName string) error {
+	// Installing Integration CRD
+	installed, err := isCRDInstalled(kind)
+	if err != nil {
+		return err
+	}
+	if installed {
+		return nil
+	}
+
+	crd := []byte(deploy.Resources[resourceName])
 	crdJson, err := yaml.ToJSON(crd)
 	if err != nil {
 		return err
diff --git a/pkg/stub/action/context/action.go b/pkg/stub/action/context/action.go
new file mode 100644
index 0000000..c35b84c
--- /dev/null
+++ b/pkg/stub/action/context/action.go
@@ -0,0 +1,34 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package action
+
+import (
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+)
+
+type IntegrationContextAction interface {
+
+	// a user friendly name for the action
+	Name() string
+
+	// returns true if the action can handle the integration context
+	CanHandle(integration *v1alpha1.IntegrationContext) bool
+
+	// executes the handling function
+	Handle(integration *v1alpha1.IntegrationContext) error
+}
diff --git a/pkg/stub/action/context/build.go b/pkg/stub/action/context/build.go
new file mode 100644
index 0000000..1541e9f
--- /dev/null
+++ b/pkg/stub/action/context/build.go
@@ -0,0 +1,46 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package action
+
+import (
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/operator-framework/operator-sdk/pkg/sdk"
+)
+
+func NewIntegrationContextBuildAction() IntegrationContextAction {
+	return &integrationContextBuildAction{}
+}
+
+// start edit context
+type integrationContextBuildAction struct {
+}
+
+func (action *integrationContextBuildAction) Name() string {
+	return "Edit"
+}
+
+func (action *integrationContextBuildAction) CanHandle(context *v1alpha1.IntegrationContext) bool {
+	// TODO: implement
+	return false
+}
+
+func (action *integrationContextBuildAction) Handle(integration *v1alpha1.IntegrationContext) error {
+	target := integration.DeepCopy()
+	// TODO: implement
+	return sdk.Update(target)
+}
diff --git a/pkg/stub/action/context/edit.go b/pkg/stub/action/context/edit.go
new file mode 100644
index 0000000..871d44b
--- /dev/null
+++ b/pkg/stub/action/context/edit.go
@@ -0,0 +1,46 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package action
+
+import (
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/operator-framework/operator-sdk/pkg/sdk"
+)
+
+func NewIntegrationContextEditAction() IntegrationContextAction {
+	return &integrationContextEditAction{}
+}
+
+// start edit context
+type integrationContextEditAction struct {
+}
+
+func (action *integrationContextEditAction) Name() string {
+	return "Edit"
+}
+
+func (action *integrationContextEditAction) CanHandle(context *v1alpha1.IntegrationContext) bool {
+	// TODO: implement
+	return false
+}
+
+func (action *integrationContextEditAction) Handle(integration *v1alpha1.IntegrationContext) error {
+	target := integration.DeepCopy()
+	// TODO: implement
+	return sdk.Update(target)
+}
diff --git a/pkg/stub/action/context/monitor.go b/pkg/stub/action/context/monitor.go
new file mode 100644
index 0000000..98843f7
--- /dev/null
+++ b/pkg/stub/action/context/monitor.go
@@ -0,0 +1,46 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package action
+
+import (
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/operator-framework/operator-sdk/pkg/sdk"
+)
+
+func NewIntegrationContextMonitorAction() IntegrationContextAction {
+	return &integrationContexMonitorAction{}
+}
+
+// start edit context
+type integrationContexMonitorAction struct {
+}
+
+func (action *integrationContexMonitorAction) Name() string {
+	return "Monitor"
+}
+
+func (action *integrationContexMonitorAction) CanHandle(context *v1alpha1.IntegrationContext) bool {
+	// TODO: implement
+	return false
+}
+
+func (action *integrationContexMonitorAction) Handle(integration *v1alpha1.IntegrationContext) error {
+	target := integration.DeepCopy()
+	// TODO: implement
+	return sdk.Update(target)
+}
diff --git a/pkg/stub/action/context/save.go b/pkg/stub/action/context/save.go
new file mode 100644
index 0000000..16d3b0e
--- /dev/null
+++ b/pkg/stub/action/context/save.go
@@ -0,0 +1,46 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package action
+
+import (
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/operator-framework/operator-sdk/pkg/sdk"
+)
+
+func NewIntegrationContextSaveAction() IntegrationContextAction {
+	return &integrationContexSaveAction{}
+}
+
+// start edit context
+type integrationContexSaveAction struct {
+}
+
+func (action *integrationContexSaveAction) Name() string {
+	return "Edit"
+}
+
+func (action *integrationContexSaveAction) CanHandle(context *v1alpha1.IntegrationContext) bool {
+	// TODO: implement
+	return false
+}
+
+func (action *integrationContexSaveAction) Handle(integration *v1alpha1.IntegrationContext) error {
+	target := integration.DeepCopy()
+	// TODO: implement
+	return sdk.Update(target)
+}
diff --git a/pkg/stub/action/action.go b/pkg/stub/action/integration/action.go
similarity index 96%
rename from pkg/stub/action/action.go
rename to pkg/stub/action/integration/action.go
index 08b45b4..c1c7935 100644
--- a/pkg/stub/action/action.go
+++ b/pkg/stub/action/integration/action.go
@@ -21,7 +21,7 @@ import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 )
 
-type Action interface {
+type IntegrationAction interface {
 
 	// a user friendly name for the action
 	Name() string
diff --git a/pkg/stub/action/build.go b/pkg/stub/action/integration/build.go
similarity index 96%
rename from pkg/stub/action/build.go
rename to pkg/stub/action/integration/build.go
index 5dd69b8..98b71d4 100644
--- a/pkg/stub/action/build.go
+++ b/pkg/stub/action/integration/build.go
@@ -19,6 +19,7 @@ package action
 
 import (
 	"context"
+
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/build"
 	"github.com/apache/camel-k/pkg/build/api"
@@ -30,7 +31,7 @@ type BuildAction struct {
 	buildManager *build.BuildManager
 }
 
-func NewBuildAction(ctx context.Context, namespace string) *BuildAction {
+func NewBuildAction(ctx context.Context, namespace string) IntegrationAction {
 	return &BuildAction{
 		buildManager: build.NewBuildManager(ctx, namespace),
 	}
diff --git a/pkg/stub/action/deploy.go b/pkg/stub/action/integration/deploy.go
similarity index 98%
rename from pkg/stub/action/deploy.go
rename to pkg/stub/action/integration/deploy.go
index 3d242d9..43e50b8 100644
--- a/pkg/stub/action/deploy.go
+++ b/pkg/stub/action/integration/deploy.go
@@ -30,7 +30,7 @@ import (
 type DeployAction struct {
 }
 
-func NewDeployAction() *DeployAction {
+func NewDeployAction() IntegrationAction {
 	return &DeployAction{}
 }
 
diff --git a/pkg/stub/action/initialize.go b/pkg/stub/action/integration/initialize.go
similarity index 97%
rename from pkg/stub/action/initialize.go
rename to pkg/stub/action/integration/initialize.go
index f0c119a..6caa1b3 100644
--- a/pkg/stub/action/initialize.go
+++ b/pkg/stub/action/integration/initialize.go
@@ -27,7 +27,7 @@ import (
 type InitializeAction struct {
 }
 
-func NewInitializeAction() *InitializeAction {
+func NewInitializeAction() IntegrationAction {
 	return &InitializeAction{}
 }
 
diff --git a/pkg/stub/action/monitor.go b/pkg/stub/action/integration/monitor.go
similarity index 97%
rename from pkg/stub/action/monitor.go
rename to pkg/stub/action/integration/monitor.go
index 9f67307..ad14532 100644
--- a/pkg/stub/action/monitor.go
+++ b/pkg/stub/action/integration/monitor.go
@@ -27,7 +27,7 @@ import (
 type MonitorAction struct {
 }
 
-func NewMonitorAction() *MonitorAction {
+func NewMonitorAction() IntegrationAction {
 	return &MonitorAction{}
 }
 
diff --git a/pkg/stub/handler.go b/pkg/stub/handler.go
index 53a2a42..5c927cf 100644
--- a/pkg/stub/handler.go
+++ b/pkg/stub/handler.go
@@ -22,30 +22,33 @@ import (
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 
-	"github.com/apache/camel-k/pkg/stub/action"
+	caction "github.com/apache/camel-k/pkg/stub/action/context"
+	iaction "github.com/apache/camel-k/pkg/stub/action/integration"
 	"github.com/operator-framework/operator-sdk/pkg/sdk"
 	"github.com/sirupsen/logrus"
 )
 
 func NewHandler(ctx context.Context, namespace string) sdk.Handler {
 	return &Handler{
-		actionPool: []action.Action{
-			action.NewInitializeAction(),
-			action.NewBuildAction(ctx, namespace),
-			action.NewDeployAction(),
-			action.NewMonitorAction(),
+		integrationActionPool: []iaction.IntegrationAction{
+			iaction.NewInitializeAction(),
+			iaction.NewBuildAction(ctx, namespace),
+			iaction.NewDeployAction(),
+			iaction.NewMonitorAction(),
 		},
+		integrationContextActionPool: []caction.IntegrationContextAction{},
 	}
 }
 
 type Handler struct {
-	actionPool []action.Action
+	integrationActionPool        []iaction.IntegrationAction
+	integrationContextActionPool []caction.IntegrationContextAction
 }
 
 func (h *Handler) Handle(ctx context.Context, event sdk.Event) error {
 	switch o := event.Object.(type) {
 	case *v1alpha1.Integration:
-		for _, a := range h.actionPool {
+		for _, a := range h.integrationActionPool {
 			if a.CanHandle(o) {
 				logrus.Info("Invoking action ", a.Name(), " on integration ", o.Name)
 				if err := a.Handle(o); err != nil {
@@ -53,6 +56,15 @@ func (h *Handler) Handle(ctx context.Context, event sdk.Event) error {
 				}
 			}
 		}
+	case *v1alpha1.IntegrationContext:
+		for _, a := range h.integrationContextActionPool {
+			if a.CanHandle(o) {
+				logrus.Info("Invoking action ", a.Name(), " on context ", o.Name)
+				if err := a.Handle(o); err != nil {
+					return err
+				}
+			}
+		}
 	}
 	return nil
 }
diff --git a/runtime/jvm/.gitignore b/runtime/jvm/.gitignore
index dd8baff..ed92983 100644
--- a/runtime/jvm/.gitignore
+++ b/runtime/jvm/.gitignore
@@ -1,5 +1,10 @@
+target
+
+*.iml
+
 .idea
 .project
 .metadata
-target
-*.iml
+.settings
+.factorypath
+.classpath


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@xxxxxxxxxxxxxxxx


With regards,
Apache Git Services