Skip to content

Commit

Permalink
include context traits when looking up for a compatible context #649
Browse files Browse the repository at this point in the history
  • Loading branch information
lburgazzoli authored and nicolaferraro committed May 14, 2019
1 parent b11b4f3 commit 1dbc74b
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 3 deletions.
48 changes: 46 additions & 2 deletions pkg/controller/integration/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ package integration
import (
"context"

"github.com/apache/camel-k/pkg/util"

k8sclient "sigs.k8s.io/controller-runtime/pkg/client"

"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
"github.com/apache/camel-k/pkg/util"

"github.com/pkg/errors"
)

Expand Down Expand Up @@ -75,6 +75,22 @@ func LookupContextForIntegration(ctx context.Context, c k8sclient.Reader, integr
continue
}

//
// When a platform context is created it inherits the traits from the integrations and as
// some traits may influence the build thus the artifacts present on the container image,
// we need to take traits into account when looking up for compatible contexts.
//
// It could also happen that an integration is updated and a trait is modified, if we do
// not include traits in the lookup, we may use a context that does not have all the
// characteristics required by the integration.
//
// An context be used only if it contains a subset of the traits and related configurations
// declared on integration.
//
if !HasMatchingTraits(&ctx, integration) {
continue
}

if util.StringSliceContains(ctx.Spec.Dependencies, integration.Status.Dependencies) {
return &ctx, nil
}
Expand All @@ -83,3 +99,31 @@ func LookupContextForIntegration(ctx context.Context, c k8sclient.Reader, integr

return nil, nil
}

// HasMatchingTraits compare traits defined on context against those defined on integration.
func HasMatchingTraits(ctx *v1alpha1.IntegrationContext, integration *v1alpha1.Integration) bool {
for ctxTraitName, ctxTraitConf := range ctx.Spec.Traits {
iTraitConf, ok := integration.Spec.Traits[ctxTraitName]
if !ok {
// skip it because trait configured on context is not defined on integration.
return false
}

for ck, cv := range ctxTraitConf.Configuration {
iv, ok := iTraitConf.Configuration[ck]

if !ok {
// skip it because trait configured on context has a value that is not defined
// in integration trait
return false
}
if iv != cv {
// skip it because trait configured on context has a value that differs from
// the one configured on integration
return false
}
}
}

return true
}
191 changes: 190 additions & 1 deletion pkg/controller/integration/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"github.com/stretchr/testify/assert"
)

func TestLookupContextForIntegration(t *testing.T) {
func TestLookupContextForIntegration_DiscardContextsInError(t *testing.T) {
c, err := test.NewFakeClient(
&v1alpha1.IntegrationContext{
TypeMeta: metav1.TypeMeta{
Expand Down Expand Up @@ -100,3 +100,192 @@ func TestLookupContextForIntegration(t *testing.T) {
assert.NotNil(t, i)
assert.Equal(t, "my-context-2", i.Name)
}

func TestLookupContextForIntegration_DiscardContextsWithIncompatibleTraits(t *testing.T) {
c, err := test.NewFakeClient(
//
// Should be discarded because it contains both of the required traits but one
// contains a different configuration value
//
&v1alpha1.IntegrationContext{
TypeMeta: metav1.TypeMeta{
APIVersion: v1alpha1.SchemeGroupVersion.String(),
Kind: v1alpha1.IntegrationContextKind,
},
ObjectMeta: metav1.ObjectMeta{
Namespace: "ns",
Name: "my-context-1",
Labels: map[string]string{
"camel.apache.org/context.type": v1alpha1.IntegrationContextTypePlatform,
},
},
Spec: v1alpha1.IntegrationContextSpec{
Dependencies: []string{
"camel-core",
"camel-irc",
},
Traits: map[string]v1alpha1.TraitSpec{
"knative": {
Configuration: map[string]string{
"enabled": "true",
},
},
"knative-service": {
Configuration: map[string]string{
"enabled": "false",
},
},
},
},
Status: v1alpha1.IntegrationContextStatus{
Phase: v1alpha1.IntegrationContextPhaseReady,
},
},
//
// Should be discarded because it contains a subset of the required traits but
// with different configuration value
//
&v1alpha1.IntegrationContext{
TypeMeta: metav1.TypeMeta{
APIVersion: v1alpha1.SchemeGroupVersion.String(),
Kind: v1alpha1.IntegrationContextKind,
},
ObjectMeta: metav1.ObjectMeta{
Namespace: "ns",
Name: "my-context-2",
Labels: map[string]string{
"camel.apache.org/context.type": v1alpha1.IntegrationContextTypePlatform,
},
},
Spec: v1alpha1.IntegrationContextSpec{
Dependencies: []string{
"camel-core",
"camel-irc",
},
Traits: map[string]v1alpha1.TraitSpec{
"knative": {
Configuration: map[string]string{
"enabled": "false",
},
},
},
},
Status: v1alpha1.IntegrationContextStatus{
Phase: v1alpha1.IntegrationContextPhaseReady,
},
},
//
// Should be discarded because it contains both of the required traits but
// also an additional one
//
&v1alpha1.IntegrationContext{
TypeMeta: metav1.TypeMeta{
APIVersion: v1alpha1.SchemeGroupVersion.String(),
Kind: v1alpha1.IntegrationContextKind,
},
ObjectMeta: metav1.ObjectMeta{
Namespace: "ns",
Name: "my-context-3",
Labels: map[string]string{
"camel.apache.org/context.type": v1alpha1.IntegrationContextTypePlatform,
},
},
Spec: v1alpha1.IntegrationContextSpec{
Dependencies: []string{
"camel-core",
"camel-irc",
},
Traits: map[string]v1alpha1.TraitSpec{
"knative": {
Configuration: map[string]string{
"enabled": "true",
},
},
"knative-service": {
Configuration: map[string]string{
"enabled": "true",
},
},
"gc": {
Configuration: map[string]string{
"enabled": "true",
},
},
},
},
Status: v1alpha1.IntegrationContextStatus{
Phase: v1alpha1.IntegrationContextPhaseReady,
},
},
//
// Should be discarded because it contains a subset of the required traits and
// same configuration values
//
&v1alpha1.IntegrationContext{
TypeMeta: metav1.TypeMeta{
APIVersion: v1alpha1.SchemeGroupVersion.String(),
Kind: v1alpha1.IntegrationContextKind,
},
ObjectMeta: metav1.ObjectMeta{
Namespace: "ns",
Name: "my-context-4",
Labels: map[string]string{
"camel.apache.org/context.type": v1alpha1.IntegrationContextTypePlatform,
},
},
Spec: v1alpha1.IntegrationContextSpec{
Dependencies: []string{
"camel-core",
"camel-irc",
},
Traits: map[string]v1alpha1.TraitSpec{
"knative": {
Configuration: map[string]string{
"enabled": "true",
},
},
},
},
Status: v1alpha1.IntegrationContextStatus{
Phase: v1alpha1.IntegrationContextPhaseReady,
},
},
)

assert.Nil(t, err)

i, err := LookupContextForIntegration(context.TODO(), c, &v1alpha1.Integration{
TypeMeta: metav1.TypeMeta{
APIVersion: v1alpha1.SchemeGroupVersion.String(),
Kind: v1alpha1.IntegrationKind,
},
ObjectMeta: metav1.ObjectMeta{
Namespace: "ns",
Name: "my-integration",
},
Spec: v1alpha1.IntegrationSpec{
Traits: map[string]v1alpha1.TraitSpec{
"knative": {
Configuration: map[string]string{
"enabled": "true",
},
},
"knative-service": {
Configuration: map[string]string{
"enabled": "true",
},
},
},
},
Status: v1alpha1.IntegrationStatus{
Dependencies: []string{
"camel-core",
"camel-irc",
},
},
})

assert.Nil(t, err)
assert.NotNil(t, i)
assert.Equal(t, "my-context-4", i.Name)
}

0 comments on commit 1dbc74b

Please sign in to comment.