Skip to content

Commit d0dac23

Browse files
feat: generate multiple config files instead of only one config.json (#331)
* feat: generate multiple config files instead of only one config.json Signed-off-by: Lin Yang <[email protected]> * build(deps): bump go-resty from 2.7.0 to 2.14.0 Signed-off-by: Lin Yang <[email protected]> * fix: path for fgw configuration Signed-off-by: Lin Yang <[email protected]> * fix: wrong fgw arguments Signed-off-by: Lin Yang <[email protected]> * fix: wrong fgw config dir Signed-off-by: Lin Yang <[email protected]> * fix: chart readme Signed-off-by: Lin Yang <[email protected]> * fix: golang lint Signed-off-by: Lin Yang <[email protected]> * build: bump pipy to 1.4.1 Signed-off-by: Lin Yang <[email protected]> build: bump pipy to 1.4.1 Signed-off-by: Lin Yang <[email protected]> --------- Signed-off-by: Lin Yang <[email protected]>
1 parent ab0e2c9 commit d0dac23

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1556
-426
lines changed

charts/fsm/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -445,11 +445,11 @@ The following table lists the configurable parameters of the fsm chart and their
445445
| fsm.remoteLogging.port | int | `30514` | Port of the remote logging service |
446446
| fsm.remoteLogging.sampledFraction | string | `"1.0"` | Sampled Fraction |
447447
| fsm.remoteLogging.secretName | string | `"fsm-remote-logging-secret"` | Secret Name |
448-
| fsm.repoServer | object | `{"codebase":"","image":{"name":"pipy-repo","registry":"flomesh","tag":"1.3.0"},"ipaddr":"127.0.0.1","port":6060,"standalone":false}` | Pipy RepoServer |
448+
| fsm.repoServer | object | `{"codebase":"","image":{"name":"pipy-repo","registry":"flomesh","tag":"1.4.1"},"ipaddr":"127.0.0.1","port":6060,"standalone":false}` | Pipy RepoServer |
449449
| fsm.repoServer.codebase | string | `""` | codebase is the folder used by fsmController. |
450450
| fsm.repoServer.image.name | string | `"pipy-repo"` | Repo server image name |
451451
| fsm.repoServer.image.registry | string | `"flomesh"` | Registry for repo server image |
452-
| fsm.repoServer.image.tag | string | `"1.3.0"` | Repo server image tag |
452+
| fsm.repoServer.image.tag | string | `"1.4.1"` | Repo server image tag |
453453
| fsm.repoServer.ipaddr | string | `"127.0.0.1"` | ipaddr of host/service where Pipy RepoServer is installed |
454454
| fsm.repoServer.port | int | `6060` | port of pipy RepoServer |
455455
| fsm.repoServer.standalone | bool | `false` | if false , Pipy RepoServer is installed within fsmController pod. |
@@ -458,10 +458,10 @@ The following table lists the configurable parameters of the fsm chart and their
458458
| fsm.serviceLB.image.name | string | `"mirrored-klipper-lb"` | service-lb image name |
459459
| fsm.serviceLB.image.registry | string | `"flomesh"` | Registry for service-lb image |
460460
| fsm.serviceLB.image.tag | string | `"v0.4.7"` | service-lb image tag |
461-
| fsm.sidecar | object | `{"image":{"name":"pipy","registry":"flomesh","tag":"1.3.0"},"sidecarDisabledMTLS":false,"sidecarLogLevel":"error","sidecarTimeout":60}` | Sidecar supported by fsm |
461+
| fsm.sidecar | object | `{"image":{"name":"pipy","registry":"flomesh","tag":"1.4.1"},"sidecarDisabledMTLS":false,"sidecarLogLevel":"error","sidecarTimeout":60}` | Sidecar supported by fsm |
462462
| fsm.sidecar.image.name | string | `"pipy"` | Sidecar image name |
463463
| fsm.sidecar.image.registry | string | `"flomesh"` | Registry for sidecar image |
464-
| fsm.sidecar.image.tag | string | `"1.3.0"` | Sidecar image tag |
464+
| fsm.sidecar.image.tag | string | `"1.4.1"` | Sidecar image tag |
465465
| fsm.sidecar.sidecarDisabledMTLS | bool | `false` | Sidecar runs without mTLS |
466466
| fsm.sidecar.sidecarLogLevel | string | `"error"` | Log level for the proxy sidecar. Non developers should generally never set this value. In production environments the LogLevel should be set to `error` |
467467
| fsm.sidecar.sidecarTimeout | int | `60` | Sets connect/idle/read/write timeout |

charts/fsm/components/scripts.tar.gz

7.58 KB
Binary file not shown.

charts/fsm/components/scripts/gateways/config.json

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version": ""}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
export default function (config) {
2+
var $requestTime
3+
4+
var key = config.key
5+
var latencyThreshold = Number.parseFloat(config.circuitBreak.latencyThreshold)
6+
var errorCountThreshold = Number.parseInt(config.circuitBreak.errorCountThreshold)
7+
var errorRatioThreshold = Number.parseFloat(config.circuitBreak.errorRatioThreshold)
8+
var concurrencyThreshold = Number.parseInt(config.circuitBreak.concurrencyThreshold)
9+
var checkInterval = Number.parseFloat(config.circuitBreak.checkInterval) * 1000
10+
var breakInterval = Number.parseFloat(config.circuitBreak.breakInterval) * 1000
11+
12+
var response = new Message(
13+
{
14+
status: config.circuitBreak.response?.status || 503,
15+
headers: config.circuitBreak.response?.headers,
16+
},
17+
config.circuitBreak.response?.body || 'Service unavailable'
18+
)
19+
20+
var sharedStates = new algo.SharedMap(key)
21+
22+
sharedStates.set('start', 0)
23+
sharedStates.set('concurrency', 0)
24+
sharedStates.set('total', 0)
25+
sharedStates.set('error', 0)
26+
sharedStates.set('brokenBefore', 0)
27+
28+
function isBroken() {
29+
var brokenBefore = sharedStates.get('brokenBefore')
30+
return (brokenBefore && Date.now() < brokenBefore)
31+
}
32+
33+
function check() {
34+
var t = Date.now()
35+
var total = sharedStates.add('total', 1)
36+
if (t - $requestTime >= latencyThreshold) {
37+
var error = sharedStates.add('error', 1)
38+
} else {
39+
var error = sharedStates.get('error')
40+
}
41+
var concurrency = sharedStates.get('concurrency')
42+
if (
43+
total > 0 &&
44+
concurrency >= concurrencyThreshold &&
45+
error >= errorCountThreshold &&
46+
error / total >= errorRatioThreshold
47+
) {
48+
sharedStates.set('brokenBefore', t + breakInterval)
49+
sharedStates.set('start', 0)
50+
sharedStates.set('total', 0)
51+
sharedStates.set('error', 0)
52+
} else {
53+
var start = sharedStates.get('start')
54+
if (start && t - start >= checkInterval) {
55+
sharedStates.set('start', t)
56+
sharedStates.set('total', 0)
57+
sharedStates.set('error', 0)
58+
} else {
59+
sharedStates.set('start', t)
60+
}
61+
}
62+
}
63+
64+
return pipeline($=>$
65+
.pipe(
66+
evt => {
67+
if (evt instanceof MessageStart) {
68+
if (isBroken()) {
69+
return 'deny'
70+
} else {
71+
$requestTime = Date.now()
72+
sharedStates.add('concurrency', 1)
73+
return 'pass'
74+
}
75+
}
76+
}, {
77+
'pass': ($=>$
78+
.pipeNext()
79+
.handleMessageStart(
80+
() => {
81+
sharedStates.sub('concurrency', 1)
82+
check()
83+
}
84+
)
85+
),
86+
'deny': ($=>$
87+
.replaceData()
88+
.replaceMessage(response)
89+
)
90+
}
91+
)
92+
)
93+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
export default function (config) {
2+
var delayPercentage = config.faultInjection.delay?.percentage | 0
3+
var delayMin = config.faultInjection.delay?.min | 0
4+
var delayMax = config.faultInjection.delay?.max | 0
5+
var abortPercentage = config.faultInjection.abort?.percentage | 0
6+
7+
delayPercentage = Math.max(0, Math.min(100, delayPercentage))
8+
abortPercentage = Math.max(0, Math.min(100, abortPercentage))
9+
10+
var abortMessage = new Message(
11+
{
12+
status: config.faultInjection.abort?.response?.status || 503,
13+
headers: config.faultInjection.abort?.response?.headers,
14+
},
15+
config.faultInjection.abort?.response?.body || 'Service unavailable'
16+
)
17+
18+
var delayDispatcher = new algo.LoadBalancer([true, false], {
19+
weight: target => target ? delayPercentage : 100 - delayPercentage
20+
})
21+
22+
var abortDispatcher = new algo.LoadBalancer([true, false], {
23+
weight: target => target ? abortPercentage : 100 - abortPercentage
24+
})
25+
26+
return pipeline($=>$
27+
.handleMessageStart(
28+
() => {
29+
if (delayDispatcher.allocate().target) {
30+
return new Timeout((Math.random() * (delayMax - delayMin) + delayMin) / 1000).wait()
31+
}
32+
}
33+
)
34+
.pipe(() => abortDispatcher.allocate().target ? 'abort' : 'pass', {
35+
'abort': $=>$.replaceData().replaceMessage(abortMessage),
36+
'pass': $=>$.pipeNext()
37+
})
38+
)
39+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
export default function (config) {
2+
var c = config.httpLog
3+
var b = c.batch
4+
5+
var logger = new logging.JSONLogger(config.key).toHTTP(
6+
c.target, {
7+
method: c.method || 'POST',
8+
headers: c.headers,
9+
batch: b ? {
10+
size: b.size,
11+
timeout: 1,
12+
interval: b.interval || 1,
13+
prefix: b.prefix,
14+
postfix: b.postfix,
15+
separator: b.separator,
16+
} : null,
17+
bufferLimit: c.bufferLimit || 8*1024*1024,
18+
}
19+
)
20+
21+
var log = logger.log
22+
23+
var meshName = os.env.MESH_NAME || ''
24+
25+
var node = {
26+
ip: os.env.POD_IP || '127.0.0.1',
27+
name: os.env.HOSTNAME || 'localhost',
28+
}
29+
30+
var pod = {
31+
ns: os.env.POD_NAMESPACE || 'default',
32+
ip: os.env.POD_IP || '127.0.0.1',
33+
name: os.env.POD_NAME || os.env.HOSTNAME || 'localhost',
34+
}
35+
36+
var $ctx
37+
38+
return pipeline($=>$
39+
.onStart(c => { $ctx = c })
40+
.pipeNext()
41+
.handleMessageEnd(() => {
42+
var inbound = $ctx.parent.inbound
43+
var reqHead = $ctx.head
44+
var reqTail = $ctx.tail
45+
var headers = reqHead.headers
46+
var response = $ctx.response
47+
var resHead = response.head
48+
var resTail = response.tail
49+
log({
50+
type: 'fgw',
51+
meshName, node, pod,
52+
localAddr: inbound.localAddr,
53+
localPort: inbound.localPort,
54+
remoteAddr: inbound.remoteAddr,
55+
remotePort: inbound.remotePort,
56+
reqTime: $ctx.headTime,
57+
resTime: response.headTime,
58+
endTime: response.tailTime,
59+
req: {
60+
protocol: reqHead.protocol,
61+
scheme: reqHead.scheme,
62+
authority: reqHead.authority,
63+
method: reqHead.method,
64+
path: reqHead.path,
65+
headers: $ctx.head.headers,
66+
reqSize: reqTail.bodySize,
67+
},
68+
res: {
69+
protocol: resHead.protocol,
70+
status: resHead.status,
71+
statusText: resHead.statusText,
72+
resSize: resTail?.bodySize || 0,
73+
},
74+
backend: $ctx.backend?.name,
75+
target: $ctx.target,
76+
retries: $ctx.retries,
77+
trace: headers['x-b3-sampled'] === '1' ? {
78+
id: headers['x-b3-traceid'],
79+
span: headers['x-b3-spanid'],
80+
parent: headers['x-b3-parentspanid'],
81+
sampled: '1',
82+
} : null
83+
})
84+
})
85+
)
86+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
var PIPY_UUID = pipy.uuid || ''
2+
var PIPY_NAME = pipy.name || ''
3+
var PIPY_SOURCE = pipy.source || ''
4+
var K8S_CLUSTER = os.env.PIPY_K8S_CLUSTER || ''
5+
6+
var LATENCY_BUCKETS = [
7+
1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000,
8+
10000, 30000, 60000, 300000, 600000, 1800000, 3600000,
9+
Infinity
10+
]
11+
12+
var backends = new Set
13+
14+
var meta_info = new stats.Gauge('fgw_meta_info', ['uuid', 'name', 'codebase', 'cluster'])
15+
meta_info.withLabels(PIPY_UUID, PIPY_NAME, PIPY_SOURCE, K8S_CLUSTER).set(1)
16+
17+
var bandwidth = new stats.Counter('fgw_bandwidth', ['type', 'backend', 'target', 'route'])
18+
var bandwidth_ingress = bandwidth.withLabels('ingress')
19+
var bandwidth_egress = bandwidth.withLabels('egress')
20+
var backend_connection_total = new stats.Gauge('fgw_backend_connection_total', ['backend'])
21+
22+
var http_request_total = new stats.Counter('fgw_http_request_total')
23+
var http_status = new stats.Counter('fgw_http_status', ['backend', 'target', 'route', 'consumer', 'matched_host', 'matched_uri', 'code'])
24+
var http_latency = new stats.Histogram('fgw_http_latency', LATENCY_BUCKETS, ['backend', 'target', 'route', 'consumer', 'type'])
25+
26+
var http_retry = new stats.Counter('fgw_http_retry', ['backend'])
27+
var http_retry_success = new stats.Counter('fgw_http_retry_success', ['backend'])
28+
var http_retry_limit_exceeded = new stats.Counter('fgw_http_retry_limit_exceeded', ['backend'])
29+
var http_retry_backoff_exponential = new stats.Counter('fgw_http_retry_backoff_exponential', ['backend'])
30+
31+
export default function (config) {
32+
var sampleInterval = Number.parseFloat(config.metrics?.sampleInterval) || 5
33+
34+
function updateUpstreamStats() {
35+
new Timeout(sampleInterval).wait().then(() => {
36+
backends.forEach(be => {
37+
backend_connection_total.withLabels(be.name).set(be.concurrency)
38+
})
39+
updateUpstreamStats()
40+
})
41+
}
42+
43+
updateUpstreamStats()
44+
45+
var $ctx
46+
47+
return pipeline($=>$
48+
.onStart(c => { $ctx = c })
49+
.handleMessageStart(() => {
50+
http_request_total.increase()
51+
})
52+
.pipeNext()
53+
.handleMessageEnd(() => {
54+
var host = $ctx.host
55+
var backend = $ctx.backendResource?.metadata?.name
56+
var route = $ctx.routeResource.metadata?.name
57+
var target = $ctx.target
58+
var consumer = $ctx.consumer
59+
var response = $ctx.response
60+
var status = response.head?.status
61+
var ingress = $ctx.tail.headSize + $ctx.tail.bodySize
62+
var egress = response.tail ? response.tail.headSize + response.tail.bodySize : 0
63+
64+
http_status.withLabels(backend, target, route, consumer, host, $ctx.basePath, status).increase()
65+
var rx = bandwidth_ingress.withLabels(backend)
66+
rx.increase(ingress)
67+
rx.withLabels(target, route).increase(ingress)
68+
var tx = bandwidth_egress.withLabels(backend)
69+
tx.increase(egress)
70+
tx.withLabels(target, route).increase(egress)
71+
72+
var l = http_latency.withLabels(target, backend, route, consumer)
73+
l.withLabels('upstream').observe(response.headTime - $ctx.sendTime)
74+
l.withLabels('fgw').observe($ctx.sendTime - $ctx.headTime)
75+
l.withLabels('request').observe(Date.now() - $ctx.headTime)
76+
77+
var retries = $ctx.retries
78+
if (retries.length > 0) {
79+
http_retry.withLabels(backend).increase()
80+
if (retries[retries.length - 1].succeeded) {
81+
http_retry_success.withLabels(backend).increase()
82+
} else {
83+
http_retry_limit_exceeded.withLabels(backend).increase()
84+
}
85+
if (retries.length > 1) {
86+
http_retry_backoff_exponential.withLabels(backend).increase()
87+
}
88+
}
89+
if ($ctx.backend) {
90+
backends.add($ctx.backend)
91+
}
92+
})
93+
)
94+
}

0 commit comments

Comments
 (0)