Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

fix: update the target service deployment spec after the plugin execution #57

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
9 changes: 2 additions & 7 deletions kontrol-service/engine/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,9 @@ func GenerateProdDevCluster(baseClusterTopologyMaybeWithTemplateOverrides *resol
return nil, stacktrace.NewError("Service with UUID %s has no DeploymentSpec", devServiceName)
}

deploymentSpec := flow.DeepCopyDeploymentSpec(devService.DeploymentSpec)

// TODO: find a better way to update deploymentSpec, this assumes there is only container in the pod
deploymentSpec.Template.Spec.Containers[0].Image = item.Image

patches = append(patches, flow_spec.ServicePatch{
Service: devServiceName,
DeploymentSpec: deploymentSpec,
Service: devServiceName,
Image: item.Image,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use the image instead of the spec?

})
}

Expand Down
13 changes: 6 additions & 7 deletions kontrol-service/engine/flow/dev_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
"kardinal.kontrol-service/plugins"
"kardinal.kontrol-service/types/cluster_topology/resolved"
"kardinal.kontrol-service/types/flow_spec"

v1 "k8s.io/api/apps/v1"
)

// CreateDevFlow creates a dev flow from the given topologies
Expand Down Expand Up @@ -56,7 +54,7 @@ func CreateDevFlow(
if err != nil {
return nil, err
}
_, err = applyPatch(pluginRunner, topologyRef, clusterGraph, flowID, targetService, servicePatch.DeploymentSpec)
_, err = applyPatch(pluginRunner, topologyRef, clusterGraph, flowID, targetService, servicePatch.Image)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -147,7 +145,7 @@ func applyPatch(
clusterGraph graph.Graph[resolved.ServiceHash, *resolved.Service],
flowID string,
targetService *resolved.Service,
deploymentSpec *v1.DeploymentSpec,
newImage string,
) (*resolved.ClusterTopology, error) {
// Find downstream stateful services
statefulPaths := findAllDownstreamStatefulPaths(targetService, clusterGraph, topology)
Expand All @@ -167,7 +165,7 @@ func applyPatch(

externalPaths := findAllDownstreamExternalPaths(targetService, clusterGraph, topology)
externalServices := make([]*resolved.Service, 0)
alreadyHandledExternalServices := make([]string, 0)

for _, path := range externalPaths {
externalServiceHash, err := lo.Last(path)
if externalServiceHash == "" || err != nil {
Expand Down Expand Up @@ -206,7 +204,8 @@ func applyPatch(
}

modifiedTargetService := DeepCopyService(targetService)
modifiedTargetService.DeploymentSpec = deploymentSpec
// TODO: find a better way to update deploymentSpec, this assumes there is only container in the pod
modifiedTargetService.DeploymentSpec.Template.Spec.Containers[0].Image = newImage
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the target service deployment spec could have been updated when executing the external plugins before these lines, for instance, there could be some env vars overwriting that we need to keep in the deployment spec.
The new image is the only value we need to maintain from the flow_patch.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should think on a MergeSpec(a Spec, b Spec) Spec function instead. Then we decide how to merge it inside the function (like a always take precedence)

modifiedTargetService.Version = flowID
err := topology.UpdateWithService(modifiedTargetService)
if err != nil {
Expand Down Expand Up @@ -266,7 +265,7 @@ func applyPatch(
}

// if the service is an external service of the target service, it was already handled above
if lo.Contains(externalServices, service) && !lo.Contains(alreadyHandledExternalServices, service.ServiceID) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"alreadyHandledExternalServices" is never filled.
I think the service handled above doesn't fall under this condition because "lo.Contains" is comparing pointers and the service pointer has changed after that modification above

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this still true after the new gateway support? let me check it

if lo.Contains(externalServices, service) {
// assume there's only one parent service for now but eventually we'll likely need to account for multiple parents to external service
parentServices := topology.FindImmediateParents(service)
if len(parentServices) == 0 {
Expand Down
24 changes: 15 additions & 9 deletions kontrol-service/engine/flow/dev_flow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ import (
const dummyPluginName = "https://github.com/h4ck3rk3y/identity-plugin.git"

func clusterTopologyExample() resolved.ClusterTopology {
dummySpec := &appsv1.DeploymentSpec{}
dummySpec := &appsv1.DeploymentSpec{
Template: v1.PodTemplateSpec{
Spec: v1.PodSpec{
Containers: []v1.Container{{Image: "dummy-image"}},
},
},
}
testPlugins := []*resolved.StatefulPlugin{
{
Name: dummyPluginName,
Expand Down Expand Up @@ -710,8 +716,8 @@ func TestDevFlowImmutability(t *testing.T) {
FlowId: "dev-flow-1",
ServicePatches: []flow_spec.ServicePatch{
{
Service: "checkoutservice",
DeploymentSpec: checkoutservice.DeploymentSpec,
Service: "checkoutservice",
Image: checkoutservice.DeploymentSpec.Template.Spec.Containers[0].Image,
},
},
}
Expand Down Expand Up @@ -761,8 +767,8 @@ func TestFlowMerging(t *testing.T) {
FlowId: "dev-flow-1",
ServicePatches: []flow_spec.ServicePatch{
{
Service: "checkoutservice",
DeploymentSpec: checkoutservice.DeploymentSpec,
Service: "checkoutservice",
Image: checkoutservice.DeploymentSpec.Template.Spec.Containers[0].Image,
},
},
}
Expand Down Expand Up @@ -800,8 +806,8 @@ func TestExternalServicesFlowOnDependentService(t *testing.T) {
FlowId: "dev-flow-1",
ServicePatches: []flow_spec.ServicePatch{
{
Service: "cartservice",
DeploymentSpec: cartservice.DeploymentSpec,
Service: "cartservice",
Image: cartservice.DeploymentSpec.Template.Spec.Containers[0].Image,
},
},
}
Expand Down Expand Up @@ -833,8 +839,8 @@ func TestExternalServicesCreateDevFlowOnNotDependentService(t *testing.T) {
FlowId: "dev-flow-1",
ServicePatches: []flow_spec.ServicePatch{
{
Service: "frontend",
DeploymentSpec: frontend.DeploymentSpec,
Service: "frontend",
Image: frontend.DeploymentSpec.Template.Spec.Containers[0].Image,
},
},
}
Expand Down
2 changes: 1 addition & 1 deletion kontrol-service/engine/flow/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ func generateDynamicLuaScript(allServices []*resolved.Service, flowId string, na
service = fallbackService
}
if service == nil {
logrus.Errorf("No service found for '%s' for version '%s' or baseline '%s'. No routing can configured.", serviceID, flowId, &baselineFlowVersion)
logrus.Errorf("No service found for '%s' for version '%s' or baseline '%s'. No routing can configured.", serviceID, flowId, baselineFlowVersion)
continue
}

Expand Down
6 changes: 2 additions & 4 deletions kontrol-service/types/flow_spec/resolved.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package flow_spec

import v1 "k8s.io/api/apps/v1"

type FlowPatch struct {
FlowId string
ServicePatches []ServicePatch
}

type ServicePatch struct {
Service string
DeploymentSpec *v1.DeploymentSpec
Service string
Image string
}
Loading