Skip to content

632-devfile annotation support in generators #123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 22, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/devfile/library
go 1.15

require (
github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed
github.com/devfile/api/v2 v2.0.0-20211102191020-937a76298861
github.com/fatih/color v1.7.0
github.com/gobwas/glob v0.2.3
github.com/golang/mock v1.5.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed h1:OXF9l+MlJrirXAqKN6EZUVaHB0FKm7nh0EjpktwnBig=
github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q=
github.com/devfile/api/v2 v2.0.0-20211102191020-937a76298861 h1:ghb7RgiJwRoVrZaXCWK+aCTMwgXX2nBitHiy7/NPHT0=
github.com/devfile/api/v2 v2.0.0-20211102191020-937a76298861/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
Expand Down
26 changes: 19 additions & 7 deletions pkg/devfile/generator/generators.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ type DeploymentParams struct {
}

// GetDeployment gets a deployment object
func GetDeployment(deployParams DeploymentParams) *appsv1.Deployment {
func GetDeployment(devfileObj parser.DevfileObj, deployParams DeploymentParams) (*appsv1.Deployment, error) {

podTemplateSpecParams := podTemplateSpecParams{
ObjectMeta: deployParams.ObjectMeta,
Expand All @@ -175,13 +175,19 @@ func GetDeployment(deployParams DeploymentParams) *appsv1.Deployment {
PodSelectorLabels: deployParams.PodSelectorLabels,
}

containerAnnotations, err := getContainerAnnotations(devfileObj, common.DevfileOptions{})
if err != nil {
return nil, err
}
deployParams.ObjectMeta.Annotations = mergeMaps(deployParams.ObjectMeta.Annotations, containerAnnotations.Deployment)

deployment := &appsv1.Deployment{
TypeMeta: deployParams.TypeMeta,
ObjectMeta: deployParams.ObjectMeta,
Spec: *getDeploymentSpec(deploySpecParams),
}

return deployment
return deployment, nil
}

// PVCParams is a struct to create PVC
Expand Down Expand Up @@ -218,7 +224,11 @@ func GetService(devfileObj parser.DevfileObj, serviceParams ServiceParams, optio
if err != nil {
return nil, err
}

containerAnnotations, err := getContainerAnnotations(devfileObj, options)
if err != nil {
return nil, err
}
serviceParams.ObjectMeta.Annotations = mergeMaps(serviceParams.ObjectMeta.Annotations, containerAnnotations.Service)
service := &corev1.Service{
TypeMeta: serviceParams.TypeMeta,
ObjectMeta: serviceParams.ObjectMeta,
Expand All @@ -236,9 +246,9 @@ type IngressParams struct {
}

// GetIngress gets an ingress
func GetIngress(ingressParams IngressParams) *extensionsv1.Ingress {

func GetIngress(endpoint v1.Endpoint, ingressParams IngressParams) *extensionsv1.Ingress {
ingressSpec := getIngressSpec(ingressParams.IngressSpecParams)
ingressParams.ObjectMeta.Annotations = mergeMaps(ingressParams.ObjectMeta.Annotations, endpoint.Annotations)

ingress := &extensionsv1.Ingress{
TypeMeta: ingressParams.TypeMeta,
Expand All @@ -250,8 +260,9 @@ func GetIngress(ingressParams IngressParams) *extensionsv1.Ingress {
}

// GetNetworkingV1Ingress gets a networking v1 ingress
func GetNetworkingV1Ingress(ingressParams IngressParams) *networkingv1.Ingress {
func GetNetworkingV1Ingress(endpoint v1.Endpoint, ingressParams IngressParams) *networkingv1.Ingress {
ingressSpec := getNetworkingV1IngressSpec(ingressParams.IngressSpecParams)
ingressParams.ObjectMeta.Annotations = mergeMaps(ingressParams.ObjectMeta.Annotations, endpoint.Annotations)

ingress := &networkingv1.Ingress{
TypeMeta: ingressParams.TypeMeta,
Expand All @@ -270,9 +281,10 @@ type RouteParams struct {
}

// GetRoute gets a route
func GetRoute(routeParams RouteParams) *routev1.Route {
func GetRoute(endpoint v1.Endpoint, routeParams RouteParams) *routev1.Route {

routeSpec := getRouteSpec(routeParams.RouteSpecParams)
routeParams.ObjectMeta.Annotations = mergeMaps(routeParams.ObjectMeta.Annotations, endpoint.Annotations)

route := &routev1.Route{
TypeMeta: routeParams.TypeMeta,
Expand Down
275 changes: 275 additions & 0 deletions pkg/devfile/generator/generators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package generator
import (
"fmt"
"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"reflect"
"strings"
"testing"
Expand Down Expand Up @@ -860,3 +863,275 @@ func TestGetInitContainers(t *testing.T) {
}

}

func TestGetService(t *testing.T) {
trueBool := true

serviceParams := ServiceParams{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"preserved-key": "preserved-value",
},
},
}

tests := []struct {
name string
containerComponents []v1.Component
expected corev1.Service
}{
{
// Currently dedicatedPod can only filter out annotations
// ToDo: dedicatedPod support: https://github.com/devfile/api/issues/670
name: "has dedicated pod",
containerComponents: []v1.Component{
testingutil.GenerateDummyContainerComponent("container1", nil, []v1.Endpoint{
{
Name: "http-8080",
TargetPort: 8080,
},
}, nil, v1.Annotation{
Service: map[string]string{
"key1": "value1",
},
}, nil),
testingutil.GenerateDummyContainerComponent("container2", nil, nil, nil, v1.Annotation{
Service: map[string]string{
"key2": "value2",
},
}, &trueBool),
},
expected: corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"preserved-key": "preserved-value",
"key1": "value1",
},
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Name: "port-8080",
Port: 8080,
TargetPort: intstr.FromInt(8080),
},
},
},
},
},
{
name: "no dedicated pod",
containerComponents: []v1.Component{
testingutil.GenerateDummyContainerComponent("container1", nil, []v1.Endpoint{
{
Name: "http-8080",
TargetPort: 8080,
},
}, nil, v1.Annotation{
Service: map[string]string{
"key1": "value1",
},
}, nil),
testingutil.GenerateDummyContainerComponent("container2", nil, nil, nil, v1.Annotation{
Service: map[string]string{
"key2": "value2",
},
}, nil),
},
expected: corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"preserved-key": "preserved-value",
"key1": "value1",
"key2": "value2",
},
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Name: "port-8080",
Port: 8080,
TargetPort: intstr.FromInt(8080),
},
},
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockDevfileData := data.NewMockDevfileData(ctrl)

options := common.DevfileOptions{
ComponentOptions: common.ComponentOptions{
ComponentType: v1.ContainerComponentType,
},
}
// set up the mock data
mockGetComponents := mockDevfileData.EXPECT().GetComponents(options)
mockGetComponents.Return(tt.containerComponents, nil).AnyTimes()
mockDevfileData.EXPECT().GetProjects(common.DevfileOptions{}).Return(nil, nil).AnyTimes()
mockDevfileData.EXPECT().GetEvents().Return(v1.Events{}).AnyTimes()

devObj := parser.DevfileObj{
Data: mockDevfileData,
}
svc, err := GetService(devObj, serviceParams, common.DevfileOptions{})
// Checks for unexpected error cases
if err != nil {
t.Errorf("TestGetService(): unexpected error %v", err)
}
assert.Equal(t, tt.expected, *svc, "TestGetService(): The two values should be the same.")

})
}
}

func TestGetDeployment(t *testing.T) {
trueBool := true
containers := []corev1.Container{
{
Name: "container1",
},
{
Name: "container2",
},
}
deploymentParams := DeploymentParams{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"preserved-key": "preserved-value",
},
},
Containers: containers,
}

objectMeta := metav1.ObjectMeta{
Annotations: map[string]string{
"preserved-key": "preserved-value",
"key1": "value1",
"key2": "value2",
},
}

objectMetaDedicatedPod := metav1.ObjectMeta{
Annotations: map[string]string{
"preserved-key": "preserved-value",
"key1": "value1",
},
}

tests := []struct {
name string
containerComponents []v1.Component
expected appsv1.Deployment
}{
{
// Currently dedicatedPod can only filter out annotations
// ToDo: dedicatedPod support: https://github.com/devfile/api/issues/670
name: "has dedicated pod",
containerComponents: []v1.Component{
testingutil.GenerateDummyContainerComponent("container1", nil, []v1.Endpoint{
{
Name: "http-8080",
TargetPort: 8080,
},
}, nil, v1.Annotation{
Deployment: map[string]string{
"key1": "value1",
},
}, nil),
testingutil.GenerateDummyContainerComponent("container2", nil, nil, nil, v1.Annotation{
Deployment: map[string]string{
"key2": "value2",
},
}, &trueBool),
},
expected: appsv1.Deployment{
ObjectMeta: objectMetaDedicatedPod,
Spec: appsv1.DeploymentSpec{
Strategy: appsv1.DeploymentStrategy{
Type: appsv1.RecreateDeploymentStrategyType,
},
Selector: &metav1.LabelSelector{
MatchLabels: nil,
},
Template: corev1.PodTemplateSpec{
ObjectMeta: objectMetaDedicatedPod,
Spec: corev1.PodSpec{
Containers: containers,
},
},
},
},
},
{
name: "no dedicated pod",
containerComponents: []v1.Component{
testingutil.GenerateDummyContainerComponent("container1", nil, []v1.Endpoint{
{
Name: "http-8080",
TargetPort: 8080,
},
}, nil, v1.Annotation{
Deployment: map[string]string{
"key1": "value1",
},
}, nil),
testingutil.GenerateDummyContainerComponent("container2", nil, nil, nil, v1.Annotation{
Deployment: map[string]string{
"key2": "value2",
},
}, nil),
},
expected: appsv1.Deployment{
ObjectMeta: objectMeta,
Spec: appsv1.DeploymentSpec{
Strategy: appsv1.DeploymentStrategy{
Type: appsv1.RecreateDeploymentStrategyType,
},
Selector: &metav1.LabelSelector{
MatchLabels: nil,
},
Template: corev1.PodTemplateSpec{
ObjectMeta: objectMeta,
Spec: corev1.PodSpec{
Containers: containers,
},
},
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockDevfileData := data.NewMockDevfileData(ctrl)

options := common.DevfileOptions{
ComponentOptions: common.ComponentOptions{
ComponentType: v1.ContainerComponentType,
},
}
// set up the mock data
mockGetComponents := mockDevfileData.EXPECT().GetComponents(options)
mockGetComponents.Return(tt.containerComponents, nil).AnyTimes()

devObj := parser.DevfileObj{
Data: mockDevfileData,
}
deploy, err := GetDeployment(devObj, deploymentParams)
// Checks for unexpected error cases
if err != nil {
t.Errorf("TestGetDeployment(): unexpected error %v", err)
}
assert.Equal(t, tt.expected, *deploy, "TestGetDeployment(): The two values should be the same.")

})
}
}
Loading