Skip to content

Commit

Permalink
finished lua script, controllerMap issue not done
Browse files Browse the repository at this point in the history
Signed-off-by: Kuromesi <[email protected]>
  • Loading branch information
Kuromesi committed Jul 14, 2023
1 parent 9fa42b9 commit 9a062e0
Show file tree
Hide file tree
Showing 5 changed files with 444 additions and 200 deletions.
228 changes: 169 additions & 59 deletions lua_configuration/networking.istio.io/VirtualService/trafficRouting.lua
Original file line number Diff line number Diff line change
@@ -1,45 +1,140 @@
-- obj = {
-- -- matches = {
-- -- {
-- -- headers = {
-- -- {
-- -- name = "xxx",
-- -- value = "xxx",
-- -- type = "RegularExpression"
-- -- }
-- -- }
-- -- }
-- -- },
-- spec = {
-- hosts = {
-- "reviews",
-- },
-- http = {
-- {
-- route = {
-- {
-- destination = {
-- host = "reviews",
-- subset = "c1"
-- matches = {
-- {
-- headers = {
-- {
-- name = "xxx",
-- value = "xxx",
-- type = "RegularExpression"
-- }
-- }
-- }
-- },
-- data = {
-- spec = {
-- hosts = {
-- "reviews",
-- },
-- http = {
-- {
-- route = {
-- {
-- destination = {
-- host = "reviews",
-- subset = "c1",
-- port = {
-- number = 80
-- }
-- }
-- }
-- }
-- }
-- }
-- }
-- },
-- },

-- stableService = "reviews",
-- canaryService = "canary",
-- stableWeight = 90,
-- canaryWeight = 10
-- }

spec = obj.data.spec

spec = obj.spec
if (obj.matches) then
for _, match in ipairs(obj.matches) do
local route = {}
route["matches"] = {}

-- AN VIRUTALSERVICE EMXAPLE
-- apiVersion: networking.istio.io/v1alpha3
-- kind: VirtualService
-- metadata:
-- name: productpage
-- namespace: nsA
-- spec:
-- http:
-- - match:
-- - uri:
-- prefix: "/productpage/v1/"
-- route:
-- - destination:
-- host: productpage-v1.nsA.svc.cluster.local
-- - route:
-- - destination:
-- host: productpage.nsA.svc.cluster.local

function DeepCopy(original)
local copy
if type(original) == 'table' then
copy = {}
for key, value in pairs(original) do
copy[key] = DeepCopy(value)
end
else
copy = original
end
return copy
end

-- find matched route of VirtualService spec with stable svc
function FindMatchedRules(spec, stableService)
local matchedRoutes = {}
local rules = {}
if (spec.http) then
for _, http in ipairs(spec.http) do
table.insert(rules, http)
end
end
if (spec.tls) then
for _, tls in ipairs(spec.tls) do
table.insert(rules, tls)
end
end
if (spec.tcp) then
for _, tcp in ipairs(spec.tcp) do
table.insert(rules, tcp)
end
end
for _, rule in ipairs(rules) do
for _, route in ipairs(rule.route) do
if route.destination.host == stableService then
table.insert(matchedRoutes, rule)
end
end
end
return matchedRoutes
end

function FindMatchedDestination(spec, stableService)
local matchedDst = {}
local rules = {}
if (spec.http) then
for _, http in ipairs(spec.http) do
table.insert(rules, http)
end
end
if (spec.tls) then
for _, tls in ipairs(spec.tls) do
table.insert(rules, tls)
end
end
if (spec.tcp) then
for _, tcp in ipairs(spec.tcp) do
table.insert(rules, tcp)
end
end
for _, rule in ipairs(rules) do
for _, route in ipairs(rule.route) do
if route.destination.host == stableService then
matchedDst = route.destination
return matchedDst
end
end
end
return matchedDst
end

-- generate routes with matches
function GenerateMatchedRoutes(spec, matches, stableService, canaryService, stableWeight, canaryWeight)
local route = {}
route["match"] = {}
for _, match in ipairs(matches) do
for key, value in pairs(match) do
local vsMatch = {}
vsMatch[key] = {}
Expand All @@ -53,41 +148,56 @@ if (obj.matches) then
vsMatch[key][rule["name"]] = {}
vsMatch[key][rule["name"]][matchType] = rule["value"]
end
table.insert(route["matches"], vsMatch)
table.insert(route["match"], vsMatch)
end
route["route"] = {
{
destination = {
host = obj.stableService,
},
weight = obj.stableWeight,
end
local matchedDst = FindMatchedDestination(spec, stableService)
route["route"] = {
{
destination = DeepCopy(matchedDst),
weight = stableWeight,
},
{
destination = {
host = canaryService,
port = DeepCopy(matchedDst.port)
},
{
destination = {
host = obj.canaryService,
},
weight = obj.canaryWeight,
}
weight = canaryWeight,
}
table.insert(spec.http, 1, route)
end
return spec
}
table.insert(spec.http, 1, route)
end

for i, rule in ipairs(obj.spec.http) do
for _, route in ipairs(rule.route) do
local destination = route.destination
if destination.host == obj.stableService then
route.weight = obj.stableWeight
-- destination.weight = obj.stableWeight
local canary = {
destination = {
host = obj.canaryService,
},
weight = obj.canaryWeight,
}
table.insert(rule.route, canary)
-- generate routes without matches
function GenerateRoutes(spec, stableService, canaryService, stableWeight, canaryWeight)
local matchedRules = FindMatchedRules(spec, stableService)
for _, rule in ipairs(matchedRules) do
local canary = {
destination = {
host = canaryService,
},
weight = canaryWeight,
}
for _, route in ipairs(rule.route) do
-- incase there are multiple versions traffic already
if (route.destination.host == stableService) then
canary.destination.port = DeepCopy(route.destination.port)
end
if (route.weight) then
route.weight = math.floor(route.weight * stableWeight / 100)
else
route.weight = math.floor(stableWeight / #rule.route)
end
end
table.insert(rule.route, canary)
end
end
return spec

if (obj.matches) then
GenerateMatchedRoutes(spec, obj.matches, obj.stableService, obj.canaryService, obj.stableWeight, obj.canaryWeight)
return obj.data
end

GenerateRoutes(spec, obj.stableService, obj.canaryService, obj.stableWeight, obj.canaryWeight)
return obj.data

18 changes: 9 additions & 9 deletions pkg/trafficrouting/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import (

var (
defaultGracePeriodSeconds int32 = 3
controllerMap map[string]interface{} = make(map[string]interface{})
ControllerMap map[string]interface{} = make(map[string]interface{})
)

type TrafficRoutingContext struct {
Expand Down Expand Up @@ -86,9 +86,9 @@ func (m *Manager) InitializeTrafficRouting(c *TrafficRoutingContext) error {
cService := getCanaryServiceName(sService, c.OnlyTrafficRouting)
// new network provider
key := fmt.Sprintf("%s.%s", c.Key, sService)
if _, ok := controllerMap[key]; ok {
return nil
}
// if _, ok := ControllerMap[key]; ok {
// return nil
// }
trController, err := newNetworkProvider(m.Client, c, sService, cService)
if err != nil {
klog.Errorf("%s newNetworkProvider failed: %s", c.Key, err.Error())
Expand All @@ -98,7 +98,7 @@ func (m *Manager) InitializeTrafficRouting(c *TrafficRoutingContext) error {
if err != nil {
return err
}
controllerMap[key] = trController
ControllerMap[key] = trController
return nil
}

Expand Down Expand Up @@ -183,14 +183,14 @@ func (m *Manager) DoTrafficRouting(c *TrafficRoutingContext) (bool, error) {

// new network provider
key := fmt.Sprintf("%s.%s", c.Key, trafficRouting.Service)
trController, ok := controllerMap[key].(network.NetworkProvider)
trController, ok := ControllerMap[key].(network.NetworkProvider)
if !ok {
// in case the rollout controller restart unexpectedly, create a new trafficRouting controller
err := m.InitializeTrafficRouting(c)
if err != nil {
return false, err
}
trController, _ = controllerMap[key].(network.NetworkProvider)
trController, _ = ControllerMap[key].(network.NetworkProvider)
}
verify, err := trController.EnsureRoutes(context.TODO(), &c.Strategy)
if err != nil {
Expand All @@ -214,7 +214,7 @@ func (m *Manager) FinalisingTrafficRouting(c *TrafficRoutingContext, onlyRestore

cServiceName := getCanaryServiceName(trafficRouting.Service, c.OnlyTrafficRouting)
key := fmt.Sprintf("%s.%s", c.Key, trafficRouting.Service)
trController, ok := controllerMap[key].(network.NetworkProvider)
trController, ok := ControllerMap[key].(network.NetworkProvider)
if !ok {
klog.Errorf("failed to fetch newNetworkProvider: %s", key)
return false, nil
Expand Down Expand Up @@ -271,7 +271,7 @@ func (m *Manager) FinalisingTrafficRouting(c *TrafficRoutingContext, onlyRestore
return false, err
}
klog.Infof("%s remove canary service(%s) success", c.Key, cService.Name)
delete(controllerMap, c.Key)
// delete(ControllerMap, key)
return true, nil
}

Expand Down
Loading

0 comments on commit 9a062e0

Please sign in to comment.