This is an automated email from the ASF dual-hosted git repository. lburgazzoli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 23d0287ae62446392b6f924fd56a86e25f0a8ff5 Author: nferraro <[email protected]> AuthorDate: Wed Oct 3 22:40:03 2018 +0200 Initial work on traits --- pkg/apis/camel/v1alpha1/types.go | 19 ++++++--- pkg/trait/catalog/catalog.go | 85 +++++++++++++++++++++++++++++++++++++++ pkg/trait/catalog/expose.go | 34 ++++++++++++++++ pkg/trait/catalog/identity.go | 34 ++++++++++++++++ pkg/trait/doc.go | 19 +++++++++ pkg/trait/trait.go | 39 ++++++++++++++++++ pkg/util/kubernetes/collection.go | 64 +++++++++++++++++++++++++++++ 7 files changed, 288 insertions(+), 6 deletions(-) diff --git a/pkg/apis/camel/v1alpha1/types.go b/pkg/apis/camel/v1alpha1/types.go index 114942f..61141af 100644 --- a/pkg/apis/camel/v1alpha1/types.go +++ b/pkg/apis/camel/v1alpha1/types.go @@ -48,12 +48,13 @@ type Integration struct { // IntegrationSpec -- type IntegrationSpec struct { - Replicas *int32 `json:"replicas,omitempty"` - Source SourceSpec `json:"source,omitempty"` - Context string `json:"context,omitempty"` - Dependencies []string `json:"dependencies,omitempty"` - DependenciesAutoDiscovery *bool `json:"dependenciesAutoDiscovery,omitempty"` - Configuration []ConfigurationSpec `json:"configuration,omitempty"` + Replicas *int32 `json:"replicas,omitempty"` + Source SourceSpec `json:"source,omitempty"` + Context string `json:"context,omitempty"` + Dependencies []string `json:"dependencies,omitempty"` + Traits map[string]IntegrationTraitSpec `json:"traits,omitempty"` + DependenciesAutoDiscovery *bool `json:"dependenciesAutoDiscovery,omitempty"` + Configuration []ConfigurationSpec `json:"configuration,omitempty"` } // SourceSpec -- @@ -81,6 +82,12 @@ const ( LanguageKotlin Language = "kts" ) +// A IntegrationTraitSpec contains the configuration of a trait +type IntegrationTraitSpec struct { + Enabled *bool `json:"enabled,omitempty"` + Configuration map[string]string `json:"configuration,omitempty"` +} + // IntegrationStatus -- type IntegrationStatus struct { Phase IntegrationPhase `json:"phase,omitempty"` diff --git a/pkg/trait/catalog/catalog.go b/pkg/trait/catalog/catalog.go new file mode 100644 index 0000000..924ed37 --- /dev/null +++ b/pkg/trait/catalog/catalog.go @@ -0,0 +1,85 @@ +/* +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 catalog + +import ( + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + "github.com/apache/camel-k/pkg/trait" + "github.com/apache/camel-k/pkg/util/kubernetes" +) + +// TraitID uniquely identifies a trait +type TraitID string + +const ( + // Expose exposes a integration to the external world + Expose TraitID = "expose" +) + +// A Catalog is just a DeploymentCustomizer that applies multiple traits +type Catalog trait.DeploymentCustomizer + +// For returns a Catalog for the given integration details +func For(environment trait.Environment) Catalog { + +} + +func compose(traits ...trait.DeploymentCustomizer) trait.DeploymentCustomizer { + if len(traits) == 0 { + return &identityTrait{} + } else if len(traits) == 1 { + return traits[0] + } + var composite trait.DeploymentCustomizer = &identityTrait{} + for _, t := range traits { + composite = &catalogCustomizer{ + t1: composite, + t2: t, + } + } + return composite +} + +// ------------------------------------------- + +type catalogCustomizer struct { + t1 trait.DeploymentCustomizer + t2 trait.DeploymentCustomizer +} + +func (c *catalogCustomizer) Name() string { + return "" +} + +func (c *catalogCustomizer) Customize(environment trait.Environment, resources *kubernetes.Collection) (bool, error) { + atLeastOnce := false + var done bool + var err error + if done, err = c.t1.Customize(environment, resources); err != nil { + return false, err + } else if done && c.t1.Name() != "" { + environment.ExecutedCustomizers = append(environment.ExecutedCustomizers, c.t1.Name()) + } + atLeastOnce = atLeastOnce || done + done2, err := c.t2.Customize(environment, resources) + if done2 && c.t2.Name() != "" { + environment.ExecutedCustomizers = append(environment.ExecutedCustomizers, c.t2.Name()) + } + environment.ExecutedCustomizers = append(environment.ExecutedCustomizers, c.t1.Name()) + return atLeastOnce || done2, err +} diff --git a/pkg/trait/catalog/expose.go b/pkg/trait/catalog/expose.go new file mode 100644 index 0000000..91890eb --- /dev/null +++ b/pkg/trait/catalog/expose.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 catalog + +import ( + "github.com/apache/camel-k/pkg/trait" + "github.com/apache/camel-k/pkg/util/kubernetes" +) + +type exposeTrait struct { +} + +func (*exposeTrait) Name() string { + return "expose" +} + +func (*exposeTrait) Customize(environment trait.Environment, resources *kubernetes.Collection) (bool, error) { + return false, nil +} diff --git a/pkg/trait/catalog/identity.go b/pkg/trait/catalog/identity.go new file mode 100644 index 0000000..cddd0f4 --- /dev/null +++ b/pkg/trait/catalog/identity.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 catalog + +import ( + "github.com/apache/camel-k/pkg/trait" + "github.com/apache/camel-k/pkg/util/kubernetes" +) + +type identityTrait struct { +} + +func (*identityTrait) Name() string { + return "identity" +} + +func (*identityTrait) Customize(environment trait.Environment, resources *kubernetes.Collection) (bool, error) { + return false, nil +} diff --git a/pkg/trait/doc.go b/pkg/trait/doc.go new file mode 100644 index 0000000..7216c27 --- /dev/null +++ b/pkg/trait/doc.go @@ -0,0 +1,19 @@ +/* +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 trait contains implementations of all available traits (features) +package trait diff --git a/pkg/trait/trait.go b/pkg/trait/trait.go new file mode 100644 index 0000000..e0bb7ef --- /dev/null +++ b/pkg/trait/trait.go @@ -0,0 +1,39 @@ +/* +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 trait + +import ( + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + "github.com/apache/camel-k/pkg/util/kubernetes" +) + +// A Environment provides the context where the trait is executed +type Environment struct { + Platform *v1alpha1.IntegrationPlatform + Context *v1alpha1.IntegrationContext + Integration *v1alpha1.Integration + ExecutedCustomizers []string +} + +// A DeploymentCustomizer performs customization of the deployed objects +type DeploymentCustomizer interface { + // The Name of the customizer + Name() string + // Customize executes the trait customization on the resources and return true if the resources have been changed + Customize(environment Environment, resources *kubernetes.Collection) (bool, error) +} diff --git a/pkg/util/kubernetes/collection.go b/pkg/util/kubernetes/collection.go new file mode 100644 index 0000000..a3ff2b7 --- /dev/null +++ b/pkg/util/kubernetes/collection.go @@ -0,0 +1,64 @@ +/* +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 kubernetes + +import ( + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// A Collection is a container of Kubernetes resources +type Collection struct { + items []runtime.Object +} + +// Items returns all resources belonging to the collection +func (c *Collection) Items() []runtime.Object { + return c.items +} + +// Add adds a resource to the collection +func (c *Collection) Add(resource runtime.Object) { + c.items = append(c.items, resource) +} + +// VisitDeployment executes the visitor function on all Deployment resources +func (c *Collection) VisitDeployment(visitor func(*appsv1.Deployment)) { + c.Visit(func(res runtime.Object) { + if conv, ok := res.(*appsv1.Deployment); ok { + visitor(conv) + } + }) +} + +// VisitConfigMap executes the visitor function on all ConfigMap resources +func (c *Collection) VisitConfigMap(visitor func(configMap *corev1.ConfigMap)) { + c.Visit(func(res runtime.Object) { + if conv, ok := res.(*corev1.ConfigMap); ok { + visitor(conv) + } + }) +} + +// Visit executes the visitor function on all resources +func (c *Collection) Visit(visitor func(runtime.Object)) { + for _, res := range c.items { + visitor(res) + } +}
