add lua scripts for istio (#178)

* add lua scripts for istio

Signed-off-by: Kuromesi <blackfacepan@163.com>

* make some improvements for istio lua script

Signed-off-by: Kuromesi <blackfacepan@163.com>

---------

Signed-off-by: Kuromesi <blackfacepan@163.com>
This commit is contained in:
Kuromesi 2023-11-06 17:34:57 +08:00 committed by GitHub
parent d41b1fa7d7
commit 07b7f20f6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 484 additions and 1 deletions

View File

@ -138,7 +138,7 @@ func objectToTable(path string) error {
return fmt.Errorf("failed to open file: %s", err)
}
defer fileStream.Close()
header := "-- THIS IS GENERATED BY LUA.GO FOR DEBUGGING --\n"
header := "-- THIS IS GENERATED BY CONVERT_TEST_CASE_TO_LUA_OBJECT.GO FOR DEBUGGING --\n"
_, err = io.WriteString(fileStream, header+objStr)
if err != nil {
return fmt.Errorf("failed to WriteString %s", err)

View File

@ -0,0 +1,49 @@
trafficRouting:
apiVersion: rollouts.kruise.io/v1alpha1
kind: TrafficRouting
metadata:
name: tr-demo
spec:
strategy:
matches:
- headers:
- type: Exact
name: version
value: canary
objectRef:
- service: svc-demo
customNetworkRefs:
- apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
name: ds-demo
original:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: ds-demo
spec:
host: svc-demo
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
subsets:
- labels:
version: base
name: version-base
expected:
- apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: ds-demo
spec:
host: svc-demo
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
subsets:
- labels:
version: base
name: version-base
- labels:
istio.service.tag: gray
name: canary

View File

@ -0,0 +1,8 @@
local spec = obj.data.spec
local canary = {}
canary.labels = {}
canary.name = "canary"
local podLabelKey = "istio.service.tag"
canary.labels[podLabelKey] = "gray"
table.insert(spec.subsets, canary)
return obj.data

View File

@ -0,0 +1,122 @@
rollout:
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-demo
annotations:
rollouts.kruise.io/rolling-style: canary
spec:
disabled: false
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: deploy-demo
strategy:
canary:
steps:
- matches:
- headers:
- type: Exact
name: user-agent
value: pc
- type: RegularExpression
name: name
value: ".*demo"
- matches:
- headers:
- type: Exact
name: user-agent
value: pc
- headers:
- type: RegularExpression
name: name
value: ".*demo"
- weight: 50
trafficRoutings:
- service: svc-demo
customNetworkRefs:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
name: vs-demo
original:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- route:
- destination:
host: svc-demo
expected:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- match:
- headers:
user-agent:
exact: pc
name:
regex: .*demo
route:
- destination:
host: svc-demo-canary
- route:
- destination:
host: svc-demo
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- match:
- headers:
name:
regex: .*demo
route:
- destination:
host: svc-demo-canary
- match:
- headers:
user-agent:
exact: pc
route:
- destination:
host: svc-demo-canary
- route:
- destination:
host: svc-demo
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- route:
- destination:
host: svc-demo
weight: 50
- destination:
host: svc-demo-canary
weight: 50

View File

@ -0,0 +1,61 @@
trafficRouting:
apiVersion: rollouts.kruise.io/v1alpha1
kind: TrafficRouting
metadata:
name: tr-demo
spec:
strategy:
matches:
- headers:
- type: Exact
name: user-agent
value: pc
- type: RegularExpression
name: name
value: ".*demo"
objectRef:
- service: svc-demo
customNetworkRefs:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
name: vs-demo
original:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- route:
- destination:
host: svc-demo
subset: base
expected:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- match:
- headers:
user-agent:
exact: pc
name:
regex: .*demo
route:
- destination:
host: svc-demo
subset: canary
- route:
- destination:
host: svc-demo
subset: base

View File

@ -0,0 +1,68 @@
trafficRouting:
apiVersion: rollouts.kruise.io/v1alpha1
kind: TrafficRouting
metadata:
name: tr-demo
spec:
strategy:
matches:
- headers:
- type: Exact
name: user-agent
value: pc
- headers:
- type: RegularExpression
name: name
value: ".*demo"
objectRef:
- service: svc-demo
customNetworkRefs:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
name: vs-demo
original:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- route:
- destination:
host: svc-demo
subset: base
expected:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- match:
- headers:
name:
regex: .*demo
route:
- destination:
host: svc-demo
subset: canary
- match:
- headers:
user-agent:
exact: pc
route:
- destination:
host: svc-demo
subset: canary
- route:
- destination:
host: svc-demo
subset: base

View File

@ -0,0 +1,50 @@
trafficRouting:
apiVersion: rollouts.kruise.io/v1alpha1
kind: TrafficRouting
metadata:
name: tr-demo
spec:
strategy:
weight: 50
objectRef:
- service: svc-demo
customNetworkRefs:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
name: vs-demo
original:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- route:
- destination:
host: svc-demo
subset: base
expected:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-vs
namespace: demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- route:
- destination:
host: svc-demo
subset: base
weight: 50
- destination:
host: svc-demo
subset: canary
weight: 50

View File

@ -0,0 +1,125 @@
spec = obj.data.spec
if obj.canaryWeight == -1 then
obj.canaryWeight = 100
obj.stableWeight = 0
end
function GetHost(destination)
local host = destination.destination.host
dot_position = string.find(host, ".", 1, true)
if (dot_position) then
host = string.sub(host, 1, dot_position - 1)
end
return host
end
-- find routes of VirtualService with stableService
function GetRulesToPatch(spec, stableService, protocol)
local matchedRoutes = {}
if (spec[protocol] ~= nil) then
for _, rule in ipairs(spec[protocol]) do
-- skip routes contain matches
if (rule.match == nil) then
for _, route in ipairs(rule.route) do
if GetHost(route) == stableService then
table.insert(matchedRoutes, rule)
end
end
end
end
end
return matchedRoutes
end
function CalculateWeight(route, stableWeight, n)
local weight
if (route.weight) then
weight = math.floor(route.weight * stableWeight / 100)
else
weight = math.floor(stableWeight / n)
end
return weight
end
-- generate routes with matches, insert a rule before other rules, only support http headers, cookies etc.
function GenerateRoutesWithMatches(spec, matches, stableService, canaryService)
for _, match in ipairs(matches) do
local route = {}
route["match"] = {}
for key, value in pairs(match) do
local vsMatch = {}
vsMatch[key] = {}
for _, rule in ipairs(value) do
if rule["type"] == "RegularExpression" then
matchType = "regex"
elseif rule["type"] == "Exact" then
matchType = "exact"
elseif rule["type"] == "Prefix" then
matchType = "prefix"
end
if key == "headers" then
vsMatch[key][rule["name"]] = {}
vsMatch[key][rule["name"]][matchType] = rule.value
else
vsMatch[key][matchType] = rule.value
end
end
table.insert(route["match"], vsMatch)
end
route.route = {
{
destination = {}
}
}
-- stableService == canaryService indicates DestinationRule exists and subset is set to be canary by default
if stableService == canaryService then
route.route[1].destination.host = stableService
route.route[1].destination.subset = "canary"
else
route.route[1].destination.host = canaryService
end
table.insert(spec.http, 1, route)
end
end
-- generate routes without matches, change every rule whose host is stableService
function GenerateRoutes(spec, stableService, canaryService, stableWeight, canaryWeight, protocol)
local matchedRules = GetRulesToPatch(spec, stableService, protocol)
for _, rule in ipairs(matchedRules) do
local canary
if stableService ~= canaryService then
canary = {
destination = {
host = canaryService,
},
weight = canaryWeight,
}
else
canary = {
destination = {
host = stableService,
subset = "canary",
},
weight = canaryWeight,
}
end
-- incase there are multiple versions traffic already, do a for-loop
for _, route in ipairs(rule.route) do
-- update stable service weight
route.weight = CalculateWeight(route, stableWeight, #rule.route)
end
table.insert(rule.route, canary)
end
end
if (obj.matches)
then
GenerateRoutesWithMatches(spec, obj.matches, obj.stableService, obj.canaryService)
else
GenerateRoutes(spec, obj.stableService, obj.canaryService, obj.stableWeight, obj.canaryWeight, "http")
GenerateRoutes(spec, obj.stableService, obj.canaryService, obj.stableWeight, obj.canaryWeight, "tcp")
GenerateRoutes(spec, obj.stableService, obj.canaryService, obj.stableWeight, obj.canaryWeight, "tls")
end
return obj.data