Compare commits

...

716 Commits

Author SHA1 Message Date
Istio Automation 85c28434c3
Automator: update envoy@ in istio/proxy@master (#6402) 2025-07-10 19:03:33 -04:00
Istio Automation dd3d9baa45
Automator: update common-files@master in istio/proxy@master (#6398) 2025-07-10 07:18:33 -04:00
Istio Automation 28bd02a1b9
Automator: update envoy@ in istio/proxy@master (#6396) 2025-07-09 10:55:32 -04:00
Istio Automation 51074d7979
Automator: update envoy@ in istio/proxy@master (#6391) 2025-07-08 10:56:30 -04:00
Istio Automation 2cb036959c
Automator: update common-files@master in istio/proxy@master (#6389) 2025-07-08 05:50:31 -04:00
Istio Automation 3ae982ec4e
Automator: update envoy@ in istio/proxy@master (#6387) 2025-07-07 10:56:32 -04:00
Istio Automation fbe1167e87
Automator: update envoy@ in istio/proxy@master (#6383) 2025-07-06 10:57:28 -04:00
Istio Automation fba14d9f67
Automator: update go-control-plane in istio/proxy@master (#6382) 2025-07-05 22:13:27 -04:00
Istio Automation 38b94dff3e
Automator: update envoy@ in istio/proxy@master (#6381) 2025-07-05 10:58:27 -04:00
Istio Automation fb3df4ebd1
Automator: update envoy@ in istio/proxy@master (#6380) 2025-07-04 11:38:26 -04:00
Istio Automation 9ca562874b
Automator: update envoy@ in istio/proxy@master (#6379) 2025-07-03 11:56:25 -04:00
Istio Automation 884980ae61
Automator: update envoy@ in istio/proxy@master (#6378) 2025-07-02 10:58:25 -04:00
Istio Automation 715e9950d3
Automator: update envoy@ in istio/proxy@master (#6377) 2025-07-01 11:43:24 -04:00
Istio Automation 85878351b6
Automator: update common-files@master in istio/proxy@master (#6376) 2025-06-30 16:58:22 -04:00
Istio Automation b80b90e891
Automator: update envoy@ in istio/proxy@master (#6375) 2025-06-30 10:56:22 -04:00
Istio Automation a568c3561a
Automator: update envoy@ in istio/proxy@master (#6374) 2025-06-29 10:56:21 -04:00
Istio Automation b2f733524a
Automator: update go-control-plane in istio/proxy@master (#6373) 2025-06-28 22:13:20 -04:00
Istio Automation a04f0159fd
Automator: update envoy@ in istio/proxy@master (#6372) 2025-06-28 11:42:19 -04:00
Istio Automation 9414c10b56
Automator: update envoy@ in istio/proxy@master (#6371) 2025-06-27 10:55:20 -04:00
Istio Automation 8ffb10eef0
Automator: update envoy@ in istio/proxy@master (#6367) 2025-06-26 11:42:19 -04:00
Istio Automation 465dfe27b8
Automator: update common-files@master in istio/proxy@master (#6366) 2025-06-26 08:25:19 -04:00
Istio Automation eac6a8ea28
Automator: update envoy@ in istio/proxy@master (#6364) 2025-06-25 11:47:17 -04:00
Istio Automation c51abd662d
Automator: update envoy@ in istio/proxy@master (#6363) 2025-06-24 11:55:28 -04:00
Istio Automation 491c23b5b2
Automator: update envoy@ in istio/proxy@master (#6362) 2025-06-23 11:52:24 -04:00
Istio Automation 17926fc432
Automator: update envoy@ in istio/proxy@master (#6361) 2025-06-22 11:13:23 -04:00
Istio Automation 8243b8a544
Automator: update go-control-plane in istio/proxy@master (#6360) 2025-06-21 22:13:22 -04:00
Istio Automation 866870fac0
Automator: update envoy@ in istio/proxy@master (#6358) 2025-06-20 11:41:12 -04:00
Istio Automation 3a3d5c5eeb
Automator: update envoy@ in istio/proxy@master (#6357) 2025-06-19 11:39:09 -04:00
Istio Automation f1a368d5fe
Automator: update common-files@master in istio/proxy@master (#6356) 2025-06-19 10:07:09 -04:00
Istio Automation 1409b2e78f
Automator: update common-files@master in istio/proxy@master (#6355) 2025-06-18 14:36:09 -04:00
Istio Automation cbc8bcc988
Automator: update envoy@ in istio/proxy@master (#6354) 2025-06-18 10:58:59 -04:00
Istio Automation 3c9dbf2756
Automator: update envoy@ in istio/proxy@master (#6351) 2025-06-17 11:54:16 -04:00
Istio Automation aea95c7140
Automator: update envoy@ in istio/proxy@master (#6350) 2025-06-16 10:58:14 -04:00
Istio Automation 4e8d8ea338
Automator: update envoy@ in istio/proxy@master (#6348) 2025-06-15 11:04:14 -04:00
Istio Automation e477738647
Automator: update go-control-plane in istio/proxy@master (#6349) 2025-06-14 22:13:12 -04:00
Lior Lieberman 44e40b801e
add new override_host lb policy (#6347) 2025-06-13 14:29:27 -04:00
Istio Automation 72326c50df
Automator: update envoy@ in istio/proxy@master (#6346) 2025-06-13 10:55:27 -04:00
zirain 28c94ac20d
sync upstream (#6345)
* Automator: update envoy@ in istio/proxy@master

* fix build

Signed-off-by: zirain <zirain2009@gmail.com>

* fix

Signed-off-by: zirain <zirain2009@gmail.com>

* fix asan

Signed-off-by: zirain <zirain2009@gmail.com>

---------

Signed-off-by: zirain <zirain2009@gmail.com>
Co-authored-by: istio-testing <istio-testing-bot@google.com>
2025-06-13 00:08:27 -04:00
Istio Automation 7230983027
Automator: update envoy@ in istio/proxy@master (#6340) 2025-06-11 11:53:26 -04:00
Istio Automation 8fd34bd127
Automator: update envoy@ in istio/proxy@master (#6339) 2025-06-10 11:41:24 -04:00
Istio Automation 5f58981e6f
Automator: update envoy@ in istio/proxy@master (#6338) 2025-06-09 11:50:14 -04:00
zirain 0507e331dd
sync upstream (#6337)
* Automator: update envoy@ in istio/proxy@master

* sync envoy with upstream

Signed-off-by: zirain <zirain2009@gmail.com>

* nit

---------

Signed-off-by: zirain <zirain2009@gmail.com>
Co-authored-by: istio-testing <istio-testing-bot@google.com>
2025-06-09 07:43:14 -04:00
Istio Automation 16fad2b5d9
Automator: update common-files@master in istio/proxy@master (#6336) 2025-06-08 04:08:12 -04:00
Istio Automation 5d4727241d
Automator: update go-control-plane in istio/proxy@master (#6335) 2025-06-07 22:13:51 -04:00
Keith Mattix II 024957f198
Manual Update: update envoy@ in istio/proxy@master (#6333)
* Automator: update envoy@ in istio/proxy@master

* Correctly namespace the libc++ bazel option

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

---------

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
Co-authored-by: istio-testing <istio-testing-bot@google.com>
2025-06-06 20:28:52 -04:00
Istio Automation d023cdd5f0
Automator: update common-files@master in istio/proxy@master (#6331) 2025-06-06 10:27:54 -04:00
Istio Automation cb2c0289b1
Automator: update envoy@ in istio/proxy@master (#6329) 2025-06-05 11:08:51 -04:00
Istio Automation e5dc651d35
Automator: update common-files@master in istio/proxy@master (#6330) 2025-06-04 12:49:50 -04:00
Istio Automation 3941fec91b
Automator: update envoy@ in istio/proxy@master (#6328) 2025-06-02 10:53:40 -04:00
Istio Automation 1fae178953
Automator: update envoy@ in istio/proxy@master (#6327) 2025-06-01 10:53:39 -04:00
Istio Automation f3c11540b0
Automator: update go-control-plane in istio/proxy@master (#6326) 2025-05-31 22:12:38 -04:00
Istio Automation cfde121e25
Automator: update envoy@ in istio/proxy@master (#6325) 2025-05-31 11:51:38 -04:00
Istio Automation f7d8213fb6
Automator: update envoy@ in istio/proxy@master (#6324) 2025-05-30 11:08:37 -04:00
Istio Automation 68585389c4
Automator: update envoy@ in istio/proxy@master (#6322) 2025-05-29 11:53:36 -04:00
Istio Automation 1834fcc306
Automator: update envoy@ in istio/proxy@master (#6321) 2025-05-28 11:43:34 -04:00
Istio Automation aab89e829d
Automator: update envoy@ in istio/proxy@master (#6320) 2025-05-27 11:44:33 -04:00
Bruno Palermo 1b16ce6423
Include CPU utilization resource monitor (#6318) 2025-05-27 02:33:23 -04:00
Istio Automation 7b20907635
Automator: update envoy@ in istio/proxy@master (#6319) 2025-05-26 10:54:22 -04:00
Istio Automation 65c34ec654
Automator: update go-control-plane in istio/proxy@master (#6317) 2025-05-24 22:11:28 -04:00
Istio Automation 06e3ead9db
Automator: update envoy@ in istio/proxy@master (#6316) 2025-05-24 11:01:28 -04:00
Istio Automation 63942621de
Automator: update envoy@ in istio/proxy@master (#6315) 2025-05-23 11:28:24 -04:00
Istio Automation f3131949e4
Automator: update envoy@ in istio/proxy@master (#6314) 2025-05-22 11:08:23 -04:00
Istio Automation 87dd28dfaf
Automator: update common-files@master in istio/proxy@master (#6313) 2025-05-22 09:30:32 -04:00
Istio Automation 633531a5bc
Automator: update common-files@master in istio/proxy@master (#6312) 2025-05-22 04:41:32 -04:00
Istio Automation 85c932f655
Automator: update envoy@ in istio/proxy@master (#6311) 2025-05-21 11:59:25 -04:00
Istio Automation f0842aa465
Automator: update envoy@ in istio/proxy@master (#6310) 2025-05-20 11:09:25 -04:00
Istio Automation 0e1ff29aa8
Automator: update envoy@ in istio/proxy@master (#6309) 2025-05-19 10:53:24 -04:00
Istio Automation 8d28fdd081
Automator: update envoy@ in istio/proxy@master (#6308) 2025-05-18 11:40:23 -04:00
Istio Automation d12108e0db
Automator: update go-control-plane in istio/proxy@master (#6307) 2025-05-17 22:19:09 -04:00
zirain 9445f5937f
Sync with upstream (#6306)
* Automator: update envoy@ in istio/proxy@master

* fix build

Signed-off-by: zirain <zirain2009@gmail.com>

---------

Signed-off-by: zirain <zirain2009@gmail.com>
Co-authored-by: istio-testing <istio-testing-bot@google.com>
2025-05-17 22:06:09 -04:00
Istio Automation 1ca15b8ba6
Automator: update envoy@ in istio/proxy@master (#6304) 2025-05-16 11:53:10 -04:00
Istio Automation 6aaacdd054
Automator: update common-files@master in istio/proxy@master (#6303) 2025-05-15 14:31:14 -04:00
Istio Automation 1dbc6e9794
Automator: update envoy@ in istio/proxy@master (#6302) 2025-05-15 11:50:14 -04:00
Istio Automation 9064710ab4
Automator: update envoy@ in istio/proxy@master (#6301) 2025-05-14 11:41:32 -04:00
Istio Automation 2c605ad6f5
Automator: update common-files@master in istio/proxy@master (#6299) 2025-05-13 18:10:12 -04:00
Istio Automation 14537f0863
Automator: update envoy@ in istio/proxy@master (#6298) 2025-05-13 11:25:13 -04:00
Istio Automation e6d9841a4f
Automator: update envoy@ in istio/proxy@master (#6296) 2025-05-12 19:31:11 -04:00
Istio Automation 66388d0181
Automator: update envoy@ in istio/proxy@master (#6295) 2025-05-11 10:53:11 -04:00
Istio Automation 72630c019f
Automator: update go-control-plane in istio/proxy@master (#6294) 2025-05-10 22:12:46 -04:00
Istio Automation b52e33a823
Automator: update envoy@ in istio/proxy@master (#6293) 2025-05-10 10:56:47 -04:00
Istio Automation c5d3627199
Automator: update envoy@ in istio/proxy@master (#6289) 2025-05-09 11:31:45 -04:00
Istio Automation 5cecd24136
Automator: update common-files@master in istio/proxy@master (#6287) 2025-05-09 10:06:46 -04:00
Istio Automation c4fcc92e44
Automator: update common-files@master in istio/proxy@master (#6286) 2025-05-09 06:16:46 -04:00
Istio Automation 85d93e0013
Automator: update envoy@ in istio/proxy@master (#6285) 2025-05-08 10:57:47 -04:00
Istio Automation 44c82b7b9c
Automator: update common-files@master in istio/proxy@master (#6281) 2025-05-07 14:32:45 -04:00
Istio Automation 5df4291d78
Automator: update envoy@ in istio/proxy@master (#6280) 2025-05-07 10:56:45 -04:00
Istio Automation 9950dd1ee8
Automator: update envoy@ in istio/proxy@master (#6277) 2025-05-06 11:52:43 -04:00
Istio Automation 097f8c563c
Automator: update envoy@ in istio/proxy@master (#6274) 2025-05-05 11:34:44 -04:00
Istio Automation de9edf0b67
Automator: update go-control-plane in istio/proxy@master (#6273) 2025-05-03 22:12:40 -04:00
Istio Automation 43f7e312ff
Automator: update envoy@ in istio/proxy@master (#6272) 2025-05-03 11:56:40 -04:00
Istio Automation 1e6beeaa55
Automator: update envoy@ in istio/proxy@master (#6271) 2025-05-02 10:53:39 -04:00
Istio Automation 88df19ee23
Automator: update envoy@ in istio/proxy@master (#6270) 2025-05-01 11:31:38 -04:00
Istio Automation 7bafbf2268
Automator: update envoy@ in istio/proxy@master (#6269) 2025-05-01 01:15:37 -04:00
Istio Automation b17690c0e3
Automator: update envoy@ in istio/proxy@master (#6268) 2025-04-29 12:01:36 -04:00
Istio Automation 47efd7a031
Automator: update envoy@ in istio/proxy@master (#6267) 2025-04-28 12:24:56 -04:00
Istio Automation 4e48433cd0
Automator: update go-control-plane in istio/proxy@master (#6266) 2025-04-26 22:12:54 -04:00
Istio Automation 6d266652c8
Automator: update envoy@ in istio/proxy@master (#6265) 2025-04-26 11:46:53 -04:00
Istio Automation 9d176df1db
Automator: update envoy@ in istio/proxy@master (#6264) 2025-04-25 11:04:53 -04:00
Istio Automation 115b0eb036
Automator: update common-files@master in istio/proxy@master (#6263) 2025-04-25 04:08:03 -04:00
Kuat 216b9ef9fb
build: fix breakage in core proto rules (#6262)
Change-Id: I755ea813ecf6e0e76ac0e236fec501f0448ff9e3

Signed-off-by: Kuat Yessenov <kuat@google.com>
2025-04-24 18:42:02 -04:00
Istio Automation 4e641e0bb8
Automator: update common-files@master in istio/proxy@master (#6261) 2025-04-24 16:32:02 -04:00
Istio Automation 4ba4edc9e6
Automator: update envoy@ in istio/proxy@master (#6260) 2025-04-24 11:49:55 -04:00
Istio Automation e6e2ed4f4f
Automator: update envoy@ in istio/proxy@master (#6259) 2025-04-23 11:51:53 -04:00
zirain 514a644781
Sync envoy (#6257)
* Automator: update envoy@ in istio/proxy@master

* sync envoy

---------

Co-authored-by: istio-testing <istio-testing-bot@google.com>
2025-04-22 20:08:52 -04:00
Istio Automation e0fd35acbd
Automator: update envoy@ in istio/proxy@master (#6255) 2025-04-21 10:52:27 -04:00
Istio Automation a8dc181482
Automator: update envoy@ in istio/proxy@master (#6254) 2025-04-20 10:51:27 -04:00
Istio Automation d36a211276
Automator: update go-control-plane in istio/proxy@master (#6253) 2025-04-19 22:12:27 -04:00
Istio Automation 5a62959ebf
Automator: update envoy@ in istio/proxy@master (#6252) 2025-04-19 10:59:26 -04:00
Istio Automation b0d4ae0c83
Automator: update envoy@ in istio/proxy@master (#6250) 2025-04-18 11:34:25 -04:00
Istio Automation b6258b5d41
Automator: update envoy@ in istio/proxy@master (#6244) 2025-04-17 10:51:24 -04:00
dependabot[bot] a16c86c7b2
Bump golang.org/x/net from 0.36.0 to 0.38.0 (#6242)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.36.0 to 0.38.0.
- [Commits](https://github.com/golang/net/compare/v0.36.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.38.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-16 19:33:22 -04:00
Istio Automation ebe9ed11ed
Automator: update envoy@ in istio/proxy@master (#6241) 2025-04-16 11:54:23 -04:00
Istio Automation c00934a851
Automator: update envoy@ in istio/proxy@master (#6239) 2025-04-15 11:41:23 -04:00
Istio Automation 8358a38f0a
Automator: update envoy@ in istio/proxy@master (#6238) 2025-04-14 11:55:22 -04:00
Istio Automation e2782afa20
Automator: update go-control-plane in istio/proxy@master (#6237) 2025-04-12 22:12:18 -04:00
Istio Automation e7a3438021
Automator: update envoy@ in istio/proxy@master (#6236) 2025-04-12 11:06:18 -04:00
Istio Automation c271a2a361
Automator: update envoy@ in istio/proxy@master (#6235) 2025-04-11 12:08:18 -04:00
zirain aca940e1ae
chore: find failed on mac (#6228) 2025-04-10 12:45:18 -04:00
Istio Automation f5f75fccad
Automator: update envoy@ in istio/proxy@master (#6230) 2025-04-10 11:49:17 -04:00
Istio Automation 43e7bea767
Automator: update common-files@master in istio/proxy@master (#6229) 2025-04-10 08:42:17 -04:00
Istio Automation e211657be9
Automator: update common-files@master in istio/proxy@master (#6227) 2025-04-10 08:06:18 -04:00
Istio Automation b25f1c6363
Automator: update envoy@ in istio/proxy@master (#6224) 2025-04-09 11:43:16 -04:00
Istio Automation 4a2d8f7541
Automator: update common-files@master in istio/proxy@master (#6223) 2025-04-09 09:26:15 -04:00
Istio Automation 405c75a8fd
Automator: update envoy@ in istio/proxy@master (#6222) 2025-04-08 11:49:14 -04:00
Istio Automation a096eab649
Automator: update envoy@ in istio/proxy@master (#6221) 2025-04-07 11:00:52 -04:00
Istio Automation 29a1faa60c
Automator: update envoy@ in istio/proxy@master (#6220) 2025-04-06 10:52:49 -04:00
Istio Automation 350f6d5c01
Automator: update go-control-plane in istio/proxy@master (#6219) 2025-04-05 22:12:49 -04:00
Istio Automation f3d9265744
Automator: update envoy@ in istio/proxy@master (#6218) 2025-04-05 10:51:48 -04:00
Istio Automation b2f49ea7c0
Automator: update envoy@ in istio/proxy@master (#6217) 2025-04-04 10:52:48 -04:00
Istio Automation 832185f524
Automator: update envoy@ in istio/proxy@master (#6216) 2025-04-03 11:41:47 -04:00
Istio Automation 52cd9c1e00
Automator: update envoy@ in istio/proxy@master (#6215) 2025-04-02 11:57:48 -04:00
Istio Automation 0708949e77
Automator: update envoy@ in istio/proxy@master (#6205) 2025-04-01 11:01:46 -04:00
Istio Automation 187ef6426b
Automator: update common-files@master in istio/proxy@master (#6213) 2025-04-01 03:18:46 -04:00
Istio Automation 8572e6de6a
Automator: update common-files@master in istio/proxy@master (#6212) 2025-03-31 15:13:45 -04:00
Istio Automation 2240686201
Automator: update go-control-plane in istio/proxy@master (#6211) 2025-03-29 22:10:43 -04:00
Istio Automation 12c92748ed
Automator: update common-files@master in istio/proxy@master (#6206) 2025-03-26 12:59:49 -04:00
Istio Automation 147cc9af7b
Automator: update envoy@ in istio/proxy@master (#6201) 2025-03-25 10:59:51 -04:00
Istio Automation dfae03070b
Automator: update envoy@ in istio/proxy@master (#6196) 2025-03-24 10:51:48 -04:00
Istio Automation a757555db3
Automator: update go-control-plane in istio/proxy@master (#6195) 2025-03-22 22:11:44 -04:00
Istio Automation e80703132d
Automator: update envoy@ in istio/proxy@master (#6194) 2025-03-22 11:24:44 -04:00
Istio Automation 4b4991300c
Automator: update envoy@ in istio/proxy@master (#6189) 2025-03-21 11:46:45 -04:00
Istio Automation 2d9c9eb1da
Automator: update envoy@ in istio/proxy@master (#6185) 2025-03-20 11:29:43 -04:00
Istio Automation f08201e7c7
Automator: update envoy@ in istio/proxy@master (#6184) 2025-03-19 11:55:40 -04:00
Istio Automation b3920fcf56
Automator: update envoy@ in istio/proxy@master (#6183) 2025-03-18 11:37:41 -04:00
Istio Automation 7152aa80e7
Automator: update common-files@master in istio/proxy@master (#6182) 2025-03-17 12:31:15 -04:00
Istio Automation 854c889f4c
Automator: update envoy@ in istio/proxy@master (#6181) 2025-03-17 10:52:37 -04:00
Istio Automation 1aa0851ed5
Automator: update envoy@ in istio/proxy@master (#6180) 2025-03-16 10:52:30 -04:00
Istio Automation 9963cb6e79
Automator: update go-control-plane in istio/proxy@master (#6179) 2025-03-15 22:11:31 -04:00
Istio Automation 7e21bf29d9
Automator: update envoy@ in istio/proxy@master (#6178) 2025-03-15 11:35:29 -04:00
Istio Automation dc8bf846a0
Automator: update envoy@ in istio/proxy@master (#6177) 2025-03-14 11:31:55 -04:00
zirain a3b20fbf0d
chore: bump go to 1.24 (#6175) 2025-03-13 20:44:54 -04:00
Istio Automation b1a30a228b
Automator: update envoy@ in istio/proxy@master (#6176) 2025-03-13 11:47:57 -04:00
dependabot[bot] 630838deca
Bump golang.org/x/net from 0.34.0 to 0.36.0 (#6173)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.34.0 to 0.36.0.
- [Commits](https://github.com/golang/net/compare/v0.34.0...v0.36.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-13 06:39:54 -04:00
Istio Automation bbdabac40a
Automator: update envoy@ in istio/proxy@master (#6172) 2025-03-12 11:49:08 -04:00
Istio Automation 09b8e0419e
Automator: update common-files@master in istio/proxy@master (#6171) 2025-03-11 16:11:07 -04:00
Istio Automation 285284dcd8
Automator: update envoy@ in istio/proxy@master (#6170) 2025-03-11 11:49:06 -04:00
Istio Automation 00ca866cb9
Automator: update common-files@master in istio/proxy@master (#6169) 2025-03-10 13:08:08 -04:00
Istio Automation ea517cadc8
Automator: update go-control-plane in istio/proxy@master (#6168) 2025-03-08 21:12:03 -05:00
Istio Automation 0954debc61
Automator: update envoy@ in istio/proxy@master (#6167) 2025-03-08 10:30:03 -05:00
zirain 72a567fb4c
update envoy (#6166)
* Automator: update envoy@ in istio/proxy@master

* fix

---------

Co-authored-by: istio-testing <istio-testing-bot@google.com>
2025-03-07 22:39:03 -05:00
Istio Automation c81d1c7910
Automator: update common-files@master in istio/proxy@master (#6162) 2025-03-06 03:56:01 -05:00
Istio Automation c299ef8332
Automator: update envoy@ in istio/proxy@master (#6160) 2025-03-04 10:42:59 -05:00
Istio Automation 0e24cfb9ec
Automator: update go-control-plane in istio/proxy@master (#6159) 2025-03-01 21:11:48 -05:00
Istio Automation ddc87ca613
Automator: update envoy@ in istio/proxy@master (#6158) 2025-03-01 10:43:49 -05:00
Istio Automation 70d182b019
Automator: update envoy@ in istio/proxy@master (#6157) 2025-02-28 09:56:30 -05:00
Istio Automation 44133ea459
Automator: update common-files@master in istio/proxy@master (#6156) 2025-02-27 12:25:30 -05:00
Istio Automation d72a525881
Automator: update envoy@ in istio/proxy@master (#6155) 2025-02-27 10:29:30 -05:00
Istio Automation 7bce06d301
Automator: update common-files@master in istio/proxy@master (#6154) 2025-02-26 14:18:29 -05:00
Istio Automation 9dacc003f0
Automator: update envoy@ in istio/proxy@master (#6153) 2025-02-26 10:34:29 -05:00
Istio Automation ad794e899c
Automator: update envoy@ in istio/proxy@master (#6152) 2025-02-25 09:52:27 -05:00
Istio Automation e6b4dc405b
Automator: update common-files@master in istio/proxy@master (#6151) 2025-02-24 14:32:28 -05:00
Istio Automation b9c8138326
Automator: update envoy@ in istio/proxy@master (#6150) 2025-02-24 09:48:55 -05:00
Istio Automation 5d5edd4817
Automator: update envoy@ in istio/proxy@master (#6149) 2025-02-23 10:01:54 -05:00
Istio Automation f777f1f75f
Automator: update go-control-plane in istio/proxy@master (#6148) 2025-02-22 21:10:53 -05:00
Istio Automation dd13c6784a
Automator: update envoy@ in istio/proxy@master (#6147) 2025-02-22 10:33:53 -05:00
Istio Automation 3944d5c584
Automator: update envoy@ in istio/proxy@master (#6145) 2025-02-21 10:34:52 -05:00
Istio Automation 12794c7725
Automator: update envoy@ in istio/proxy@master (#6144) 2025-02-20 10:49:52 -05:00
Istio Automation 450bbc9559
Automator: update envoy@ in istio/proxy@master (#6142) 2025-02-19 09:49:51 -05:00
Istio Automation d5285a06d5
Automator: update common-files@master in istio/proxy@master (#6140) 2025-02-18 13:56:49 -05:00
Istio Automation b2eb9e6de2
Automator: update envoy@ in istio/proxy@master (#6139) 2025-02-18 09:47:49 -05:00
Istio Automation 87f21076d0
Automator: update envoy@ in istio/proxy@master (#6137) 2025-02-17 09:46:49 -05:00
Istio Automation 5dd1d365e4
Automator: update envoy@ in istio/proxy@master (#6133) 2025-02-16 09:47:47 -05:00
Istio Automation 09bbb30113
Automator: update go-control-plane in istio/proxy@master (#6131) 2025-02-15 21:10:47 -05:00
Istio Automation 3300cfebf5
Automator: update envoy@ in istio/proxy@master (#6130) 2025-02-15 09:48:46 -05:00
Istio Automation 277287076f
Automator: update envoy@ in istio/proxy@master (#6128) 2025-02-14 09:51:46 -05:00
Istio Automation 3ee8889e31
Automator: update common-files@master in istio/proxy@master (#6126) 2025-02-13 16:35:45 -05:00
Istio Automation 9d289678ba
Automator: update envoy@ in istio/proxy@master (#6125) 2025-02-13 09:48:45 -05:00
Istio Automation 2c1a278182
Automator: update envoy@ in istio/proxy@master (#6123) 2025-02-12 09:48:44 -05:00
Istio Automation ad2deb3f81
Automator: update envoy@ in istio/proxy@master (#6120) 2025-02-11 10:49:43 -05:00
Keith Mattix II 9ca2524d6c
Add null check to log message (#6117)
Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
2025-02-10 19:45:43 -05:00
Istio Automation cfdde45e96
Automator: update common-files@master in istio/proxy@master (#6118) 2025-02-10 17:14:43 -05:00
Istio Automation 089e781c2e
Automator: update envoy@ in istio/proxy@master (#6115) 2025-02-10 10:49:33 -05:00
Istio Automation 526aeb10d3
Automator: update go-control-plane in istio/proxy@master (#6113) 2025-02-08 21:10:29 -05:00
Istio Automation a9f18ad30a
Automator: update envoy@ in istio/proxy@master (#6112) 2025-02-08 09:48:29 -05:00
Istio Automation 896077d9f4
Automator: update envoy@ in istio/proxy@master (#6110) 2025-02-07 10:40:50 -05:00
zirain 0e5ee833b5
address comments (#6109) 2025-02-07 00:47:49 -05:00
Istio Automation f7cc614dc1
Automator: update envoy@ in istio/proxy@master (#6108) 2025-02-06 10:34:48 -05:00
zirain e425bfecd5
reenable cryptomb (#6107)
* reenable cryptomb

* try 7.4

* debug

* revert

* retry

Signed-off-by: zirain <zirain2009@gmail.com>

---------

Signed-off-by: zirain <zirain2009@gmail.com>
2025-02-06 08:45:49 -05:00
Istio Automation 519448b6d8
Automator: update envoy@ in istio/proxy@master (#6106) 2025-02-05 10:38:26 -05:00
zirain b1237fd9f2
update envoy and fix build (#6105)
* Automator: update envoy@ in istio/proxy@master

* fix quic build

* disabled cryptomb

---------

Co-authored-by: istio-testing <istio-testing-bot@google.com>
2025-02-05 07:03:26 -05:00
Istio Automation 1dc69a1c9e
Automator: update common-files@master in istio/proxy@master (#6104) 2025-02-03 20:19:24 -05:00
Istio Automation 43adfed2e0
Automator: update common-files@master in istio/proxy@master (#6103) 2025-02-03 16:59:13 -05:00
Istio Automation f3b3ab2f73
Automator: update go-control-plane in istio/proxy@master (#6102) 2025-02-01 21:11:47 -05:00
John Howard 068793d292
mx: allow disabling unconditionally (#6101)
For https://github.com/istio/istio/issues/54913, see PR for context
2025-01-30 16:59:52 -05:00
Istio Automation a895327df8
Automator: update go-control-plane in istio/proxy@master (#6098) 2025-01-25 21:12:46 -05:00
Istio Automation cbd898add0
Automator: update common-files@master in istio/proxy@master (#6093) 2025-01-24 04:19:01 -05:00
Istio Automation 6b493c7aca
Automator: update common-files@master in istio/proxy@master (#6091) 2025-01-22 14:21:58 -05:00
Istio Automation 549d3bbb86
Automator: update common-files@master in istio/proxy@master (#6090) 2025-01-22 12:20:58 -05:00
Istio Automation ce668311b7
Automator: update envoy@ in istio/proxy@master (#6089) 2025-01-22 10:48:58 -05:00
Istio Automation 35e62e2c29
Automator: update common-files@master in istio/proxy@master (#6088) 2025-01-21 19:54:56 -05:00
Istio Automation c138703eee
Automator: update envoy@ in istio/proxy@master (#6087) 2025-01-21 09:53:57 -05:00
Istio Automation 91b5e5d46a
Automator: update common-files@master in istio/proxy@master (#6086) 2025-01-20 14:25:56 -05:00
Nikhilesh 96bb942e84
bazel RLQS config extension (#6084)
* RLQS config extension

* RLQS config extension order correction
2025-01-20 01:00:55 -05:00
Istio Automation 04b6075e14
Automator: update envoy@ in istio/proxy@master (#6083) 2025-01-19 09:47:55 -05:00
Istio Automation 4100b590bb
Automator: update go-control-plane in istio/proxy@master (#6080) 2025-01-18 21:10:55 -05:00
Istio Automation 30bf0d6a46
Automator: update envoy@ in istio/proxy@master (#6079) 2025-01-18 09:47:55 -05:00
Istio Automation 1db3ffd955
Automator: update envoy@ in istio/proxy@master (#6078) 2025-01-17 10:41:55 -05:00
John Howard 0c0386455b
Disable spammy logs in release (#6066)
* Disable spammy logs in release

The `debug` flag does not impact the result of the build, but it does turn on ~every logging option in bazel resulting in 200k lines of logs each run

* Update scripts/release-binary.sh

Co-authored-by: Keith Mattix II <keithmattix@microsoft.com>

---------

Co-authored-by: Keith Mattix II <keithmattix@microsoft.com>
2025-01-16 15:35:55 -05:00
Istio Automation 6b385ab792
Automator: update common-files@master in istio/proxy@master (#6077) 2025-01-16 11:40:54 -05:00
Istio Automation 84caaba23a
Automator: update envoy@ in istio/proxy@master (#6074) 2025-01-16 10:28:54 -05:00
Istio Automation 0471d24373
Automator: update common-files@master in istio/proxy@master (#6073) 2025-01-15 16:59:53 -05:00
Keith Mattix II 6b837d5dd8
Add metadata fallback for client sidecar reporters (#6028)
* Add metadata fallback for client sidecar reporters

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Move logic

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Add test

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Fix compiler error

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Fixup

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Fix ownership bug

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Don't use string_view because of scope

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

---------

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
2025-01-15 12:57:53 -05:00
zirain 1ebefd0ea0
chore: enable dependabot (#6071) 2025-01-15 12:43:53 -05:00
John Howard 0cc7022f53
Drop protoc docs generation (#6070)
This is not used anywhere. The make target also doesn't work (due to
stackdriver removal) and no one complained which suggests no one has ran
it for a long time
2025-01-15 10:55:53 -05:00
Istio Automation 081e87a37b
Automator: update envoy@ in istio/proxy@master (#6072) 2025-01-15 10:30:53 -05:00
Zuzana Miklánková 4003e06aa8
bump golang.org/x/net to v0.33.0 (#6067)
To address CVE-2024-45338.
Istio-proxy itself is not affected, the library is only used in tests.

Signed-off-by: Zuzana Miklankova <zmiklank@redhat.com>
2025-01-15 07:11:53 -05:00
John Howard cd9f9e69b7
Fixes for waypoint stat generation (#6068)
* Fixes for waypoint stat generation

* test fixes
2025-01-14 14:34:51 -05:00
Istio Automation 2b17fbbead
Automator: update envoy@ in istio/proxy@master (#6065) 2025-01-14 10:44:52 -05:00
Istio Automation 8f1a4189e8
Automator: update envoy@ in istio/proxy@master (#6064) 2025-01-13 10:44:47 -05:00
Istio Automation b8cc914c8f
Automator: update go-control-plane in istio/proxy@master (#6063) 2025-01-11 21:10:44 -05:00
Istio Automation 0149de9855
Automator: update envoy@ in istio/proxy@master (#6062) 2025-01-11 09:49:44 -05:00
Istio Automation 8948e13f48
Automator: update envoy@ in istio/proxy@master (#6061) 2025-01-10 10:34:04 -05:00
Istio Automation bf2163d9eb
Automator: update envoy@ in istio/proxy@master (#6059) 2025-01-09 09:54:03 -05:00
Istio Automation a83a8b718a
Automator: update common-files@master in istio/proxy@master (#6058) 2025-01-08 16:38:02 -05:00
Istio Automation e12e71e769
Automator: update envoy@ in istio/proxy@master (#6057) 2025-01-08 10:40:01 -05:00
Istio Automation 4bdf258a3f
Automator: update common-files@master in istio/proxy@master (#6056) 2025-01-07 17:44:01 -05:00
Istio Automation 7c1428643f
Automator: update common-files@master in istio/proxy@master (#6055) 2025-01-07 16:03:01 -05:00
Istio Automation 56b4d5caec
Automator: update envoy@ in istio/proxy@master (#6053) 2025-01-07 10:56:02 -05:00
Istio Automation bf82f0c322
Automator: update common-files@master in istio/proxy@master (#6054) 2025-01-07 10:08:02 -05:00
Istio Automation a5f9c4e06f
Automator: update envoy@ in istio/proxy@master (#6052) 2025-01-06 10:39:00 -05:00
Istio Automation 8e4c54e6d2
Automator: update go-control-plane in istio/proxy@master (#6051) 2025-01-04 21:11:58 -05:00
Istio Automation 5cef8c326e
Automator: update envoy@ in istio/proxy@master (#6050) 2025-01-04 10:44:57 -05:00
Istio Automation c98bc5b067
Automator: update common-files@master in istio/proxy@master (#6049) 2025-01-03 18:59:58 -05:00
Istio Automation 9385ad46e7
Automator: update common-files@master in istio/proxy@master (#6048) 2025-01-03 16:41:57 -05:00
zirain afcfa7519c
bump bazel (#6023)
* bump bazel to 7.1.2

* bump to 7.2.0

* revert

* bump to 7.4.1

* sync with upstream
2025-01-03 16:02:57 -05:00
zirain 2821208112
MX support additional labels (#6030)
* support additional labels

Signed-off-by: zirain <zirain2009@gmail.com>

* add test

* update

* TCP MX

* update

* fix

---------

Signed-off-by: zirain <zirain2009@gmail.com>
2025-01-03 14:33:57 -05:00
Istio Automation 75315e65c5
Automator: update envoy@ in istio/proxy@master (#6046) 2025-01-03 10:32:56 -05:00
Istio Automation 777579cc6f
Automator: update common-files@master in istio/proxy@master (#6044) 2025-01-02 17:28:56 -05:00
Istio Automation 584d399c25
Automator: update common-files@master in istio/proxy@master (#6043) 2025-01-02 16:02:56 -05:00
Istio Automation cfbefc9cb1
Automator: update common-files@master in istio/proxy@master (#6042) 2025-01-02 11:41:55 -05:00
Istio Automation b0f5c6e40e
Automator: update envoy@ in istio/proxy@master (#6041) 2025-01-02 11:05:56 -05:00
Istio Automation 2070827719
Automator: update envoy@ in istio/proxy@master (#6038) 2025-01-01 10:35:55 -05:00
Istio Automation 911737b96b
Automator: update common-files@master in istio/proxy@master (#6034) 2024-12-30 17:53:53 -05:00
Istio Automation 1e9d92a616
Automator: update envoy@ in istio/proxy@master (#6033) 2024-12-30 09:45:52 -05:00
Keith Mattix II 1450780f36
format (#5968) 2024-12-29 22:07:52 -05:00
Istio Automation 289151ac12
Automator: update envoy@ in istio/proxy@master (#6032) 2024-12-29 09:46:51 -05:00
Istio Automation 5e3d334582
Automator: update go-control-plane in istio/proxy@master (#6031) 2024-12-28 21:13:50 -05:00
Istio Automation 93aad69a6c
Automator: update envoy@ in istio/proxy@master (#6029) 2024-12-28 09:45:50 -05:00
Keith Mattix II 5d72fdac48
Make lint and update docs (#6027)
Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
2024-12-26 19:56:49 -05:00
Istio Automation 5280e55dac
Automator: update envoy@ in istio/proxy@master (#6026) 2024-12-25 10:32:47 -05:00
Istio Automation cf1ff87ebb
Automator: update envoy@ in istio/proxy@master (#6025) 2024-12-24 20:47:47 -05:00
Istio Automation 871d23e6bd
Automator: update envoy@ in istio/proxy@master (#6024) 2024-12-23 09:47:46 -05:00
Istio Automation 73396379b4
Automator: update envoy@ in istio/proxy@master (#6022) 2024-12-22 09:45:45 -05:00
zirain 6d5d324009
update envoy and fix build (#6020) 2024-12-22 08:17:45 -05:00
Istio Automation 5f336d92df
Automator: update go-control-plane in istio/proxy@master (#6021) 2024-12-21 21:17:16 -05:00
Istio Automation 2e561cd539
Automator: update envoy@ in istio/proxy@master (#6016) 2024-12-19 10:47:11 -05:00
Istio Automation 33e229a1a4
Automator: update envoy@ in istio/proxy@master (#6010) 2024-12-18 11:08:32 -05:00
Istio Automation bc9a03cd86
Automator: update envoy@ in istio/proxy@master (#6008) 2024-12-17 21:25:00 -05:00
Istio Automation 61f031f010
Automator: update common-files@master in istio/proxy@master (#6009) 2024-12-17 13:21:00 -05:00
Istio Automation 2d0b426070
Automator: update common-files@master in istio/proxy@master (#6007) 2024-12-16 16:38:26 -05:00
Istio Automation 131fb41236
Automator: update common-files@master in istio/proxy@master (#6006) 2024-12-16 13:46:26 -05:00
John Howard dff3c5eaea
Cleanup deadcode from stackdriver tests (#6004) 2024-12-16 12:57:28 -05:00
Istio Automation 70049a6c89
Automator: update envoy@ in istio/proxy@master (#6005) 2024-12-16 09:46:16 -05:00
Istio Automation c5df3135b4
Automator: update go-control-plane in istio/proxy@master (#6003) 2024-12-14 21:12:42 -05:00
Istio Automation cee476c96f
Automator: update envoy@ in istio/proxy@master (#6002) 2024-12-14 10:32:43 -05:00
Keith Mattix II 9b5152057e
Add compdb script (#5963)
* Add compdb script:

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Add license

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Fix shebang

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

---------

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
2024-12-14 04:07:03 -05:00
Istio Automation 608d683460
Automator: update common-files@master in istio/proxy@master (#6000) 2024-12-13 12:05:03 -05:00
Istio Automation b175ff3c4e
Automator: update envoy@ in istio/proxy@master (#5999) 2024-12-13 10:33:03 -05:00
Istio Automation 21aa6a5fa1
Automator: update envoy@ in istio/proxy@master (#5998) 2024-12-12 09:53:02 -05:00
Istio Automation e17dfe800f
Automator: update envoy@ in istio/proxy@master (#5997) 2024-12-11 10:36:49 -05:00
Istio Automation da3f3f8122
Automator: update envoy@ in istio/proxy@master (#5996) 2024-12-10 11:05:38 -05:00
Istio Automation 493c490cbf
Automator: update common-files@master in istio/proxy@master (#5995) 2024-12-10 05:43:39 -05:00
Istio Automation 6ef4d417d0
Automator: update envoy@ in istio/proxy@master (#5989) 2024-12-09 09:48:38 -05:00
Istio Automation 803f9a71ee
Automator: update common-files@master in istio/proxy@master (#5991) 2024-12-09 02:01:14 -05:00
Istio Automation bbbf5dc561
Automator: update go-control-plane in istio/proxy@master (#5988) 2024-12-07 21:13:08 -05:00
Istio Automation 8fc6b12b4d
Automator: update envoy@ in istio/proxy@master (#5987) 2024-12-07 09:50:08 -05:00
Istio Automation 4c198c0739
Automator: update common-files@master in istio/proxy@master (#5986) 2024-12-06 17:54:07 -05:00
Istio Automation 5f80bc103d
Automator: update common-files@master in istio/proxy@master (#5984) 2024-12-06 10:26:09 -05:00
Istio Automation c834fac2f6
Automator: update envoy@ in istio/proxy@master (#5982) 2024-12-06 10:02:08 -05:00
Istio Automation 7f6e22aa5b
Automator: update envoy@ in istio/proxy@master (#5980) 2024-12-05 10:49:06 -05:00
Istio Automation 196be6aab9
Automator: update envoy@ in istio/proxy@master (#5978) 2024-12-04 09:58:37 -05:00
Istio Automation 879300a40c
Automator: update common-files@master in istio/proxy@master (#5977) 2024-12-03 19:43:21 -05:00
Istio Automation ff43dec5cd
Automator: update envoy@ in istio/proxy@master (#5974) 2024-12-03 10:43:37 -05:00
Istio Automation 01b8fd5b11
Automator: update common-files@master in istio/proxy@master (#5972) 2024-12-02 12:55:36 -05:00
Istio Automation e4fafdc06a
Automator: update envoy@ in istio/proxy@master (#5971) 2024-12-02 10:27:35 -05:00
Istio Automation 8164fd671b
Automator: update envoy@ in istio/proxy@master (#5970) 2024-12-01 09:44:34 -05:00
Istio Automation 94437650db
Automator: update go-control-plane in istio/proxy@master (#5969) 2024-11-30 21:12:34 -05:00
Istio Automation f5fb004f30
Automator: update envoy@ in istio/proxy@master (#5967) 2024-11-30 09:43:33 -05:00
Istio Automation 7725c1c986
Automator: update envoy@ in istio/proxy@master (#5966) 2024-11-29 09:43:32 -05:00
Istio Automation 225979a62a
Automator: update envoy@ in istio/proxy@master (#5964) 2024-11-28 10:32:31 -05:00
Istio Automation 04ba57ef85
Automator: update envoy@ in istio/proxy@master (#5962) 2024-11-27 10:26:30 -05:00
Istio Automation ff0b57fc20
Automator: update envoy@ in istio/proxy@master (#5958) 2024-11-26 10:48:49 -05:00
Istio Automation 1320648113
Automator: update envoy@ in istio/proxy@master (#5956) 2024-11-25 09:43:54 -05:00
Istio Automation 491e261847
Automator: update envoy@ in istio/proxy@master (#5955) 2024-11-24 09:43:17 -05:00
Istio Automation 31b603f46e
Automator: update go-control-plane in istio/proxy@master (#5954) 2024-11-23 21:12:17 -05:00
Istio Automation f6e8766f0b
Automator: update envoy@ in istio/proxy@master (#5953) 2024-11-23 10:34:16 -05:00
Istio Automation 99c27a9bb0
Automator: update common-files@master in istio/proxy@master (#5952) 2024-11-22 16:14:16 -05:00
Istio Automation a2fc3f7a78
Automator: update envoy@ in istio/proxy@master (#5951) 2024-11-22 10:39:16 -05:00
Istio Automation f30adb60de
Automator: update envoy@ in istio/proxy@master (#5947) 2024-11-21 10:42:42 -05:00
Istio Automation 7f4961784f
Automator: update envoy@ in istio/proxy@master (#5943) 2024-11-20 10:39:59 -05:00
Istio Automation ea251d9027
Automator: update envoy@ in istio/proxy@master (#5940) 2024-11-19 10:39:59 -05:00
Istio Automation 42ab5848de
Automator: update envoy@ in istio/proxy@master (#5938) 2024-11-18 09:46:57 -05:00
Istio Automation 5800040e3a
Automator: update go-control-plane in istio/proxy@master (#5937) 2024-11-16 21:12:54 -05:00
Istio Automation ec7c4d555e
Automator: update envoy@ in istio/proxy@master (#5936) 2024-11-16 10:03:54 -05:00
Istio Automation 1ceb165669
Automator: update envoy@ in istio/proxy@master (#5935) 2024-11-15 10:41:35 -05:00
Istio Automation ebc43dd8e8
Automator: update envoy@ in istio/proxy@master (#5934) 2024-11-14 11:02:34 -05:00
Istio Automation c8bfbf6439
Automator: update envoy@ in istio/proxy@master (#5933) 2024-11-13 10:43:33 -05:00
Istio Automation 698faa778c
Automator: update envoy@ in istio/proxy@master (#5931) 2024-11-12 10:44:32 -05:00
Istio Automation e498583f62
Automator: update envoy@ in istio/proxy@master (#5930) 2024-11-11 09:43:31 -05:00
Istio Automation daadd7371a
Automator: update envoy@ in istio/proxy@master (#5929) 2024-11-10 09:43:03 -05:00
Istio Automation fdb55fe680
Automator: update go-control-plane in istio/proxy@master (#5928) 2024-11-09 21:13:02 -05:00
Istio Automation 450b33ddf3
Automator: update envoy@ in istio/proxy@master (#5927) 2024-11-09 10:45:01 -05:00
Istio Automation f124d0e092
Automator: update envoy@ in istio/proxy@master (#5925) 2024-11-08 09:45:00 -05:00
Istio Automation ba8893c737
Automator: update common-files@master in istio/proxy@master (#5924) 2024-11-07 14:48:26 -05:00
Istio Automation 4a4f8885dd
Automator: update envoy@ in istio/proxy@master (#5921) 2024-11-07 10:41:27 -05:00
zirain e86741054f
add test for serializeAsProto (#5919)
* add test for serializeAsProto

* lint
2024-11-06 12:04:30 -05:00
Istio Automation 9734540ba3
Automator: update envoy@ in istio/proxy@master (#5920) 2024-11-06 10:49:26 -05:00
Istio Automation 3ff69b49ba
Automator: update common-files@master in istio/proxy@master (#5918) 2024-11-05 23:39:54 -05:00
zirain e0d4ce52e3
implement serializeAsProto (#5915) 2024-11-05 13:07:42 -05:00
Istio Automation d4b933c0b9
Automator: update envoy@ in istio/proxy@master (#5916) 2024-11-05 10:39:41 -05:00
Istio Automation cf09bab953
Automator: update envoy@ in istio/proxy@master (#5914) 2024-11-04 09:43:41 -05:00
Istio Automation b53d450663
Automator: update go-control-plane in istio/proxy@master (#5913) 2024-11-02 22:12:38 -04:00
Istio Automation 467eae0d7a
Automator: update envoy@ in istio/proxy@master (#5912) 2024-11-02 11:24:38 -04:00
Istio Automation fba4c67cf6
Automator: update envoy@ in istio/proxy@master (#5910) 2024-11-01 10:44:51 -04:00
Istio Automation 3790ec743b
Automator: update envoy@ in istio/proxy@master (#5906) 2024-10-31 11:44:51 -04:00
Istio Automation b641be303d
Automator: update envoy@ in istio/proxy@master (#5898) 2024-10-30 11:39:54 -04:00
Istio Automation 0df62073b0
Automator: update envoy@ in istio/proxy@master (#5895) 2024-10-29 11:42:54 -04:00
Istio Automation b34faf3ec2
Automator: update common-files@master in istio/proxy@master (#5893) 2024-10-28 14:09:52 -04:00
Istio Automation cec2166722
Automator: update envoy@ in istio/proxy@master (#5891) 2024-10-28 10:41:51 -04:00
Istio Automation 48238cfe62
Automator: update go-control-plane in istio/proxy@master (#5890) 2024-10-26 22:12:50 -04:00
Istio Automation ba9135cfbd
Automator: update envoy@ in istio/proxy@master (#5889) 2024-10-26 11:33:50 -04:00
Istio Automation 96cbb48e14
Automator: update envoy@ in istio/proxy@master (#5887) 2024-10-25 11:23:50 -04:00
Istio Automation b23760cf29
Automator: update envoy@ in istio/proxy@master (#5884) 2024-10-24 11:07:49 -04:00
Istio Automation 94d6398e8a
Automator: update common-files@master in istio/proxy@master (#5883) 2024-10-24 10:33:49 -04:00
Istio Automation a0129815ff
Automator: update envoy@ in istio/proxy@master (#5879) 2024-10-23 10:49:32 -04:00
Istio Automation ad5609d5f5
Automator: update envoy@ in istio/proxy@master (#5878) 2024-10-21 11:42:56 -04:00
Istio Automation b61546a054
Automator: update go-control-plane in istio/proxy@master (#5877) 2024-10-19 22:12:53 -04:00
Istio Automation b155d715a8
Automator: update envoy@ in istio/proxy@master (#5876) 2024-10-19 10:47:53 -04:00
Istio Automation 27a7461581
Automator: update envoy@ in istio/proxy@master (#5874) 2024-10-18 11:57:53 -04:00
Istio Automation c955d82537
Automator: update envoy@ in istio/proxy@master (#5872) 2024-10-17 11:58:52 -04:00
Istio Automation b6fc5b58d9
Automator: update envoy@ in istio/proxy@master (#5871) 2024-10-16 11:44:52 -04:00
Istio Automation cf6bb6b2d6
Automator: update common-files@master in istio/proxy@master (#5861) 2024-10-15 15:27:50 -04:00
Istio Automation 3005ce3fe1
Automator: update envoy@ in istio/proxy@master (#5869) 2024-10-15 10:46:27 -04:00
Istio Automation 32b266f1c9
Automator: update envoy@ in istio/proxy@master (#5868) 2024-10-14 11:21:27 -04:00
Istio Automation eb920e9e6f
Automator: update go-control-plane in istio/proxy@master (#5867) 2024-10-12 22:13:25 -04:00
Istio Automation ddae7098b8
Automator: update envoy@ in istio/proxy@master (#5866) 2024-10-11 10:42:58 -04:00
Istio Automation 1a8e8d40ff
Automator: update envoy@ in istio/proxy@master (#5863) 2024-10-10 11:36:46 -04:00
Istio Automation 9fb55b8c33
Automator: update envoy@ in istio/proxy@master (#5862) 2024-10-09 11:43:47 -04:00
Istio Automation f5a53daf0d
Automator: update envoy@ in istio/proxy@master (#5860) 2024-10-08 12:01:44 -04:00
Istio Automation b5771ab520
Automator: update envoy@ in istio/proxy@master (#5858) 2024-10-07 10:41:23 -04:00
Istio Automation db5107d018
Automator: update envoy@ in istio/proxy@master (#5857) 2024-10-06 10:51:22 -04:00
Istio Automation e11c37aeca
Automator: update go-control-plane in istio/proxy@master (#5856) 2024-10-05 22:12:21 -04:00
Istio Automation 332c542aa5
Automator: update envoy@ in istio/proxy@master (#5855) 2024-10-05 11:30:21 -04:00
Istio Automation c59a38d143
Automator: update common-files@master in istio/proxy@master (#5854) 2024-10-04 20:58:00 -04:00
Kuat fc942e4295
fix build due to upstream changes (#5853)
Change-Id: I38c8c4d08747ac048d63318a60fc58830e7a7a99

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-10-04 19:04:01 -04:00
Istio Automation 006527e964
Automator: update common-files@master in istio/proxy@master (#5851) 2024-10-03 18:50:00 -04:00
Istio Automation 44fe838efc
Automator: update envoy@ in istio/proxy@master (#5850) 2024-10-03 11:26:30 -04:00
Istio Automation 430338d16e
Automator: update envoy@ in istio/proxy@master (#5848) 2024-10-02 11:39:29 -04:00
Kuat ff75792665
refactor follow-up (#5845)
Change-Id: I6e0a848716c6f71b6ba929455b61010f4dd5362c

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-10-01 21:03:30 -04:00
Istio Automation 6a4e70feef
Automator: update envoy@ in istio/proxy@master (#5844) 2024-10-01 11:30:29 -04:00
Istio Automation 9f66492f0f
Automator: update envoy@ in istio/proxy@master (#5841) 2024-09-30 10:42:28 -04:00
Istio Automation 0840b5ca18
Automator: update go-control-plane in istio/proxy@master (#5840) 2024-09-28 22:12:26 -04:00
Istio Automation 3b82953e0e
Automator: update envoy@ in istio/proxy@master (#5839) 2024-09-28 10:38:25 -04:00
Jonh Wendell bee898357e
Fix the go toolchain version (#5836)
It needs to be `x.y.z`.
2024-09-27 12:15:25 -04:00
Istio Automation 535ce95086
Automator: update envoy@ in istio/proxy@master (#5834) 2024-09-27 11:26:25 -04:00
Istio Automation 7ace483f40
Automator: update envoy@ in istio/proxy@master (#5831) 2024-09-26 11:45:23 -04:00
Kuat 75004b8bd4
minor clean up post refactor (#5832)
Change-Id: I7859c5ad54b8308b6c138932d7914cff5573fc54

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-09-25 19:25:35 -04:00
Kuat 24a4847dcf
Refactor metadata exchange in preparation for upstreaming (#5825)
* refactoring

Change-Id: I1abef439650eebf6b9a8f26d078ac5ba05f0ba23
Signed-off-by: Kuat Yessenov <kuat@google.com>

* remove stale file

Change-Id: I12a177ad558528471c602313798f2f24a83c84df
Signed-off-by: Kuat Yessenov <kuat@google.com>

* merge

Change-Id: Ib0254ff7257981efb40113e158a8e4836d3e646e
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix test

Change-Id: Icb79eceed2fd00b29bf9ae327fdbfbf11c411ff4
Signed-off-by: Kuat Yessenov <kuat@google.com>

* revert testdata

Change-Id: I671022496c255a0ddae472db287871c21a2cde47
Signed-off-by: Kuat Yessenov <kuat@google.com>

* add test

Change-Id: I177615e42cd9e5e97e3aba5ac0df5a386230f828
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix test

Change-Id: Ibd73649bac9da6d6c714bba197444f13100cd3f1
Signed-off-by: Kuat Yessenov <kuat@google.com>

---------

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-09-24 18:28:26 -04:00
Istio Automation bd3177ba7a
Automator: update common-files@master in istio/proxy@master (#5829) 2024-09-24 12:36:24 -04:00
Istio Automation 53d0d548e5
Automator: update envoy@ in istio/proxy@master (#5827) 2024-09-24 11:36:24 -04:00
Istio Automation b6591a9999
Automator: update envoy@ in istio/proxy@master (#5824) 2024-09-23 11:46:23 -04:00
Istio Automation 4e37264f7c
Automator: update go-control-plane in istio/proxy@master (#5823) 2024-09-21 22:12:21 -04:00
Istio Automation 1211b219d5
Automator: update envoy@ in istio/proxy@master (#5821) 2024-09-21 11:29:20 -04:00
Istio Automation 2111f1a3fc
Automator: update common-files@master in istio/proxy@master (#5818) 2024-09-20 14:32:20 -04:00
Istio Automation f204be73bd
Automator: update envoy@ in istio/proxy@master (#5816) 2024-09-20 11:35:19 -04:00
zirain 9d9dc7d9c8
fix deps (#5815)
* Automator: update envoy@ in istio/proxy@master

* fix deps

---------

Co-authored-by: istio-testing <istio-testing-bot@google.com>
2024-09-20 08:17:19 -04:00
Istio Automation 0850bd6625
Automator: update envoy@ in istio/proxy@master (#5809) 2024-09-18 11:40:18 -04:00
Istio Automation 989a8cbcae
Automator: update envoy@ in istio/proxy@master (#5805) 2024-09-17 11:27:16 -04:00
Istio Automation 180dcc50d1
Automator: update envoy@ in istio/proxy@master (#5801) 2024-09-16 11:37:17 -04:00
Istio Automation b9a56ed5f7
Automator: update go-control-plane in istio/proxy@master (#5799) 2024-09-14 22:14:14 -04:00
Istio Automation 94a9e192d4
Automator: update envoy@ in istio/proxy@master (#5796) 2024-09-14 10:37:13 -04:00
Istio Automation db8d49dcaf
Automator: update common-files@master in istio/proxy@master (#5794) 2024-09-13 19:43:02 -04:00
Istio Automation 3634966d32
Automator: update envoy@ in istio/proxy@master (#5792) 2024-09-13 11:55:13 -04:00
Istio Automation 4187a10812
Automator: update common-files@master in istio/proxy@master (#5790) 2024-09-12 13:08:35 -04:00
Istio Automation e8a7218486
Automator: update envoy@ in istio/proxy@master (#5789) 2024-09-12 11:38:35 -04:00
Istio Automation 9285105258
Automator: update common-files@master in istio/proxy@master (#5788) 2024-09-11 15:52:34 -04:00
Istio Automation afbd9e264a
Automator: update envoy@ in istio/proxy@master (#5784) 2024-09-11 10:40:34 -04:00
Istio Automation 628088d580
Automator: update envoy@ in istio/proxy@master (#5783) 2024-09-10 11:27:33 -04:00
Istio Automation 56490c48a5
Automator: update envoy@ in istio/proxy@master (#5782) 2024-09-09 11:35:32 -04:00
Istio Automation 0c71d1f824
Automator: update envoy@ in istio/proxy@master (#5781) 2024-09-08 10:38:30 -04:00
Istio Automation e61e6f97c6
Automator: update go-control-plane in istio/proxy@master (#5780) 2024-09-07 22:12:30 -04:00
Istio Automation 4195ae840b
Automator: update envoy@ in istio/proxy@master (#5779) 2024-09-07 11:24:29 -04:00
Istio Automation 023e10a7fc
Automator: update envoy@ in istio/proxy@master (#5778) 2024-09-06 10:40:29 -04:00
Istio Automation b4abf6ae06
Automator: update common-files@master in istio/proxy@master (#5777) 2024-09-06 01:52:28 -04:00
Istio Automation 3e285c1c77
Automator: update envoy@ in istio/proxy@master (#5776) 2024-09-05 10:40:27 -04:00
Istio Automation c53a6ed438
Automator: update envoy@ in istio/proxy@master (#5775) 2024-09-04 11:24:26 -04:00
Istio Automation 122cdba413
Automator: update envoy@ in istio/proxy@master (#5774) 2024-09-03 11:40:25 -04:00
Istio Automation adfb08fe49
Automator: update envoy@ in istio/proxy@master (#5773) 2024-09-02 10:39:24 -04:00
Istio Automation 9dfefce0ae
Automator: update envoy@ in istio/proxy@master (#5772) 2024-09-01 10:40:23 -04:00
Istio Automation 62e93ff050
Automator: update go-control-plane in istio/proxy@master (#5771) 2024-08-31 22:12:22 -04:00
Istio Automation c04da862b8
Automator: update envoy@ in istio/proxy@master (#5770) 2024-08-31 11:34:22 -04:00
Istio Automation 3e2ee68c64
Automator: update envoy@ in istio/proxy@master (#5769) 2024-08-30 11:09:21 -04:00
Istio Automation be9ed1dcbb
Automator: update envoy@ in istio/proxy@master (#5768) 2024-08-29 11:37:20 -04:00
Istio Automation 1b4b7499b5
Automator: update envoy@ in istio/proxy@master (#5766) 2024-08-28 22:38:19 -04:00
Istio Automation 57e863b743
Automator: update common-files@master in istio/proxy@master (#5767) 2024-08-28 21:18:19 -04:00
Istio Automation 033cbd1ef4
Automator: update envoy@ in istio/proxy@master (#5765) 2024-08-27 10:52:45 -04:00
Kevin Burek 812f11396d
Bazel build extra args for Prow CI (#5712) 2024-08-26 14:33:44 -04:00
zirain ff08598396
istio_build metric should not expiry (#5744)
* add test for istio_build metric

* use factory scope

* move into constructor
2024-08-26 13:55:44 -04:00
Istio Automation fb0f97b8dd
Automator: update envoy@ in istio/proxy@master (#5761) 2024-08-26 11:39:44 -04:00
Istio Automation 1e5b6e37c8
Automator: update envoy@ in istio/proxy@master (#5760) 2024-08-25 10:36:27 -04:00
Istio Automation cd1ff0473f
Automator: update go-control-plane in istio/proxy@master (#5759) 2024-08-24 22:12:26 -04:00
Istio Automation 77a9a2bda1
Automator: update envoy@ in istio/proxy@master (#5758) 2024-08-24 11:22:25 -04:00
Istio Automation 5643d90bd3
Automator: update envoy@ in istio/proxy@master (#5753) 2024-08-23 10:43:26 -04:00
Kuat 2d9173b3b4
cleanup: remove local rate limit and otel tests (#5752)
* cleanup: remove local rate limit and otel tests

Change-Id: I926ed60d66bc6914155cae111097284a86910ea2
Signed-off-by: Kuat Yessenov <kuat@google.com>

* remove inventory as well

Change-Id: I38bfa83dc92dcff1bb5e0a7fe8dd2a28792b1325
Signed-off-by: Kuat Yessenov <kuat@google.com>

---------

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-08-21 14:12:24 -04:00
Istio Automation 4bb7691fff
Automator: update envoy@ in istio/proxy@master (#5751) 2024-08-21 10:38:24 -04:00
Istio Automation 28487117a4
Automator: update common-files@master in istio/proxy@master (#5750) 2024-08-21 00:29:23 -04:00
Istio Automation 31dc68618f
Automator: update common-files@master in istio/proxy@master (#5749) 2024-08-20 16:38:23 -04:00
Istio Automation dc4f975ef3
Automator: update envoy@ in istio/proxy@master (#5747) 2024-08-20 11:38:22 -04:00
Istio Automation 7d3cb6e416
Automator: update common-files@master in istio/proxy@master (#5746) 2024-08-19 16:06:23 -04:00
Istio Automation 5bba4704fd
Automator: update envoy@ in istio/proxy@master (#5745) 2024-08-19 11:23:43 -04:00
Istio Automation 098fa0cf40
Automator: update envoy@ in istio/proxy@master (#5743) 2024-08-18 10:36:42 -04:00
Istio Automation 20355fc368
Automator: update go-control-plane in istio/proxy@master (#5742) 2024-08-17 22:12:42 -04:00
Istio Automation 4363d1c647
Automator: update envoy@ in istio/proxy@master (#5741) 2024-08-17 10:38:31 -04:00
Istio Automation 42191ac9c2
Automator: update envoy@ in istio/proxy@master (#5740) 2024-08-16 11:31:47 -04:00
Arijit 4a2e408ea7
Fixing dev container (#5739)
Moving the proxy building container for vscode.
2024-08-16 01:01:47 -04:00
Istio Automation 967f36f0e9
Automator: update envoy@ in istio/proxy@master (#5738) 2024-08-15 11:27:47 -04:00
Istio Automation 456db56c0b
Automator: update common-files@master in istio/proxy@master (#5737) 2024-08-14 20:57:20 -04:00
Jonh Wendell 4aa2c2c7a7
Add missing `$BAZEL_STARTUP_ARGS` to `bazel info` command (#5734)
The lack of it might result in `bazel info` returning wrong results.
2024-08-14 16:39:20 -04:00
Istio Automation f22b7930b6
Automator: update envoy@ in istio/proxy@master (#5733) 2024-08-14 11:32:19 -04:00
Istio Automation 35e33dc9aa
Automator: update envoy@ in istio/proxy@master (#5732) 2024-08-13 10:45:19 -04:00
Istio Automation 04f1317f79
Automator: update envoy@ in istio/proxy@master (#5730) 2024-08-12 10:35:31 -04:00
Istio Automation 1db7091d04
Automator: update envoy@ in istio/proxy@master (#5729) 2024-08-11 10:34:53 -04:00
Istio Automation e9d7dffccb
Automator: update go-control-plane in istio/proxy@master (#5728) 2024-08-10 22:12:53 -04:00
Istio Automation 598886d6b1
Automator: update envoy@ in istio/proxy@master (#5727) 2024-08-10 11:18:52 -04:00
Istio Automation b3a92a55c6
Automator: update envoy@ in istio/proxy@master (#5726) 2024-08-09 11:28:52 -04:00
Istio Automation 80963e8ad9
Automator: update envoy@ in istio/proxy@master (#5724) 2024-08-08 11:18:51 -04:00
Istio Automation 5e81a5e524
Automator: update common-files@master in istio/proxy@master (#5722) 2024-08-07 15:59:24 -04:00
Istio Automation 3696d225cb
Automator: update common-files@master in istio/proxy@master (#5721) 2024-08-07 11:26:23 -04:00
Istio Automation dd502f0fde
Automator: update envoy@ in istio/proxy@master (#5720) 2024-08-07 10:34:23 -04:00
Istio Automation 1532a7e3d3
Automator: update envoy@ in istio/proxy@master (#5719) 2024-08-06 11:17:03 -04:00
Istio Automation 40e715ca76
Automator: update envoy@ in istio/proxy@master (#5717) 2024-08-05 11:19:47 -04:00
Istio Automation cbdfba7250
Automator: update envoy@ in istio/proxy@master (#5716) 2024-08-04 10:34:46 -04:00
Istio Automation 95d14f4877
Automator: update envoy@ in istio/proxy@master (#5714) 2024-08-04 00:22:46 -04:00
Istio Automation 4d0d59d3c7
Automator: update go-control-plane in istio/proxy@master (#5715) 2024-08-03 22:19:46 -04:00
Istio Automation a846053d57
Automator: update envoy@ in istio/proxy@master (#5713) 2024-08-02 11:17:14 -04:00
Istio Automation 492b0eba15
Automator: update envoy@ in istio/proxy@master (#5711) 2024-08-01 11:35:12 -04:00
zirain c9b8ac3ec5
Sync with upstream (#5708)
* Automator: update envoy@ in istio/proxy@master

* remove envoy.tracers.dynamic_ot

---------

Co-authored-by: istio-testing <istio-testing-bot@google.com>
2024-07-31 11:46:06 -04:00
Istio Automation 50d4818704
Automator: update common-files@master in istio/proxy@master (#5705) 2024-07-29 15:27:36 -04:00
John Howard da29cb909f
Add new fields to workload.proto (#5704)
* Add new fields to workload.proto

* Add networkmode
2024-07-29 15:15:36 -04:00
Istio Automation b727aaaefa
Automator: update common-files@master in istio/proxy@master (#5703) 2024-07-29 10:46:35 -04:00
Istio Automation b5e8707925
Automator: update envoy@ in istio/proxy@master (#5702) 2024-07-29 10:32:36 -04:00
Istio Automation 8a5e5744ac
Automator: update go-control-plane in istio/proxy@master (#5701) 2024-07-27 22:11:33 -04:00
Istio Automation 7124ecc710
Automator: update envoy@ in istio/proxy@master (#5700) 2024-07-27 10:36:33 -04:00
Istio Automation c3eaebe647
Automator: update envoy@ in istio/proxy@master (#5697) 2024-07-26 11:34:32 -04:00
Istio Automation 15edf9d9d6
Automator: update envoy@ in istio/proxy@master (#5692) 2024-07-23 11:30:31 -04:00
Istio Automation 3acfd468c6
Automator: update common-files@master in istio/proxy@master (#5693) 2024-07-23 10:46:31 -04:00
Istio Automation 39a751f982
Automator: update envoy@ in istio/proxy@master (#5688) 2024-07-22 10:39:29 -04:00
Istio Automation 63827a9d24
Automator: update go-control-plane in istio/proxy@master (#5687) 2024-07-20 22:11:28 -04:00
Istio Automation e02f8bc49f
Automator: update envoy@ in istio/proxy@master (#5685) 2024-07-20 10:33:11 -04:00
Istio Automation c109cf08fc
Automator: update envoy@ in istio/proxy@master (#5681) 2024-07-19 10:34:19 -04:00
Istio Automation 91ab35a32b
Automator: update common-files@master in istio/proxy@master (#5679) 2024-07-18 12:42:19 -04:00
Istio Automation f940250e29
Automator: update envoy@ in istio/proxy@master (#5678) 2024-07-18 10:35:18 -04:00
Istio Automation 5e5e097ee8
Automator: update common-files@master in istio/proxy@master (#5676) 2024-07-17 16:15:18 -04:00
Istio Automation 4c4e2e0c42
Automator: update envoy@ in istio/proxy@master (#5674) 2024-07-17 11:27:17 -04:00
Istio Automation 0dfd5193c7
Automator: update envoy@ in istio/proxy@master (#5671) 2024-07-16 20:59:16 -04:00
Istio Automation 121c0456d8
Automator: update envoy@ in istio/proxy@master (#5670) 2024-07-15 11:08:14 -04:00
Istio Automation 1b78524571
Automator: update envoy@ in istio/proxy@master (#5669) 2024-07-14 11:10:13 -04:00
Istio Automation 5a3def453e
Automator: update go-control-plane in istio/proxy@master (#5668) 2024-07-13 22:12:13 -04:00
Istio Automation 8a221a7b5b
Automator: update envoy@ in istio/proxy@master (#5667) 2024-07-13 11:29:11 -04:00
Istio Automation b5ce24a13d
Automator: update envoy@ in istio/proxy@master (#5666) 2024-07-12 11:28:11 -04:00
Istio Automation 24811d4602
Automator: update envoy@ in istio/proxy@master (#5664) 2024-07-11 11:30:10 -04:00
Istio Automation 1d365f42bd
Automator: update go-control-plane in istio/proxy@master (#5658) 2024-07-10 12:28:23 -04:00
Istio Automation a82266a3fa
Automator: update envoy@ in istio/proxy@master (#5663) 2024-07-10 12:15:23 -04:00
Istio Automation b4651f312e
Automator: update common-files@master in istio/proxy@master (#5662) 2024-07-09 18:13:22 -04:00
Istio Automation 4b7782dc05
Automator: update envoy@ in istio/proxy@master (#5661) 2024-07-09 11:16:22 -04:00
Istio Automation 688f04824c
Automator: update common-files@master in istio/proxy@master (#5660) 2024-07-08 18:47:23 -04:00
Istio Automation 278fee0fe8
Automator: update envoy@ in istio/proxy@master (#5659) 2024-07-08 10:32:22 -04:00
Istio Automation 4f7b6ca563
Automator: update envoy@ in istio/proxy@master (#5657) 2024-07-07 10:32:20 -04:00
Istio Automation 335a31c82f
Automator: update envoy@ in istio/proxy@master (#5656) 2024-07-05 10:32:18 -04:00
Istio Automation 60a668aead
Automator: update envoy@ in istio/proxy@master (#5655) 2024-07-04 11:55:17 -04:00
Istio Automation 4d694b5099
Automator: update common-files@master in istio/proxy@master (#5654) 2024-07-04 02:22:08 -04:00
John Howard 8a13495063
waypoints: fix IPv6 address lookup (#5653)
Tested manually. Not really sure how to test this in this repo.
https://github.com/istio/istio/pull/51881 will provide coverage in
istio/istio
2024-07-03 17:36:07 -04:00
Istio Automation 4d746180f2
Automator: update envoy@ in istio/proxy@master (#5652) 2024-07-03 11:53:46 -04:00
Istio Automation 1fd1ca76e8
Automator: update common-files@master in istio/proxy@master (#5647) 2024-07-02 12:56:51 -04:00
Istio Automation aeae96febf
Automator: update envoy@ in istio/proxy@master (#5645) 2024-07-02 11:40:50 -04:00
Istio Automation 5518cd30b6
Automator: update envoy@ in istio/proxy@master (#5642) 2024-07-01 11:05:49 -04:00
Istio Automation 6a1558dde7
Automator: update envoy@ in istio/proxy@master (#5638) 2024-06-30 10:29:48 -04:00
Istio Automation 977b5a50db
Automator: update go-control-plane in istio/proxy@master (#5640) 2024-06-29 22:12:47 -04:00
Istio Automation 025d236c84
Automator: update envoy@ in istio/proxy@master (#5635) 2024-06-28 11:36:43 -04:00
Istio Automation a5a0c228e7
Automator: update common-files@master in istio/proxy@master (#5634) 2024-06-27 11:38:16 -04:00
Istio Automation 44dc599c3b
Automator: update envoy@ in istio/proxy@master (#5633) 2024-06-27 11:26:15 -04:00
Istio Automation 92e4007091
Automator: update common-files@master in istio/proxy@master (#5632) 2024-06-26 21:28:14 -04:00
Istio Automation 9da89a8453
Automator: update envoy@ in istio/proxy@master (#5629) 2024-06-26 11:27:14 -04:00
Istio Automation e7b8e38631
Automator: update envoy@ in istio/proxy@master (#5626) 2024-06-25 20:42:59 -04:00
Istio Automation e2eaa9b634
Automator: update envoy@ in istio/proxy@master (#5625) 2024-06-24 11:31:29 -04:00
Istio Automation 77588eef42
Automator: update envoy@ in istio/proxy@master (#5624) 2024-06-23 10:27:28 -04:00
Istio Automation 331869dd78
Automator: update go-control-plane in istio/proxy@master (#5623) 2024-06-22 22:12:21 -04:00
Istio Automation 4db473d040
Automator: update envoy@ in istio/proxy@master (#5622) 2024-06-22 10:47:20 -04:00
Istio Automation f043d03e68
Automator: update envoy@ in istio/proxy@master (#5621) 2024-06-21 11:14:20 -04:00
Istio Automation 04cc664c5b
Automator: update envoy@ in istio/proxy@master (#5620) 2024-06-20 10:27:35 -04:00
Istio Automation a710748635
Automator: update envoy@ in istio/proxy@master (#5619) 2024-06-19 11:40:34 -04:00
Keith Mattix II 3d2512a4cc
Use cluster metadata for destination_service_name (#5617)
* Use cluster metadata for destination_service_name

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Fallback to peer namespace

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Fix format

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Add cluster metadata precedence test

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Remove duplicate test case

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

---------

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
2024-06-19 11:04:34 -04:00
Istio Automation ad1b2a34cd
Automator: update envoy@ in istio/proxy@master (#5618) 2024-06-18 11:28:33 -04:00
Istio Automation 9213fba03c
Automator: update envoy@ in istio/proxy@master (#5616) 2024-06-17 10:28:31 -04:00
Istio Automation 58a098b37a
Automator: update go-control-plane in istio/proxy@master (#5615) 2024-06-15 22:12:29 -04:00
Istio Automation 205a5d0703
Automator: update envoy@ in istio/proxy@master (#5614) 2024-06-15 10:28:28 -04:00
Istio Automation e7df98ea89
Automator: update envoy@ in istio/proxy@master (#5613) 2024-06-14 11:34:46 -04:00
Istio Automation 7fa3748ae6
Automator: update envoy@ in istio/proxy@master (#5612) 2024-06-13 12:36:29 -04:00
Istio Automation 948b5aea35
Automator: update envoy@ in istio/proxy@master (#5611) 2024-06-12 11:32:28 -04:00
Istio Automation 013c068d27
Automator: update common-files@master in istio/proxy@master (#5610) 2024-06-12 10:17:28 -04:00
Istio Automation 0c0eca5d56
Automator: update common-files@master in istio/proxy@master (#5607) 2024-06-11 19:00:48 -04:00
Istio Automation 1a37f807f3
Automator: update envoy@ in istio/proxy@master (#5606) 2024-06-11 10:42:53 -04:00
John Howard 1392ce3da4
Allow versionless cluster name match in stats (#5604)
For https://github.com/istio/istio/pull/51503, but also required even if
we don't change; for inbound HBONE we need to add initial support for
passthrough (https://github.com/istio/istio/issues/51336). I don't want
to start with legacy hacks on new code, so that will for sure use InboundPassthroughCluster
2024-06-11 10:12:54 -04:00
zirain 2320d00012
add test for tcp_reporting_duration (#5599)
* add test for tcp_reporting_duration

* stats match
2024-06-10 21:04:52 -04:00
Istio Automation 547c45ffe0
Automator: update envoy@ in istio/proxy@master (#5603) 2024-06-10 10:49:52 -04:00
Istio Automation c10a86b576
Automator: update envoy@ in istio/proxy@master (#5602) 2024-06-09 10:27:45 -04:00
Istio Automation 79b1e3212c
Automator: update go-control-plane in istio/proxy@master (#5601) 2024-06-08 22:13:36 -04:00
Istio Automation 3b74ee4da4
Automator: update envoy@ in istio/proxy@master (#5600) 2024-06-08 11:07:36 -04:00
zirain 773ff5d30f
sync with upstream (#5595) 2024-06-07 12:22:36 -04:00
zirain 757b63df34
correct peer_unkown key (#5592) 2024-06-06 12:44:29 -04:00
Istio Automation a0473f11f7
Automator: update envoy@ in istio/proxy@master (#5576) 2024-06-05 13:58:53 -04:00
Istio Automation f531e57831
Automator: update common-files@master in istio/proxy@master (#5591) 2024-06-05 13:13:49 -04:00
Istio Automation 0abb2a5661
Automator: update common-files@master in istio/proxy@master (#5586) 2024-06-04 19:21:23 -04:00
zirain 09a30d6b5f
disable extension check tool (#5581)
* disable extension check tool

* update envoy

* update

* update
2024-06-04 18:21:07 -04:00
Istio Automation e4bf7c1853
Automator: update common-files@master in istio/proxy@master (#5585) 2024-06-04 15:45:06 -04:00
Istio Automation 758f194b30
Automator: update common-files@master in istio/proxy@master (#5584) 2024-06-02 11:21:04 -04:00
Istio Automation 7a965340bd
Automator: update go-control-plane in istio/proxy@master (#5583) 2024-06-01 22:13:24 -04:00
Istio Automation c95ecb0f7a
Automator: update common-files@master in istio/proxy@master (#5582) 2024-06-01 17:07:23 -04:00
Istio Automation b3cce4dbc7
Automator: update common-files@master in istio/proxy@master (#5580) 2024-05-31 10:00:11 -04:00
Istio Automation e114a7d290
Automator: update common-files@master in istio/proxy@master (#5579) 2024-05-30 18:54:06 -04:00
Istio Automation 1678bacbcd
Automator: update common-files@master in istio/proxy@master (#5578) 2024-05-28 14:22:37 -04:00
Istio Automation c32b464241
Automator: update go-control-plane in istio/proxy@master (#5577) 2024-05-28 10:33:01 -04:00
Istio Automation d3b57a59c8
Automator: update envoy@ in istio/proxy@master (#5575) 2024-05-24 10:40:04 -04:00
Istio Automation 949e79fefb
Automator: update envoy@ in istio/proxy@master (#5572) 2024-05-23 10:39:03 -04:00
Istio Automation e13f653d8d
Automator: update envoy@ in istio/proxy@master (#5569) 2024-05-22 10:07:03 -04:00
Istio Automation 657147dd2c
Automator: update common-files@master in istio/proxy@master (#5567) 2024-05-21 16:07:02 -04:00
Istio Automation 2508c9c41b
Automator: update common-files@master in istio/proxy@master (#5565) 2024-05-21 10:55:29 -04:00
Istio Automation 82c215ee03
Automator: update envoy@ in istio/proxy@master (#5564) 2024-05-21 09:36:30 -04:00
Istio Automation 8ecf97b08a
Automator: update envoy@ in istio/proxy@master (#5563) 2024-05-20 09:33:32 -04:00
Istio Automation 98c62c57e7
Automator: update go-control-plane in istio/proxy@master (#5562) 2024-05-18 22:13:29 -04:00
Istio Automation 89f3eac29a
Automator: update envoy@ in istio/proxy@master (#5561) 2024-05-18 09:33:30 -04:00
Kuat 368a5a93ca
cleanup BUILD files (#5560)
* cleanup BUILD files

Change-Id: If71f58c74262695b494d5e66d6179e6d05b518e4
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix more

Change-Id: I58df5700a55da9ece2e67a66cccb40c84e1e819b
Signed-off-by: Kuat Yessenov <kuat@google.com>

---------

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-05-17 19:45:29 -04:00
Istio Automation 2a83ccf912
Automator: update envoy@ in istio/proxy@master (#5559) 2024-05-17 10:24:30 -04:00
Istio Automation 14f9ce02b1
Automator: update envoy@ in istio/proxy@master (#5555) 2024-05-16 10:36:29 -04:00
Istio Automation bc190bb7dc
Automator: update common-files@master in istio/proxy@master (#5553) 2024-05-15 19:42:11 -04:00
Kuat 40fef42347
remove opencensus tracer (#5552)
* remove opencensus tracer

Change-Id: I130f6e902d00805568e2d4206069f9e98c70853b
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix

Change-Id: I16f9d81ce2acc5cf2725f5e718d10055043a6ac3
Signed-off-by: Kuat Yessenov <kuat@google.com>

---------

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-05-15 18:26:11 -04:00
Kuat f6112f1ad2
remove stackdriver (#5550)
* remove stackdriver

Change-Id: I3b91f2b05b7e0fe6f4878311741cc74162f84934
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix makefile

Change-Id: Ibb5d68a351f2d47efd5fc217400a8256b2843963
Signed-off-by: Kuat Yessenov <kuat@google.com>

---------

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-05-15 17:47:11 -04:00
Istio Automation 3e10b0f8d8
Automator: update common-files@master in istio/proxy@master (#5551) 2024-05-15 17:03:02 -04:00
Istio Automation f352a04be1
Automator: update envoy@ in istio/proxy@master (#5548) 2024-05-15 11:21:09 -07:00
Kuat d4c251c606
separate Stackdriver code (#5546)
* cip

Change-Id: I3e94bb01016b5d72ad18d425f14cfce1646d9a28
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix

Change-Id: I30d10a4f15b97308b9f30add447138353f0feda8
Signed-off-by: Kuat Yessenov <kuat@google.com>

* move flatbuffers

Change-Id: Ic0390cdcf4f6696dbedf644f25bf1d4c3b2bf8c6
Signed-off-by: Kuat Yessenov <kuat@google.com>

* stash failed attempt

Change-Id: I714aa078f2fc8f04a0131778e41816aefe09506b
Signed-off-by: Kuat Yessenov <kuat@google.com>

* Revert "stash failed attempt"

This reverts commit 34440e615f.

* Revert "move flatbuffers"

This reverts commit 789b8a7e95.

---------

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-05-15 08:59:42 -07:00
Kuat 962043c851
stats: turn down v8 testing (#5547)
* stats: turn down v8 testing

Change-Id: I1da35dd245bbb1ebe7578f9077efad9de20b2724
Signed-off-by: Kuat Yessenov <kuat@google.com>

* clean up inventory

Change-Id: I139fa94adb8b52504e261bbb6abf9d3edc4d8c89
Signed-off-by: Kuat Yessenov <kuat@google.com>

---------

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-05-14 12:22:45 -07:00
Istio Automation 4c512ca409
Automator: update envoy@ in istio/proxy@master (#5545) 2024-05-14 08:57:39 -07:00
Istio Automation c4aa512618
Automator: update common-files@master in istio/proxy@master (#5544) 2024-05-13 09:35:16 -07:00
Istio Automation 70924c3911
Automator: update envoy@ in istio/proxy@master (#5543) 2024-05-13 07:19:20 -07:00
Istio Automation 6b26452b71
Automator: update go-control-plane in istio/proxy@master (#5542) 2024-05-11 19:26:18 -07:00
Istio Automation ddfb9523a8
Automator: update envoy@ in istio/proxy@master (#5541) 2024-05-11 06:45:19 -07:00
zirain db29233591
sync with upstream (#5540)
* Automator: update envoy@ in istio/proxy@master

* add envoy.http.injected_credentials.oauth2

---------

Co-authored-by: istio-testing <istio-testing-bot@google.com>
2024-05-10 17:51:57 -07:00
Istio Automation 705be6570c
Automator: update common-files@master in istio/proxy@master (#5539) 2024-05-09 18:42:52 -07:00
Istio Automation 97ecf319a7
Automator: update common-files@master in istio/proxy@master (#5538) 2024-05-09 09:23:52 -07:00
Istio Automation a42cb99a26
Automator: update common-files@master in istio/proxy@master (#5536) 2024-05-08 15:47:51 -07:00
Istio Automation 4407fde0af
Automator: update envoy@ in istio/proxy@master (#5535) 2024-05-08 12:09:53 -07:00
Istio Automation 66d4e06ac2
Automator: update envoy@ in istio/proxy@master (#5534) 2024-05-07 08:10:51 -07:00
Istio Automation 8cc3013177
Automator: update envoy@ in istio/proxy@master (#5529) 2024-05-06 23:28:49 -07:00
Keith Mattix II 7bd1251c59
Use WDS to get destination_principal (#5514)
Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
2024-05-06 15:59:49 -07:00
Istio Automation 5324e65a04
Automator: update go-control-plane in istio/proxy@master (#5528) 2024-05-04 19:25:56 -07:00
Istio Automation 455dc84d9b
Automator: update envoy@ in istio/proxy@master (#5527) 2024-05-04 06:43:56 -07:00
Istio Automation a5cc532517
Automator: update envoy@ in istio/proxy@master (#5526) 2024-05-03 07:49:42 -07:00
Kuat f8c6bb79f7
use tcmalloc (#5523)
Change-Id: Ifeb9f5315a9c0ef1e0f38580e5132cd468d7a79b

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-05-02 17:33:41 -07:00
Istio Automation 0c3b0dc9db
Automator: update envoy@ in istio/proxy@master (#5517) 2024-05-02 12:06:41 -07:00
Istio Automation 796d99edb8
Automator: update common-files@master in istio/proxy@master (#5521) 2024-05-02 11:11:42 -07:00
Istio Automation 367bddf4e7
Automator: update common-files@master in istio/proxy@master (#5518) 2024-05-02 07:28:41 -07:00
Istio Automation 21ed2edd27
Automator: update envoy@ in istio/proxy@master (#5511) 2024-05-01 08:04:40 -07:00
Whitney Griffith f914b3bc80
Ambient Telemetry: implement "waypoint single" approach (#5472)
* add comments

Signed-off-by: whitneygriffith <whitney.griffith16@gmail.com>

* fix stats reporting for destination workload

* fix stats reporting for destination workload

Signed-off-by: whitneygriffith <whitney.griffith16@gmail.com>

* update expected test data

Signed-off-by: whitneygriffith <whitney.griffith16@gmail.com>

* format files

Signed-off-by: Whitney Griffith <whitney.griffith16@gmail.com>

* Update testdate

Signed-off-by: Whitney Griffith <whitney.griffith16@gmail.com>

* revert testdata

Signed-off-by: Whitney Griffith <whitney.griffith16@gmail.com>

* update testdata

Signed-off-by: Whitney Griffith <whitney.griffith16@gmail.com>

* update testdata

Signed-off-by: Whitney Griffith <whitney.griffith16@gmail.com>

---------

Signed-off-by: whitneygriffith <whitney.griffith16@gmail.com>
Signed-off-by: Whitney Griffith <whitney.griffith16@gmail.com>
Co-authored-by: Daniel Hawton <daniel@hawton.org>
2024-04-30 15:56:39 -07:00
Istio Automation ef260442e5
Automator: update envoy@ in istio/proxy@master (#5509) 2024-04-30 08:01:46 -07:00
Istio Automation fc2fd60c66
Automator: update envoy@ in istio/proxy@master (#5506) 2024-04-29 08:00:47 -07:00
Istio Automation e793690a67
Automator: update go-control-plane in istio/proxy@master (#5505) 2024-04-27 19:27:19 -07:00
Istio Automation 0d4b8a5ffe
Automator: update envoy@ in istio/proxy@master (#5504) 2024-04-27 07:40:18 -07:00
Istio Automation 5f27da798f
Automator: update envoy@ in istio/proxy@master (#5503) 2024-04-26 07:22:17 -07:00
Istio Automation f0c8cb2a2a
Automator: update envoy@ in istio/proxy@master (#5502) 2024-04-25 07:38:18 -07:00
Istio Automation 22f0f1295c
Automator: update envoy@ in istio/proxy@master (#5501) 2024-04-24 06:53:23 -07:00
Istio Automation 015a976db9
Automator: update common-files@master in istio/proxy@master (#5500) 2024-04-23 11:52:50 -07:00
Istio Automation 0d94076354
Automator: update envoy@ in istio/proxy@master (#5498) 2024-04-23 10:50:50 -07:00
Istio Automation 2c5e0e6b94
Automator: update common-files@master in istio/proxy@master (#5494) 2024-04-22 09:55:25 -07:00
Istio Automation 8a70c1b364
Automator: update envoy@ in istio/proxy@master (#5489) 2024-04-22 08:28:28 -07:00
Istio Automation 5c918deb28
Automator: update go-control-plane in istio/proxy@master (#5490) 2024-04-22 07:17:56 -07:00
Bo-Cheng Chu eaa058a403
add cr revision mr (#5481) 2024-04-19 16:46:53 -07:00
Istio Automation aa660d70b2
Automator: update envoy@ in istio/proxy@master (#5485) 2024-04-19 08:05:44 -07:00
dependabot[bot] 63446eec6b
Bump golang.org/x/net from 0.20.0 to 0.23.0 (#5484)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.20.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.20.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 07:19:43 -07:00
Istio Automation bd0d94a288
Automator: update common-files@master in istio/proxy@master (#5482) 2024-04-18 12:45:43 -07:00
Istio Automation 05cf48533d
Automator: update envoy@ in istio/proxy@master (#5477) 2024-04-18 10:31:43 -07:00
zirain ec64d1a640
update rules for new extensions (#5476) 2024-04-18 08:43:43 -07:00
Istio Automation e459d5813e
Automator: update envoy@ in istio/proxy@master (#5475) 2024-04-17 08:40:41 -07:00
Istio Automation fb16712e4a
Automator: update envoy@ in istio/proxy@master (#5470) 2024-04-16 10:05:40 -07:00
zirain 662fad0bad
sync with upstream (#5466)
* Automator: update envoy@ in istio/proxy@master

* remove duplicate flags

* test remove

---------

Co-authored-by: istio-testing <istio-testing-bot@google.com>
2024-04-15 15:29:37 -07:00
Istio Automation 23e1e1a37a
Automator: update common-files@master in istio/proxy@master (#5469) 2024-04-15 11:24:37 -07:00
Istio Automation e4b897b2a2
Automator: update go-control-plane in istio/proxy@master (#5468) 2024-04-13 19:25:32 -07:00
Istio Automation 540316942e
Automator: update common-files@master in istio/proxy@master (#5463) 2024-04-12 06:54:31 -07:00
Istio Automation d495eaf60e
Automator: update envoy@ in istio/proxy@master (#5461) 2024-04-11 07:25:30 -07:00
Eric Van Norman d29e22a29b
Update Envoy and add extension (#5458)
* Tetxt envoy pre the credential change

* Update Envoy and add extension
2024-04-10 09:24:25 -07:00
Istio Automation 9de6aa1ca1
Automator: update envoy@ in istio/proxy@master (#5454) 2024-04-09 21:44:53 -07:00
Istio Automation ad23291d9a
Automator: update envoy@ in istio/proxy@master (#5453) 2024-04-08 18:24:52 -07:00
Istio Automation 1fa8900510
Automator: update common-files@master in istio/proxy@master (#5452) 2024-04-08 12:01:55 -07:00
Istio Automation 4918673d46
Automator: update go-control-plane in istio/proxy@master (#5451) 2024-04-06 20:01:54 -07:00
Istio Automation 89b9903591
Automator: update envoy@ in istio/proxy@master (#5450) 2024-04-06 18:23:53 -07:00
Istio Automation efb143373d
Automator: update envoy@ in istio/proxy@master (#5449) 2024-04-05 18:49:52 -07:00
John Howard 858533a710
ambient: sync workload proto (#5448)
reserving fields doesn't work; the proto engine will still spam logs
about usage of unknown fields

Fixes https://github.com/istio/istio/issues/46143
2024-04-05 17:40:52 -07:00
Istio Automation 012b395bf9
Automator: update common-files@master in istio/proxy@master (#5444) 2024-04-04 19:55:12 -07:00
Istio Automation fa16e24145
Automator: update envoy@ in istio/proxy@master (#5443) 2024-04-04 19:22:20 -07:00
Istio Automation 43d17f7c74
Automator: update common-files@master in istio/proxy@master (#5439) 2024-04-04 16:47:55 -07:00
Istio Automation e239612955
Automator: update common-files@master in istio/proxy@master (#5438) 2024-04-04 14:10:08 -07:00
Istio Automation ede53e6ba9
Automator: update envoy@ in istio/proxy@master (#5435) 2024-04-03 19:42:08 -07:00
Istio Automation 58f7d913df
Automator: update common-files@master in istio/proxy@master (#5434) 2024-04-03 13:31:08 -07:00
Istio Automation 7509595c14
Automator: update common-files@master in istio/proxy@master (#5433) 2024-04-03 10:29:07 -07:00
Istio Automation 1a40f69791
Automator: update envoy@ in istio/proxy@master (#5432) 2024-04-02 19:19:07 -07:00
Istio Automation c3858cc798
Automator: update envoy@ in istio/proxy@master (#5430) 2024-04-01 19:46:05 -07:00
zirain c1732c57fb
sync with upstream (#5428)
* fix

* lint

* fix istio.stats

* update to 0331
2024-04-01 09:48:06 -07:00
Istio Automation 4ffa549090
Automator: update go-control-plane in istio/proxy@master (#5429) 2024-03-30 19:25:03 -07:00
Alex Xu 7aa67c2f39
Enable QAT key provider (#5425)
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
2024-03-28 07:36:01 -07:00
Istio Automation 50829a23f4
Automator: update envoy@ in istio/proxy@master (#5426) 2024-03-27 19:17:15 -07:00
Istio Automation 70d54bad4d
Automator: update envoy@ in istio/proxy@master (#5422) 2024-03-26 19:28:14 -07:00
Istio Automation e45cfa24d6
Automator: update common-files@master in istio/proxy@master (#5421) 2024-03-25 14:29:45 -07:00
zirain 9b7773624e
updat envoy and remove wavm (#5419)
* Automator: update envoy@ in istio/proxy@master

* update envoy and remove wavm

* disable qat

* fix stackdeiver test

Signed-off-by: zirain <zirain2009@gmail.com>

* enable envoy.transport_sockets.tls

---------

Signed-off-by: zirain <zirain2009@gmail.com>
Co-authored-by: istio-testing <istio-testing-bot@google.com>
2024-03-25 09:33:26 -07:00
Istio Automation 29d0152b7a
Automator: update go-control-plane in istio/proxy@master (#5418) 2024-03-23 19:24:24 -07:00
Istio Automation 81c893b1dd
Automator: update common-files@master in istio/proxy@master (#5417) 2024-03-21 08:47:07 -07:00
zirain bdbdd14f18
enable early_header_mutation (#5413) 2024-03-20 14:21:06 -07:00
Istio Automation 97ab83e47f
Automator: update go-control-plane in istio/proxy@master (#5410) 2024-03-16 19:25:02 -07:00
Istio Automation 5ffa62fe37
Automator: update envoy@ in istio/proxy@master (#5409) 2024-03-15 19:07:01 -07:00
Istio Automation 71848b612f
Automator: update common-files@master in istio/proxy@master (#5408) 2024-03-15 06:40:50 -07:00
zirain a7814860da
skip proto_util_speed_test on macm1 (#5407) 2024-03-14 20:06:49 -07:00
Istio Automation 4fe1aea7a2
Automator: update envoy@ in istio/proxy@master (#5406) 2024-03-14 19:34:48 -07:00
Istio Automation 37f805f90c
Automator: update envoy@ in istio/proxy@master (#5405) 2024-03-13 19:10:33 -07:00
dependabot[bot] efb2a6c21d
Bump google.golang.org/protobuf from 1.32.0 to 1.33.0 (#5404)
Bumps google.golang.org/protobuf from 1.32.0 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-13 18:17:33 -07:00
Istio Automation 40d2f770c1
Automator: update envoy@ in istio/proxy@master (#5403) 2024-03-12 18:59:07 -07:00
Istio Automation cc2eaadd3f
Automator: update envoy@ in istio/proxy@master (#5402) 2024-03-12 07:47:09 -07:00
Istio Automation f4119465c8
Automator: update common-files@master in istio/proxy@master (#5401) 2024-03-11 12:26:24 -07:00
Istio Automation 11084a8b7f
Automator: update common-files@master in istio/proxy@master (#5400) 2024-03-11 11:48:24 -07:00
Istio Automation 5cc5d07836
Automator: update common-files@master in istio/proxy@master (#5398) 2024-03-11 07:48:24 -07:00
Istio Automation 0b3b1cf651
Automator: update go-control-plane in istio/proxy@master (#5397) 2024-03-09 18:26:22 -08:00
Istio Automation 0e074e122a
Automator: update envoy@ in istio/proxy@master (#5396) 2024-03-09 17:42:22 -08:00
zirain c9687f5092
sync with upstream (#5395)
* Automator: update envoy@ in istio/proxy@master

* enable envoy.string_matcher.lua

Signed-off-by: zirain <zirain2009@gmail.com>

* fix LastFlag DownstreamRemoteReset

Signed-off-by: zirain <zirain2009@gmail.com>

* fix test

---------

Signed-off-by: zirain <zirain2009@gmail.com>
Co-authored-by: istio-testing <istio-testing-bot@google.com>
2024-03-08 19:16:22 -08:00
Istio Automation ce9a9b09cc
Automator: update envoy@ in istio/proxy@master (#5392) 2024-03-07 17:53:19 -08:00
Istio Automation 8da4e1b90f
Automator: update envoy@ in istio/proxy@master (#5389) 2024-03-06 19:52:26 -08:00
Istio Automation 4d98c31e0d
Automator: update envoy@ in istio/proxy@master (#5383) 2024-03-05 18:04:59 -08:00
Istio Automation cb6784387e
Automator: update common-files@master in istio/proxy@master (#5381) 2024-03-05 14:54:20 -08:00
Istio Automation 53e557174a
Automator: update common-files@master in istio/proxy@master (#5379) 2024-03-05 10:00:19 -08:00
zirain e78d4aa642
gen-extensions-doc (#5376) 2024-03-04 19:56:19 -08:00
Istio Automation af0cc1590e
Automator: update envoy@ in istio/proxy@master (#5375) 2024-03-04 19:06:19 -08:00
zirain 725addfc1c
envoy.tracers.opentelemetry.samplers.dynatrace (#5371)
* Automator: update envoy@ in istio/proxy@master

* enable envoy.tracers.opentelemetry.samplers.dynatrace

* update SHA

* update to 03-02

---------

Co-authored-by: istio-testing <istio-testing-bot@google.com>
2024-03-04 14:27:20 -08:00
Istio Automation a54a0030f1
Automator: update go-control-plane in istio/proxy@master (#5373) 2024-03-02 18:25:37 -08:00
Istio Automation 2256a29f2f
Automator: update common-files@master in istio/proxy@master (#5372) 2024-03-01 12:43:35 -08:00
Istio Automation 086d566ad2
Automator: update envoy@ in istio/proxy@master (#5368) 2024-02-29 06:30:47 -08:00
Istio Automation 9d6c288b11
Automator: update common-files@master in istio/proxy@master (#5366) 2024-02-28 11:19:37 -08:00
Istio Automation 6f0866269b
Automator: update envoy@ in istio/proxy@master (#5365) 2024-02-27 18:48:02 -08:00
Istio Automation 0cdc167c21
Automator: update envoy@ in istio/proxy@master (#5364) 2024-02-26 17:16:38 -08:00
Istio Automation ea184c9b6c
Automator: update common-files@master in istio/proxy@master (#5361) 2024-02-26 12:22:38 -08:00
Istio Automation babb28f9ee
Automator: update go-control-plane in istio/proxy@master (#5360) 2024-02-24 18:25:37 -08:00
Istio Automation ef2b3e19f9
Automator: update envoy@ in istio/proxy@master (#5358) 2024-02-23 17:15:31 -08:00
Istio Automation 63c5345d8e
Automator: update common-files@master in istio/proxy@master (#5357) 2024-02-23 16:45:31 -08:00
Istio Automation 94ccf26e52
Automator: update common-files@master in istio/proxy@master (#5355) 2024-02-23 11:52:21 -08:00
zirain a6391d407e
enable envoy.access_loggers.fluentd (#5353)
* Automator: update envoy@ in istio/proxy@master

* enable envoy.access_loggers.fluentd

---------

Co-authored-by: istio-testing <istio-testing-bot@google.com>
2024-02-22 20:38:20 -08:00
Istio Automation 3bf38fb24d
Automator: update common-files@master in istio/proxy@master (#5354) 2024-02-22 07:10:24 -08:00
Istio Automation fd0d0bc784
Automator: update envoy@ in istio/proxy@master (#5351) 2024-02-20 17:13:21 -08:00
Istio Automation d467d31087
Automator: update envoy@ in istio/proxy@master (#5350) 2024-02-19 20:19:10 -08:00
Istio Automation e4ca7c7995
Automator: update envoy@ in istio/proxy@master (#5349) 2024-02-18 17:19:12 -08:00
Istio Automation b0c9e69ef0
Automator: update go-control-plane in istio/proxy@master (#5348) 2024-02-17 18:26:12 -08:00
Istio Automation 4e9d81de87
Automator: update envoy@ in istio/proxy@master (#5347) 2024-02-17 17:55:12 -08:00
Istio Automation e89231c9f4
Automator: update envoy@ in istio/proxy@master (#5346) 2024-02-16 17:56:51 -08:00
Kuat dad212ee7d
fips: force stackdriver to use TLSv1.2 (#5339)
Change-Id: Icd1cd577c039512bb90234642719a8b5d3523567

Signed-off-by: Kuat Yessenov <kuat@google.com>
2024-02-16 10:45:50 -08:00
Istio Automation baed642483
Automator: update envoy@ in istio/proxy@master (#5340) 2024-02-15 17:16:48 -08:00
Istio Automation 23dd940c4a
Automator: update common-files@master in istio/proxy@master (#5337) 2024-02-15 10:58:43 -08:00
Istio Automation 115bd32b5b
Automator: update envoy@ in istio/proxy@master (#5336) 2024-02-14 19:16:59 -08:00
Istio Automation 1158a7ddf3
Automator: update common-files@master in istio/proxy@master (#5335) 2024-02-14 14:17:00 -08:00
Istio Automation 762eef909c
Automator: update common-files@master in istio/proxy@master (#5334) 2024-02-14 12:57:26 -08:00
Istio Automation 74a4588d20
Automator: update envoy@ in istio/proxy@master (#5332) 2024-02-13 18:58:25 -08:00
Istio Automation 8b1d67ecb9
Automator: update envoy@ in istio/proxy@master (#5329) 2024-02-12 17:17:34 -08:00
Istio Automation fafe0e2924
Automator: update common-files@master in istio/proxy@master (#5328) 2024-02-12 16:29:34 -08:00
Istio Automation 12fea69d17
Automator: update common-files@master in istio/proxy@master (#5327) 2024-02-12 08:24:33 -08:00
Istio Automation 4c1b321e00
Automator: update common-files@master in istio/proxy@master (#5326) 2024-02-12 07:25:34 -08:00
Istio Automation c3e672f9a9
Automator: update envoy@ in istio/proxy@master (#5324) 2024-02-11 13:08:53 -08:00
Istio Automation ceeed020ee
Automator: update go-control-plane in istio/proxy@master (#5325) 2024-02-10 18:29:23 -08:00
Istio Automation 06eba7bd76
Automator: update envoy@ in istio/proxy@master (#5321) 2024-02-09 20:39:56 -08:00
Istio Automation 57692647f5
Automator: update envoy@ in istio/proxy@master (#5315) 2024-02-08 17:11:24 -08:00
zirain 87f71d2362
wasm: align on xds attributes (#5300)
* wasm: align on xds attributes

Change-Id: Iaeb55c0dd5cb5801af28209bae2f669f42bc554d
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix test

* comment

* debug log

* fix

---------

Signed-off-by: Kuat Yessenov <kuat@google.com>
Co-authored-by: Kuat Yessenov <kuat@google.com>
2024-02-08 16:09:25 -08:00
jacob-delgado 5c91f7ebe1
Use go 1.22 (#5313) 2024-02-08 11:23:25 -08:00
Istio Automation 1ec4e7dcbd
Automator: update common-files@master in istio/proxy@master (#5312) 2024-02-08 09:51:25 -08:00
Istio Automation 4d0b802082
Automator: update envoy@ in istio/proxy@master (#5311) 2024-02-08 06:58:24 -08:00
Istio Automation 9d627e96f2
Automator: update common-files@master in istio/proxy@master (#5308) 2024-02-07 08:21:24 -08:00
Istio Automation 8fcbdd5bf8
Automator: update envoy@ in istio/proxy@master (#5306) 2024-02-07 07:18:56 -08:00
Istio Automation d897529345
Automator: update common-files@master in istio/proxy@master (#5304) 2024-02-05 18:06:34 -08:00
Istio Automation 001e04e952
Automator: update envoy@ in istio/proxy@master (#5303) 2024-02-05 17:12:43 -08:00
Istio Automation 5a12abb61b
Automator: update go-control-plane in istio/proxy@master (#5302) 2024-02-03 21:17:42 -08:00
Istio Automation 5af890956d
Automator: update envoy@ in istio/proxy@master (#5301) 2024-02-03 20:50:41 -08:00
Istio Automation 28aac26c60
Automator: update envoy@ in istio/proxy@master (#5299) 2024-02-03 06:04:41 -08:00
Istio Automation 0d3ac94f98
Automator: update envoy@ in istio/proxy@master (#5298) 2024-02-01 23:55:40 -08:00
Istio Automation eddbcdfd6e
Automator: update common-files@master in istio/proxy@master (#5297) 2024-02-01 14:14:39 -08:00
Istio Automation ea8bf21a68
Automator: update envoy@ in istio/proxy@master (#5296) 2024-01-31 18:05:39 -08:00
Istio Automation 0ea82dad35
Automator: update common-files@master in istio/proxy@master (#5295) 2024-01-31 16:08:39 -08:00
Istio Automation fc31962312
Automator: update envoy@ in istio/proxy@master (#5294) 2024-01-30 18:43:42 -08:00
Istio Automation 0223018787
Automator: update envoy@ in istio/proxy@master (#5293) 2024-01-29 17:39:28 -08:00
Istio Automation be95231d27
Automator: update go-control-plane in istio/proxy@master (#5292) 2024-01-27 18:26:31 -08:00
Istio Automation 7f299d6563
Automator: update envoy@ in istio/proxy@master (#5291) 2024-01-26 18:15:31 -08:00
Istio Automation 19b5c3c248
Automator: update envoy@ in istio/proxy@master (#5290) 2024-01-25 17:43:54 -08:00
Istio Automation 66295f7ae2
Automator: update common-files@master in istio/proxy@master (#5289) 2024-01-25 09:50:32 -08:00
Istio Automation 153b31e0b0
Automator: update envoy@ in istio/proxy@master (#5288) 2024-01-24 17:22:02 -08:00
Aryan Gupta 3923ea9db1
update go-control-plane (#5286) 2024-01-24 11:31:10 -08:00
Istio Automation 9cce369787
Automator: update envoy@ in istio/proxy@master (#5283) 2024-01-23 18:03:09 -08:00
198 changed files with 3463 additions and 13718 deletions

View File

@ -14,7 +14,10 @@ build:remote --remote_timeout=7200
# ========================================
# Enable libc++ and C++20 by default.
build:linux --config=libc++20
build:linux --config=clang
# put /usr/local/bin before /usr/bin to avoid picking up wrong python3.6 when building envoy.tls.key_providers.cryptomb
build:linux --action_env=PATH=/usr/lib/llvm/bin:/usr/local/bin:/bin:/usr/bin
# Need for CI image to pickup docker-credential-gcloud, PATH is fixed in rbe-toolchain-* configs.
build:remote-ci --action_env=PATH=/usr/local/google-cloud-sdk/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/llvm/bin
@ -23,9 +26,6 @@ build:remote-ci --action_env=PATH=/usr/local/google-cloud-sdk/bin:/usr/sbin:/usr
# See: https://github.com/envoyproxy/envoy/pull/6519
build --define path_normalization_by_default=true
# Heap profiler is supported only with gperf tcmalloc, not google tcmalloc.
# See: https://github.com/istio/istio/issues/28233
build:linux --define tcmalloc=gperftools
build:macos --define tcmalloc=disabled
# Build with embedded V8-based WebAssembly runtime.
@ -50,22 +50,17 @@ build:debug -c dbg
build --cxxopt -Wformat
build --cxxopt -Wformat-security
# Link pthread for flatbuffers
build --host_linkopt=-pthread
build:clang --host_action_env=CC=
build:clang --host_action_env=CXX=
# CI sanitizer configuration
#
build:clang-asan-ci --config=clang-asan
build:clang-asan-ci --action_env=ENVOY_UBSAN_VPTR=1
build:clang-asan-ci --copt=-fsanitize=vptr,function
build:clang-asan-ci --linkopt=-fsanitize=vptr,function
build:clang-asan-ci --config=asan
build:clang-asan-ci --linkopt='-L/usr/lib/llvm/lib/x86_64-unknown-linux-gnu'
build:clang-asan-ci --linkopt='-Wl,-rpath,/usr/lib/llvm/lib/x86_64-unknown-linux-gnu'
build:clang-asan-ci --linkopt='-L/usr/lib/llvm/lib/clang/14.0.0/lib/x86_64-unknown-linux-gnu'
build:clang-asan-ci --linkopt=-l:libclang_rt.ubsan_standalone.a
build:clang-asan-ci --linkopt=-l:libclang_rt.ubsan_standalone_cxx.a
build:clang-tsan-ci --config=clang-tsan
build:clang-tsan-ci --config=tsan
build:clang-tsan-ci --linkopt=-L/opt/libcxx_tsan/lib
build:clang-tsan-ci --linkopt=-Wl,-rpath,/opt/libcxx_tsan/lib

View File

@ -1 +1 @@
6.3.2
7.6.0

View File

@ -1,6 +1,6 @@
{
"name": "istio build-tools",
"image": "gcr.io/istio-testing/build-tools:master-19f0fb6c28d080531991023434dfadb2687444e2",
"image": "gcr.io/istio-testing/build-tools-proxy:master-8e6480403f5cf4c9a4cd9d65174d01850e632e1a",
"privileged": true,
"remoteEnv": {
"USE_GKE_GCLOUD_AUTH_PLUGIN": "True",

1
.gitattributes vendored
View File

@ -8,6 +8,7 @@
*.gen.yaml linguist-generated=true
*.gen.json linguist-generated=true
*_pb2.py linguist-generated=true
manifests/charts/**/profile*.yaml linguist-generated=true
go.sum merge=union
vendor/** linguist-vendored
common/** linguist-vendored

14
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,14 @@
# Configures Depdendabot to PR go security updates only
version: 2
updates:
# Go configuration for master branch
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"
# Limit number of open PRs to 0 so that we only get security updates
# See https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates
open-pull-requests-limit: 0
labels:
- "release-notes-none"

5
.gitignore vendored
View File

@ -12,10 +12,5 @@ test/envoye2e/tcp_metadata_exchange/testoutput
test/envoye2e/http_metadata_exchange/testoutput
*.wasm
.vscode
/extensions/common/flatbuffers
/extensions/common/node_info_generated.h
/extensions/common/node_info_bfbs_generated.h
/extensions/common/proxy_expr.h
/extensions/common/nlohmann_json.hpp
out/
.cache

26
BUILD
View File

@ -1,3 +1,8 @@
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_binary",
)
# Copyright 2016 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@ -15,10 +20,6 @@
################################################################################
#
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_binary",
)
exports_files(["LICENSE"])
@ -29,17 +30,18 @@ config_setting(
},
)
ISTIO_EXTENSIONS = [
"//source/extensions/common/workload_discovery:api_lib", # Experimental: WIP
"//source/extensions/filters/http/alpn:config_lib",
"//source/extensions/filters/http/istio_stats",
"//source/extensions/filters/http/peer_metadata:filter_lib",
"//source/extensions/filters/network/metadata_exchange:config_lib",
]
envoy_cc_binary(
name = "envoy",
repository = "@envoy",
deps = [
"//extensions/access_log_policy:access_log_policy_lib",
"//extensions/stackdriver:stackdriver_plugin",
"//source/extensions/common/workload_discovery:api_lib", # Experimental: WIP
"//source/extensions/filters/http/alpn:config_lib",
"//source/extensions/filters/http/istio_stats",
"//source/extensions/filters/http/peer_metadata:filter_lib",
"//source/extensions/filters/network/metadata_exchange:config_lib",
deps = ISTIO_EXTENSIONS + [
"@envoy//source/exe:envoy_main_entry_lib",
],
)

View File

@ -7,3 +7,16 @@ to find out how you can help.
## Prerequisites
To make sure you're ready to build Envoy, clone and follow the upstream Envoy [build instructions](https://github.com/envoyproxy/envoy/blob/main/bazel/README.md). Be sure to copy clang.bazelrc into this directory after running the setup_clang script. Confirm that your environment is ready to go by running `bazel build --config=clang --define=wasm=disabled :envoy` (in this directory).
## How to use a devcontainer
1. Change the image in .devcontainer.json to `build-tools-proxy` instead of `build-tools`
2. Open the directory in a container with the Remote - Containers extension
3. Install the following extensions:
- [clangd](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd)
- [bazel-stack-vscode-cc](https://marketplace.visualstudio.com/items?itemName=StackBuild.bazel-stack-vscode-cc)
4. Update clangd and reload the container
5. Edit the new `bsv.cc.compdb.targets` workspace setting and set it to `//:envoy_tar`
6. Execute `Bazel/C++: Generate Compilation Database` within vscode
Note: if you have a remote bazel cache or something mounted in your build container for your normal proxy builds, you'll need to configure that in the devcontainer with runArgs.

View File

@ -19,7 +19,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
SHELL := /bin/bash
SHELL := /usr/bin/env bash
# allow optional per-repo overrides
-include Makefile.overrides.mk

View File

@ -75,7 +75,7 @@ clean:
.PHONY: gen-extensions-doc
gen-extensions-doc:
buf generate --path extensions/
buf generate --path source/extensions/filters
gen:
@scripts/gen-testdata.sh
@ -89,7 +89,7 @@ test:
bazel $(BAZEL_STARTUP_ARGS) test $(BAZEL_BUILD_ARGS) $(BAZEL_CONFIG_CURRENT) -- $(BAZEL_TEST_TARGETS); \
fi
if [ -n "$(E2E_TEST_TARGETS)" ]; then \
env ENVOY_DEBUG=$(TEST_ENVOY_DEBUG) ENVOY_PATH=$(shell bazel info $(BAZEL_BUILD_ARGS) $(BAZEL_CONFIG_CURRENT) bazel-bin)/envoy $(E2E_TEST_ENVS) GO111MODULE=on go test -timeout 30m $(E2E_TEST_FLAGS) $(E2E_TEST_TARGETS); \
env ENVOY_DEBUG=$(TEST_ENVOY_DEBUG) ENVOY_PATH=$(shell bazel $(BAZEL_STARTUP_ARGS) info $(BAZEL_BUILD_ARGS) $(BAZEL_CONFIG_CURRENT) bazel-bin)/envoy $(E2E_TEST_ENVS) GO111MODULE=on go test -timeout 30m $(E2E_TEST_FLAGS) $(E2E_TEST_TARGETS); \
fi
test_asan: BAZEL_CONFIG_CURRENT = $(BAZEL_CONFIG_ASAN)
@ -105,33 +105,9 @@ check:
@echo >&2 "Please use \"make lint\" instead."
@false
lint: lint-copyright-banner format-go lint-go tidy-go lint-scripts
lint: lint-copyright-banner format-go lint-go tidy-go lint-scripts gen-extensions-doc
@scripts/check-repository.sh
@scripts/check-style.sh
@scripts/verify-last-flag-matches-upstream.sh
protoc = protoc -I common-protos -I extensions
protoc_gen_docs_plugin := --docs_out=camel_case_fields=false,warnings=true,per_file=true,mode=html_fragment_with_front_matter:$(repo_dir)/
metadata_exchange_path := extensions/metadata_exchange
metadata_exchange_protos := $(wildcard $(metadata_exchange_path)/*.proto)
metadata_exchange_docs := $(metadata_exchange_protos:.proto=.pb.html)
$(metadata_exchange_docs): $(metadata_exchange_protos)
@$(protoc) -I ./extensions $(protoc_gen_docs_plugin)$(metadata_exchange_path) $^
stackdriver_path := extensions/stackdriver/config/v1alpha1
stackdriver_protos := $(wildcard $(stackdriver_path)/*.proto)
stackdriver_docs := $(stackdriver_protos:.proto=.pb.html)
$(stackdriver_docs): $(stackdriver_protos)
@$(protoc) -I ./extensions $(protoc_gen_docs_plugin)$(stackdriver_path) $^
accesslog_policy_path := extensions/access_log_policy/config/v1alpha1
accesslog_policy_protos := $(wildcard $(accesslog_policy_path)/*.proto)
accesslog_policy_docs := $(accesslog_policy_protos:.proto=.pb.html)
$(accesslog_policy_docs): $(accesslog_policy_protos)
@$(protoc) -I ./extensions $(protoc_gen_docs_plugin)$(accesslog_policy_path) $^
extensions-docs: $(metadata_exchange_docs) $(stackdriver_docs) $(accesslog_policy_docs)
test_release:
ifeq "$(shell uname -m)" "x86_64"

View File

@ -2,3 +2,7 @@
The Istio Proxy is a microservice proxy that can be used on the client and server side, and forms a microservice mesh.
It is based on [Envoy](http://envoyproxy.io) with the addition of several policy and telemetry extensions.
According to the [conclusion from Istio workgroup meeting on 4-17-2024](https://docs.google.com/document/d/1wsa06GGiq1LEGwhkiPP0FKIZJqdAiue-VeBonWAzAyk/edit#heading=h.ma5hboh81yw):
- New extensions are not added unless they are part of core APIs

View File

@ -3,5 +3,5 @@
Here are some resources to help you understand and use Istio:
- For in-depth information about how to use Istio, visit [istio.io](https://istio.io)
- To ask questions and get assistance from our community, visit [discuss.istio.io](https://discuss.istio.io)
- To learn how to participate in our overall community, visit [our community page](https://istio.io/about/community)
- To ask questions and get assistance from our community, visit [GitHub Discussions](https://github.com/istio/istio/discussions)
- To learn how to participate in our overall community, visit [our community page](https://istio.io/latest/get-involved/)

View File

@ -22,10 +22,10 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# 1. Determine SHA256 `wget https://github.com/envoyproxy/envoy/archive/$COMMIT.tar.gz && sha256sum $COMMIT.tar.gz`
# 2. Update .bazelversion, envoy.bazelrc and .bazelrc if needed.
#
# Commit date: 2024-01-22
ENVOY_SHA = "8879434500ba7e76ff27d41087939bfab635f358"
# Commit date: 2025-07-10
ENVOY_SHA = "46bb6bc3dc41a684671fd4811eddfe82207a6d21"
ENVOY_SHA256 = "6bfaa75a783ab91f6f3ccd9b15ccc814b1b41e0f00b6e2a10fa2ed5fbdbefa34"
ENVOY_SHA256 = "e3ca4967f3cfd343cbf9983c7ec85eb1845c5d3b219e045cf008e730e9c06b61"
ENVOY_ORG = "envoyproxy"

View File

@ -7,6 +7,7 @@ ENVOY_EXTENSIONS = {
"envoy.access_loggers.file": "//source/extensions/access_loggers/file:config",
"envoy.access_loggers.extension_filters.cel": "//source/extensions/access_loggers/filters/cel:config",
"envoy.access_loggers.fluentd" : "//source/extensions/access_loggers/fluentd:config",
"envoy.access_loggers.http_grpc": "//source/extensions/access_loggers/grpc:http_config",
"envoy.access_loggers.tcp_grpc": "//source/extensions/access_loggers/grpc:tcp_config",
"envoy.access_loggers.open_telemetry": "//source/extensions/access_loggers/open_telemetry:config",
@ -43,7 +44,6 @@ ENVOY_EXTENSIONS = {
#
"envoy.grpc_credentials.file_based_metadata": "//source/extensions/grpc_credentials/file_based_metadata:config",
"envoy.grpc_credentials.aws_iam": "//source/extensions/grpc_credentials/aws_iam:config",
#
# WASM
@ -94,6 +94,11 @@ ENVOY_EXTENSIONS = {
"envoy.matching.actions.format_string": "//source/extensions/matching/actions/format_string:config",
#
# StringMatchers
#
"envoy.string_matcher.lua": "//source/extensions/string_matcher/lua:config",
#
# HTTP filters
#
@ -112,6 +117,7 @@ ENVOY_EXTENSIONS = {
"envoy.filters.http.cors": "//source/extensions/filters/http/cors:config",
"envoy.filters.http.composite": "//source/extensions/filters/http/composite:config",
"envoy.filters.http.connect_grpc_bridge": "//source/extensions/filters/http/connect_grpc_bridge:config",
"envoy.filters.http.credential_injector": "//source/extensions/filters/http/credential_injector:config",
"envoy.filters.http.csrf": "//source/extensions/filters/http/csrf:config",
"envoy.filters.http.decompressor": "//source/extensions/filters/http/decompressor:config",
"envoy.filters.http.dynamic_forward_proxy": "//source/extensions/filters/http/dynamic_forward_proxy:config",
@ -139,6 +145,7 @@ ENVOY_EXTENSIONS = {
"envoy.filters.http.on_demand": "//source/extensions/filters/http/on_demand:config",
"envoy.filters.http.original_src": "//source/extensions/filters/http/original_src:config",
"envoy.filters.http.ratelimit": "//source/extensions/filters/http/ratelimit:config",
"envoy.filters.http.rate_limit_quota": "//source/extensions/filters/http/rate_limit_quota:config",
"envoy.filters.http.rbac": "//source/extensions/filters/http/rbac:config",
"envoy.filters.http.router": "//source/extensions/filters/http/router:config",
"envoy.filters.http.set_filter_state": "//source/extensions/filters/http/set_filter_state:config",
@ -195,6 +202,7 @@ ENVOY_EXTENSIONS = {
# Resource monitors
#
"envoy.resource_monitors.cpu_utilization": "//source/extensions/resource_monitors/cpu_utilization:config",
"envoy.resource_monitors.fixed_heap": "//source/extensions/resource_monitors/fixed_heap:config",
"envoy.resource_monitors.injected_resource": "//source/extensions/resource_monitors/injected_resource:config",
"envoy.resource_monitors.downstream_connections": "//source/extensions/resource_monitors/downstream_connections:config",
@ -223,10 +231,8 @@ ENVOY_EXTENSIONS = {
# Tracers
#
"envoy.tracers.dynamic_ot": "//source/extensions/tracers/dynamic_ot:config",
"envoy.tracers.datadog": "//source/extensions/tracers/datadog:config",
"envoy.tracers.zipkin": "//source/extensions/tracers/zipkin:config",
"envoy.tracers.opencensus": "//source/extensions/tracers/opencensus:config",
"envoy.tracers.xray": "//source/extensions/tracers/xray:config",
"envoy.tracers.skywalking": "//source/extensions/tracers/skywalking:config",
"envoy.tracers.opentelemetry": "//source/extensions/tracers/opentelemetry:config",
@ -242,7 +248,8 @@ ENVOY_EXTENSIONS = {
# OpenTelemetry tracer samplers
#
"envoy.tracers.opentelemetry.samplers.always_on": "//source/extensions/tracers/opentelemetry/samplers/always_on:config",
"envoy.tracers.opentelemetry.samplers.always_on": "//source/extensions/tracers/opentelemetry/samplers/always_on:config",
"envoy.tracers.opentelemetry.samplers.dynatrace": "//source/extensions/tracers/opentelemetry/samplers/dynatrace:config",
#
# Transport sockets
@ -254,6 +261,7 @@ ENVOY_EXTENSIONS = {
"envoy.transport_sockets.tap": "//source/extensions/transport_sockets/tap:config",
"envoy.transport_sockets.starttls": "//source/extensions/transport_sockets/starttls:config",
"envoy.transport_sockets.tcp_stats": "//source/extensions/transport_sockets/tcp_stats:config",
"envoy.transport_sockets.tls": "//source/extensions/transport_sockets/tls:config",
"envoy.transport_sockets.internal_upstream": "//source/extensions/transport_sockets/internal_upstream:config",
#
@ -304,7 +312,6 @@ ENVOY_EXTENSIONS = {
"envoy.wasm.runtime.null": "//source/extensions/wasm_runtime/null:config",
"envoy.wasm.runtime.v8": "//source/extensions/wasm_runtime/v8:config",
"envoy.wasm.runtime.wamr": "//source/extensions/wasm_runtime/wamr:config",
"envoy.wasm.runtime.wavm": "//source/extensions/wasm_runtime/wavm:config",
"envoy.wasm.runtime.wasmtime": "//source/extensions/wasm_runtime/wasmtime:config",
#
@ -350,7 +357,7 @@ ENVOY_EXTENSIONS = {
# QUIC extensions
#
"envoy.quic.deterministic_connection_id_generator": "//source/extensions/quic/connection_id_generator:envoy_deterministic_connection_id_generator_config",
"envoy.quic.deterministic_connection_id_generator": "//source/extensions/quic/connection_id_generator/deterministic:envoy_deterministic_connection_id_generator_config",
"envoy.quic.crypto_stream.server.quiche": "//source/extensions/quic/crypto_stream:envoy_quic_default_crypto_server_stream",
"envoy.quic.proof_source.filter_chain": "//source/extensions/quic/proof_source:envoy_quic_default_proof_source",
@ -411,6 +418,12 @@ ENVOY_EXTENSIONS = {
"envoy.load_balancing_policies.ring_hash": "//source/extensions/load_balancing_policies/ring_hash:config",
"envoy.load_balancing_policies.subset": "//source/extensions/load_balancing_policies/subset:config",
"envoy.load_balancing_policies.cluster_provided": "//source/extensions/load_balancing_policies/cluster_provided:config",
"envoy.load_balancing_policies.override_host": "//source/extensions/load_balancing_policies/override_host:config",
#
# HTTP Early Header Mutation
#
"envoy.http.early_header_mutation.header_mutation": "//source/extensions/http/early_header_mutation/header_mutation:config",
#
# Config Subscription
@ -430,6 +443,13 @@ ENVOY_EXTENSIONS = {
#
"envoy.router.cluster_specifier_plugin.lua": "//source/extensions/router/cluster_specifiers/lua:config",
#
# Injected credentials
#
"envoy.http.injected_credentials.generic": "//source/extensions/http/injected_credentials/generic:config",
"envoy.http.injected_credentials.oauth2": "//source/extensions/http/injected_credentials/oauth2:config",
}
ENVOY_CONTRIB_EXTENSIONS = {

View File

@ -1 +1 @@
1f7ce310688a91fa34b704db34a2ccda43b50073
d46067e1a8ba3db4abe2635af5807f00ba1981e6

View File

@ -50,7 +50,7 @@ lint-python:
@${FINDFILES} -name '*.py' \( ! \( -name '*_pb2.py' \) \) -print0 | ${XARGS} autopep8 --max-line-length 160 --exit-code -d
lint-markdown:
@${FINDFILES} -name '*.md' -print0 | ${XARGS} mdl --ignore-front-matter --style common/config/mdl.rb
@${FINDFILES} -name '*.md' -not -path './manifests/addons/dashboards/*' -print0 | ${XARGS} mdl --ignore-front-matter --style common/config/mdl.rb
lint-links:
@${FINDFILES} -name '*.md' -print0 | ${XARGS} awesome_bot --skip-save-results --allow_ssl --allow-timeout --allow-dupe --allow-redirect --white-list ${MARKDOWN_LINT_ALLOWLIST}
@ -101,12 +101,16 @@ update-common:
@git clone -q --depth 1 --single-branch --branch $(UPDATE_BRANCH) https://github.com/$(BUILD_TOOLS_ORG)/common-files $(TMP)/common-files
@cd $(TMP)/common-files ; git rev-parse HEAD >files/common/.commonfiles.sha
@rm -fr common
# istio/community has its own CONTRIBUTING.md file.
@CONTRIB_OVERRIDE=$(shell grep -l "istio/community/blob/master/CONTRIBUTING.md" CONTRIBUTING.md)
@if [ "$(CONTRIB_OVERRIDE)" != "CONTRIBUTING.md" ]; then\
rm $(TMP)/common-files/files/CONTRIBUTING.md;\
fi
@cp -a $(TMP)/common-files/files/* $(TMP)/common-files/files/.devcontainer $(TMP)/common-files/files/.gitattributes $(shell pwd)
@rm -fr $(TMP)/common-files
@if [ "$(AUTOMATOR_REPO)" == "proxy" ]; then\
sed -i -e 's/build-tools:/build-tools-proxy:/g' .devcontainer/devcontainer.json;\
fi
@$(or $(COMMONFILES_POSTPROCESS), true)
check-clean-repo:

View File

@ -1,59 +0,0 @@
# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY
#
# The original version of this file is located in the https://github.com/istio/common-files repo.
# If you're looking at this file in a different repo and want to make a change, please go to the
# common-files repo, make the change there and check it in. Then come back to this repo and run
# "make update-common".
service:
# When updating this, also update the version stored in docker/build-tools/Dockerfile in the istio/tools repo.
golangci-lint-version: 1.55.x # use the fixed version to not introduce new linters unexpectedly
run:
# timeout for analysis, e.g. 30s, 5m, default is 1m
deadline: 20m
build-tags:
- integ
- integfuzz
# which dirs to skip: they won't be analyzed;
# can use regexp here: generated.*, regexp is applied on full path;
# default value is empty list, but next dirs are always skipped independently
# from this option's value:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
skip-dirs:
- genfiles$
- vendor$
# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
skip-files:
- ".*\\.pb\\.go"
- ".*\\.gen\\.go"
linters:
disable-all: true
enable:
- goimports
- gofumpt
- gci
fast: false
linters-settings:
gci:
sections:
- standard # Captures all standard packages if they do not match another section.
- default # Contains all imports that could not be matched to another section type.
- prefix(istio.io/) # Groups all imports with the specified Prefix.
goimports:
# put imports beginning with prefix after 3rd-party packages;
# it's a comma-separated list of prefixes
local-prefixes: istio.io/
issues:
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0

View File

@ -1,276 +1,221 @@
# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY
#
# The original version of this file is located in the https://github.com/istio/common-files repo.
# If you're looking at this file in a different repo and want to make a change, please go to the
# common-files repo, make the change there and check it in. Then come back to this repo and run
# "make update-common".
service:
# When updating this, also update the version stored in docker/build-tools/Dockerfile in the istio/tools repo.
golangci-lint-version: 1.55.x # use the fixed version to not introduce new linters unexpectedly
version: "2"
run:
# timeout for analysis, e.g. 30s, 5m, default is 1m
deadline: 20m
build-tags:
- integ
- integfuzz
# which dirs to skip: they won't be analyzed;
# can use regexp here: generated.*, regexp is applied on full path;
# default value is empty list, but next dirs are always skipped independently
# from this option's value:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
skip-dirs:
- genfiles$
- vendor$
# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
skip-files:
- ".*\\.pb\\.go"
- ".*\\.gen\\.go"
linters:
disable-all: true
default: none
enable:
- errcheck
- exportloopref
- copyloopvar
- depguard
- errcheck
- gocritic
- gofumpt
- goimports
- revive
- gosimple
- gosec
- govet
- ineffassign
- lll
- misspell
- revive
- staticcheck
- stylecheck
- typecheck
- unconvert
- unparam
- unused
- gci
- gosec
fast: false
linters-settings:
errcheck:
# report about not checking of errors in type assertions: `a := b.(MyStruct)`;
# default is false: such cases aren't reported by default.
check-type-assertions: false
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
# default is false: such cases aren't reported by default.
check-blank: false
govet:
# report about shadowed variables
check-shadowing: false
goimports:
# put imports beginning with prefix after 3rd-party packages;
# it's a comma-separated list of prefixes
local-prefixes: istio.io/
maligned:
# print struct with more effective memory layout or not, false by default
suggest-new: true
misspell:
# Correct spellings using locale preferences for US or UK.
# Default is to use a neutral variety of English.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
locale: US
ignore-words:
- cancelled
lll:
# max line length, lines longer will be reported. Default is 120.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
line-length: 160
# tab width in spaces. Default to 1.
tab-width: 1
revive:
ignore-generated-header: false
severity: "warning"
confidence: 0.0
error-code: 2
warning-code: 1
settings:
depguard:
rules:
DenyGogoProtobuf:
files:
- $all
deny:
- pkg: github.com/gogo/protobuf
desc: gogo/protobuf is deprecated, use golang/protobuf
errcheck:
check-type-assertions: false
check-blank: false
gocritic:
disable-all: true
enabled-checks:
- appendCombine
- argOrder
- assignOp
- badCond
- boolExprSimplify
- builtinShadow
- captLocal
- caseOrder
- codegenComment
- commentedOutCode
- commentedOutImport
- defaultCaseOrder
- deprecatedComment
- docStub
- dupArg
- dupBranchBody
- dupCase
- dupSubExpr
- elseif
- emptyFallthrough
- equalFold
- flagDeref
- flagName
- hexLiteral
- indexAlloc
- initClause
- methodExprCall
- nilValReturn
- octalLiteral
- offBy1
- rangeExprCopy
- regexpMust
- sloppyLen
- stringXbytes
- switchTrue
- typeAssertChain
- typeSwitchVar
- typeUnparen
- underef
- unlambda
- unnecessaryBlock
- unslice
- valSwap
- weakCond
gosec:
includes:
- G401
- G402
- G404
govet:
disable:
- shadow
lll:
line-length: 160
tab-width: 1
misspell:
locale: US
ignore-rules:
- cancelled
revive:
confidence: 0
severity: warning
rules:
- name: blank-imports
- name: context-keys-type
- name: time-naming
- name: var-declaration
- name: unexported-return
- name: errorf
- name: context-as-argument
- name: dot-imports
- name: error-return
- name: error-strings
- name: error-naming
- name: increment-decrement
- name: var-naming
- name: package-comments
- name: range
- name: receiver-naming
- name: indent-error-flow
- name: superfluous-else
- name: modifies-parameter
- name: unreachable-code
- name: struct-tag
- name: constant-logical-expr
- name: bool-literal-in-expr
- name: redefines-builtin-id
- name: imports-blocklist
- name: range-val-in-closure
- name: range-val-address
- name: waitgroup-by-value
- name: atomic
- name: call-to-gc
- name: duplicated-imports
- name: string-of-int
- name: defer
arguments:
- - call-chain
- name: unconditional-recursion
- name: identical-branches
unparam:
check-exported: false
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- name: blank-imports
- name: context-keys-type
- name: time-naming
- name: var-declaration
- name: unexported-return
- name: errorf
- name: context-as-argument
- name: dot-imports
- name: error-return
- name: error-strings
- name: error-naming
- name: increment-decrement
- name: var-naming
- name: package-comments
- name: range
- name: receiver-naming
- name: indent-error-flow
- name: superfluous-else
- name: modifies-parameter
- name: unreachable-code
- name: struct-tag
- name: constant-logical-expr
- name: bool-literal-in-expr
- name: redefines-builtin-id
- name: imports-blacklist
- name: range-val-in-closure
- name: range-val-address
- name: waitgroup-by-value
- name: atomic
- name: call-to-gc
- name: duplicated-imports
- name: string-of-int
- name: defer
arguments:
- - "call-chain"
- name: unconditional-recursion
- name: identical-branches
# the following rules can be enabled in the future
# - name: empty-lines
# - name: confusing-results
# - name: empty-block
# - name: get-return
# - name: confusing-naming
# - name: unexported-naming
# - name: early-return
# - name: unused-parameter
# - name: unnecessary-stmt
# - name: deep-exit
# - name: import-shadowing
# - name: modifies-value-receiver
# - name: unused-receiver
# - name: bare-return
# - name: flag-parameter
# - name: unhandled-error
# - name: if-return
unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
unparam:
# call graph construction algorithm (cha, rta). In general, use cha for libraries,
# and rta for programs with main packages. Default is cha.
algo: cha
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
gci:
sections:
- standard # Captures all standard packages if they do not match another section.
- default # Contains all imports that could not be matched to another section type.
- prefix(istio.io/) # Groups all imports with the specified Prefix.
gocritic:
enabled-checks:
- appendCombine
- argOrder
- assignOp
- badCond
- boolExprSimplify
- builtinShadow
- captLocal
- caseOrder
- codegenComment
- commentedOutCode
- commentedOutImport
- defaultCaseOrder
- deprecatedComment
- docStub
- dupArg
- dupBranchBody
- dupCase
- dupSubExpr
- elseif
- emptyFallthrough
- equalFold
- flagDeref
- flagName
- hexLiteral
- indexAlloc
- initClause
- methodExprCall
- nilValReturn
- octalLiteral
- offBy1
- rangeExprCopy
- regexpMust
- sloppyLen
- stringXbytes
- switchTrue
- typeAssertChain
- typeSwitchVar
- typeUnparen
- underef
- unlambda
- unnecessaryBlock
- unslice
- valSwap
- weakCond
# Unused
# - yodaStyleExpr
# - appendAssign
# - commentFormatting
# - emptyStringTest
# - exitAfterDefer
# - ifElseChain
# - hugeParam
# - importShadow
# - nestingReduce
# - paramTypeCombine
# - ptrToRefParam
# - rangeValCopy
# - singleCaseSwitch
# - sloppyReassign
# - unlabelStmt
# - unnamedResult
# - wrapperFunc
depguard:
rules:
DenyGogoProtobuf:
files:
- $all
deny:
- pkg: github.com/gogo/protobuf
desc: "gogo/protobuf is deprecated, use golang/protobuf"
gosec:
includes:
- G401
- G402
- G404
- linters:
- errcheck
- maligned
path: _test\.go$|tests/|samples/
- path: _test\.go$
text: 'dot-imports: should not use dot imports'
- linters:
- staticcheck
text: 'SA1019: package github.com/golang/protobuf/jsonpb'
- linters:
- staticcheck
text: 'SA1019: "github.com/golang/protobuf/jsonpb"'
- linters:
- staticcheck
text: 'SA1019: grpc.Dial is deprecated: use NewClient instead'
- linters:
- staticcheck
text: 'SA1019: grpc.DialContext is deprecated: use NewClient instead'
- linters:
- staticcheck
text: 'SA1019: grpc.WithBlock is deprecated'
- linters:
- staticcheck
text: 'SA1019: grpc.FailOnNonTempDialError'
- linters:
- staticcheck
text: 'SA1019: grpc.WithReturnConnectionError'
- path: (.+)\.go$
text: composite literal uses unkeyed fields
# TODO: remove following rule in the future
- linters:
- staticcheck
text: 'QF'
- linters:
- staticcheck
text: 'ST1005'
- linters:
- staticcheck
text: 'S1007'
paths:
- .*\.pb\.go
- .*\.gen\.go
- genfiles$
- vendor$
- third_party$
- builtin$
- examples$
issues:
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
# excluded by default patterns execute `golangci-lint run --help`
exclude:
- composite literal uses unkeyed fields
exclude-rules:
# Exclude some linters from running on test files.
- path: _test\.go$|^tests/|^samples/
linters:
- errcheck
- maligned
- path: _test\.go$
text: "dot-imports: should not use dot imports"
# We need to use the deprecated module since the jsonpb replacement is not backwards compatible.
- linters:
- staticcheck
text: "SA1019: package github.com/golang/protobuf/jsonpb"
- linters:
- staticcheck
text: 'SA1019: "github.com/golang/protobuf/jsonpb"'
# Independently from option `exclude` we use default exclude patterns,
# it can be disabled by this option. To list all
# excluded by default patterns execute `golangci-lint run --help`.
# Default value for this option is true.
exclude-use-default: true
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-issues-per-linter: 0
max-same-issues: 0
formatters:
enable:
- gci
- gofumpt
- goimports
settings:
gci:
sections:
- standard
- default
- prefix(istio.io/)
goimports:
local-prefixes:
- istio.io/
exclusions:
generated: lax
paths:
- .*\.pb\.go
- .*\.gen\.go
- genfiles$
- vendor$
- third_party$
- builtin$
- examples$

View File

@ -13,3 +13,5 @@ trustedRegistries:
- gcr.io
- docker.io
- quay.io
- "*.pkg.dev"
- "cgr.dev"

View File

@ -125,4 +125,21 @@ allowlisted_modules:
# Simplified BSD (BSD-2-Clause): https://github.com/russross/blackfriday/blob/master/LICENSE.txt
- github.com/russross/blackfriday
- github.com/russross/blackfriday/v2
- github.com/russross/blackfriday/v2
# W3C Test Suite License, W3C 3-clause BSD License
# gonum uses this for its some of its test files
# gonum.org/v1/gonum/graph/formats/rdf/testdata/LICENSE.md
- gonum.org/v1/gonum
# BSD 3-clause: https://github.com/go-inf/inf/blob/v0.9.1/LICENSE
- gopkg.in/inf.v0
# BSD 3-clause: https://github.com/go-git/gcfg/blob/main/LICENSE
- github.com/go-git/gcfg
# Apache 2.0
- github.com/aws/smithy-go
# Simplified BSD License: https://github.com/gomarkdown/markdown/blob/master/LICENSE.txt
- github.com/gomarkdown/markdown

View File

@ -24,6 +24,7 @@ function write_patch_file() {
git diff > "${PATCH_OUT}"
[ -n "${JOB_NAME}" ] && [ -n "${BUILD_ID}" ]
# shellcheck disable=SC2319
IN_PROW="$?"
# Don't persist large diffs (30M+) on CI

View File

@ -21,4 +21,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
golangci-lint run --fix -c ./common/config/.golangci-format.yml
golangci-lint run --fix -c ./common/config/.golangci.yml

View File

@ -32,7 +32,10 @@ set -x
####################################################################
# DEFAULT_KIND_IMAGE is used to set the Kubernetes version for KinD unless overridden in params to setup_kind_cluster(s)
DEFAULT_KIND_IMAGE="gcr.io/istio-testing/kind-node:v1.28.4"
DEFAULT_KIND_IMAGE="gcr.io/istio-testing/kind-node:v1.33.1"
# the default kind cluster should be ipv4 if not otherwise specified
KIND_IP_FAMILY="${KIND_IP_FAMILY:-ipv4}"
# COMMON_SCRIPTS contains the directory this file is in.
COMMON_SCRIPTS=$(dirname "${BASH_SOURCE:-$0}")
@ -144,7 +147,7 @@ function setup_kind_cluster_retry() {
# 1. NAME: Name of the Kind cluster (optional)
# 2. IMAGE: Node image used by KinD (optional)
# 3. CONFIG: KinD cluster configuration YAML file. If not specified then DEFAULT_CLUSTER_YAML is used
# 4. NOMETALBINSTALL: Dont install matllb if set.
# 4. NOMETALBINSTALL: Dont install metalb if set.
# This function returns 0 when everything goes well, or 1 otherwise
# If Kind cluster was already created then it would be cleaned up in case of errors
function setup_kind_cluster() {
@ -172,23 +175,52 @@ function setup_kind_cluster() {
if [[ -z "${CONFIG}" ]]; then
# Kubernetes 1.15+
CONFIG=${DEFAULT_CLUSTER_YAML}
# Configure the cluster IP Family only for default configs
if [ "${IP_FAMILY}" != "ipv4" ]; then
grep "ipFamily: ${IP_FAMILY}" "${CONFIG}" || \
cat <<EOF >> "${CONFIG}"
networking:
ipFamily: ${IP_FAMILY}
EOF
fi
fi
KIND_WAIT_FLAG="--wait=180s"
KIND_DISABLE_CNI="false"
if [[ -n "${KUBERNETES_CNI:-}" ]]; then
unset KIND_WAIT_FLAG
KIND_DISABLE_CNI="true"
fi
# Create KinD cluster
if ! (kind create cluster --name="${NAME}" --config "${CONFIG}" -v4 --retain --image "${IMAGE}" --wait=180s); then
if ! (yq eval "${CONFIG}" --expression ".networking.disableDefaultCNI = ${KIND_DISABLE_CNI}" \
--expression ".networking.ipFamily = \"${KIND_IP_FAMILY}\"" | \
kind create cluster --name="${NAME}" -v4 --retain --image "${IMAGE}" ${KIND_WAIT_FLAG:+"$KIND_WAIT_FLAG"} --config -); then
echo "Could not setup KinD environment. Something wrong with KinD setup. Exporting logs."
return 9
# kubectl config set clusters.kind-istio-testing.server https://istio-testing-control-plane:6443
fi
if [[ -n "${DEVCONTAINER:-}" ]]; then
# identify our docker container id using proc and regex
containerid=$(grep 'resolv.conf' /proc/self/mountinfo | sed 's/.*\/docker\/containers\/\([0-9a-f]*\).*/\1/')
docker network connect kind "$containerid"
kind export kubeconfig --name="${NAME}" --internal
fi
# Workaround kind issue causing taints to not be removed in 1.24
kubectl taint nodes "${NAME}"-control-plane node-role.kubernetes.io/control-plane- || true
kubectl taint nodes "${NAME}"-control-plane node-role.kubernetes.io/control-plane- 2>/dev/null || true
# Determine what CNI to install
case "${KUBERNETES_CNI:-}" in
"calico")
echo "Installing Calico CNI"
install_calico "" "$(dirname "$CONFIG")"
;;
"")
# perfectly fine, we accepted the default KinD CNI
;;
*)
# we don't know what to do but we've got no CNI, return non-zero
echo "${KUBERNETES_CNI} is not recognized. Supported options are \"calico\" or do not set the variable to use default."
return 1
;;
esac
# If metrics server configuration directory is specified then deploy in
# the cluster just created
@ -207,7 +239,7 @@ EOF
# https://github.com/coredns/coredns/issues/2494#issuecomment-457215452
# CoreDNS should handle those domains and answer with NXDOMAIN instead of SERVFAIL
# otherwise pods stops trying to resolve the domain.
if [ "${IP_FAMILY}" = "ipv6" ] || [ "${IP_FAMILY}" = "dual" ]; then
if [ "${KIND_IP_FAMILY}" = "ipv6" ] || [ "${KIND_IP_FAMILY}" = "dual" ]; then
# Get the current config
original_coredns=$(kubectl get -oyaml -n=kube-system configmap/coredns)
echo "Original CoreDNS config:"
@ -244,14 +276,14 @@ function cleanup_kind_clusters() {
# setup_kind_clusters sets up a given number of kind clusters with given topology
# as specified in cluster topology configuration file.
# 1. IMAGE = docker image used as node by KinD
# 2. IP_FAMILY = either ipv4 or ipv6
# 2. KIND_IP_FAMILY = either ipv4 or ipv6 or dual
#
# NOTE: Please call load_cluster_topology before calling this method as it expects
# cluster topology information to be loaded in advance
function setup_kind_clusters() {
IMAGE="${1:-"${DEFAULT_KIND_IMAGE}"}"
KUBECONFIG_DIR="${ARTIFACTS:-$(mktemp -d)}/kubeconfig"
IP_FAMILY="${2:-ipv4}"
KIND_IP_FAMILY="${2:-ipv4}"
check_default_cluster_yaml
@ -362,10 +394,21 @@ function connect_kind_clusters() {
fi
}
function install_calico {
local KUBECONFIG="${1}"
local CONFIG_DIR="${2}"
echo "Setting up ambient cluster, Calico CNI will be used."
kubectl --kubeconfig="$KUBECONFIG" apply -f "${CONFIG_DIR}"/calico.yaml
kubectl --kubeconfig="$KUBECONFIG" wait --for condition=ready -n kube-system pod -l k8s-app=calico-node --timeout 90s
kubectl --kubeconfig="$KUBECONFIG" wait --for condition=ready -n kube-system pod -l k8s-app=calico-kube-controllers --timeout 90s
}
function install_metallb() {
KUBECONFIG="${1}"
kubectl --kubeconfig="$KUBECONFIG" apply -f "${COMMON_SCRIPTS}/metallb-native.yaml"
kubectl --kubeconfig="$KUBECONFIG" wait -n metallb-system pod -l app=metallb --for=condition=Ready
kubectl --kubeconfig="$KUBECONFIG" wait -n metallb-system pod --timeout=120s -l app=metallb --for=condition=Ready
if [ -z "${METALLB_IPS4+x}" ]; then
# Take IPs from the end of the docker kind network subnet to use for MetalLB IPs

View File

@ -21,8 +21,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
GOLANGCILINT_RUN_ARGS=(--output.text.path stdout --output.junit-xml.path "${ARTIFACTS}"/junit-lint.xml)
if [[ "${ARTIFACTS}" != "" ]]; then
golangci-lint run -v -c ./common/config/.golangci.yml --out-format colored-line-number,junit-xml:"${ARTIFACTS}"/junit-lint.xml
golangci-lint run -v -c ./common/config/.golangci.yml "${GOLANGCILINT_RUN_ARGS[@]}"
else
golangci-lint run -v -c ./common/config/.golangci.yml
fi

View File

@ -1,5 +1,6 @@
# Downloaded from https://github.com/metallb/metallb/raw/v0.13.12/config/manifests/metallb-native.yaml
# With quay.io hub replaced with gcr.io/istio-testing
# And probes tuned to startup faster
apiVersion: v1
kind: Namespace
metadata:
@ -11,213 +12,6 @@ metadata:
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.1
creationTimestamp: null
name: addresspools.metallb.io
spec:
conversion:
strategy: Webhook
webhook:
clientConfig:
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlGWlRDQ0EwMmdBd0lCQWdJVU5GRW1XcTM3MVpKdGkrMmlSQzk1WmpBV1MxZ3dEUVlKS29aSWh2Y05BUUVMDQpCUUF3UWpFTE1Ba0dBMVVFQmhNQ1dGZ3hGVEFUQmdOVkJBY01ERVJsWm1GMWJIUWdRMmwwZVRFY01Cb0dBMVVFDQpDZ3dUUkdWbVlYVnNkQ0JEYjIxd1lXNTVJRXgwWkRBZUZ3MHlNakEzTVRrd09UTXlNek5hRncweU1qQTRNVGd3DQpPVE15TXpOYU1FSXhDekFKQmdOVkJBWVRBbGhZTVJVd0V3WURWUVFIREF4RVpXWmhkV3gwSUVOcGRIa3hIREFhDQpCZ05WQkFvTUUwUmxabUYxYkhRZ1EyOXRjR0Z1ZVNCTWRHUXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDDQpEd0F3Z2dJS0FvSUNBUUNxVFpxMWZRcC9vYkdlenhES0o3OVB3Ny94azJwellualNzMlkzb1ZYSm5sRmM4YjVlDQpma2ZZQnY2bndscW1keW5PL2phWFBaQmRQSS82aFdOUDBkdVhadEtWU0NCUUpyZzEyOGNXb3F0MGNTN3pLb1VpDQpvcU1tQ0QvRXVBeFFNZjhRZDF2c1gvVllkZ0poVTZBRXJLZEpIaXpFOUJtUkNkTDBGMW1OVW55Rk82UnRtWFZUDQpidkxsTDVYeTc2R0FaQVBLOFB4aVlDa0NtbDdxN0VnTWNiOXlLWldCYmlxQ3VkTXE5TGJLNmdKNzF6YkZnSXV4DQo1L1pXK2JraTB2RlplWk9ZODUxb1psckFUNzJvMDI4NHNTWW9uN0pHZVZkY3NoUnh5R1VpSFpSTzdkaXZVTDVTDQpmM2JmSDFYbWY1ZDQzT0NWTWRuUUV2NWVaOG8zeWVLa3ZrbkZQUGVJMU9BbjdGbDlFRVNNR2dhOGFaSG1URSttDQpsLzlMSmdDYjBnQmtPT0M0WnV4bWh2aERKV1EzWnJCS3pMQlNUZXN0NWlLNVlwcXRWVVk2THRyRW9FelVTK1lsDQpwWndXY2VQWHlHeHM5ZURsR3lNVmQraW15Y3NTU1UvVno2Mmx6MnZCS21NTXBkYldDQWhud0RsRTVqU2dyMjRRDQp0eGNXLys2N3d5KzhuQlI3UXdqVTFITndVRjBzeERWdEwrZ1NHVERnSEVZSlhZelYvT05zMy94TkpoVFNPSkxNDQpoeXNVdyttaGdackdhbUdXcHVIVU1DUitvTWJzMTc1UkcrQjJnUFFHVytPTjJnUTRyOXN2b0ZBNHBBQm8xd1dLDQpRYjRhY3pmeVVscElBOVFoSmFsZEY3S3dPSHVlV3gwRUNrNXg0T2tvVDBvWVp0dzFiR0JjRGtaSmF3SURBUUFCDQpvMU13VVRBZEJnTlZIUTRFRmdRVW90UlNIUm9IWTEyRFZ4R0NCdEhpb1g2ZmVFQXdId1lEVlIwakJCZ3dGb0FVDQpvdFJTSFJvSFkxMkRWeEdDQnRIaW9YNmZlRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCDQpBUXNGQUFPQ0FnRUFSbkpsWWRjMTFHd0VxWnh6RDF2R3BDR2pDN2VWTlQ3aVY1d3IybXlybHdPYi9aUWFEa0xYDQpvVStaOVVXT1VlSXJTdzUydDdmQUpvVVAwSm5iYkMveVIrU1lqUGhvUXNiVHduOTc2ZldBWTduM3FMOXhCd1Y0DQphek41OXNjeUp0dlhMeUtOL2N5ak1ReDRLajBIMFg0bWJ6bzVZNUtzWWtYVU0vOEFPdWZMcEd0S1NGVGgrSEFDDQpab1Q5YnZHS25adnNHd0tYZFF0Wnh0akhaUjVqK3U3ZGtQOTJBT051RFNabS8rWVV4b2tBK09JbzdSR3BwSHNXDQo1ZTdNY0FTVXRtb1FORXd6dVFoVkJaRWQ1OGtKYjUrV0VWbGNzanlXNnRTbzErZ25tTWNqR1BsMWgxR2hVbjV4DQpFY0lWRnBIWXM5YWo1NmpBSjk1MVQvZjhMaWxmTlVnanBLQ0c1bnl0SUt3emxhOHNtdGlPdm1UNEpYbXBwSkI2DQo4bmdHRVluVjUrUTYwWFJ2OEhSSGp1VG9CRHVhaERrVDA2R1JGODU1d09FR2V4bkZpMXZYWUxLVllWb1V2MXRKDQo4dVdUR1pwNllDSVJldlBqbzg5ZytWTlJSaVFYUThJd0dybXE5c0RoVTlqTjA0SjdVL1RvRDFpNHE3VnlsRUc5DQorV1VGNkNLaEdBeTJIaEhwVncyTGFoOS9lUzdZMUZ1YURrWmhPZG1laG1BOCtqdHNZamJadnR5Mm1SWlF0UUZzDQpUU1VUUjREbUR2bVVPRVRmeStpRHdzK2RkWXVNTnJGeVVYV2dkMnpBQU4ydVl1UHFGY2pRcFNPODFzVTJTU3R3DQoxVzAyeUtYOGJEYmZFdjBzbUh3UzliQnFlSGo5NEM1Mjg0YXpsdTBmaUdpTm1OUEM4ckJLRmhBPQ0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==
service:
name: webhook-service
namespace: metallb-system
path: /convert
conversionReviewVersions:
- v1alpha1
- v1beta1
group: metallb.io
names:
kind: AddressPool
listKind: AddressPoolList
plural: addresspools
singular: addresspool
scope: Namespaced
versions:
- deprecated: true
deprecationWarning: metallb.io v1alpha1 AddressPool is deprecated
name: v1alpha1
schema:
openAPIV3Schema:
description: AddressPool is the Schema for the addresspools API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: AddressPoolSpec defines the desired state of AddressPool.
properties:
addresses:
description: A list of IP address ranges over which MetalLB has authority.
You can list multiple ranges in a single pool, they will all share
the same settings. Each range can be either a CIDR prefix, or an
explicit start-end range of IPs.
items:
type: string
type: array
autoAssign:
default: true
description: AutoAssign flag used to prevent MetallB from automatic
allocation for a pool.
type: boolean
bgpAdvertisements:
description: When an IP is allocated from this pool, how should it
be translated into BGP announcements?
items:
properties:
aggregationLength:
default: 32
description: The aggregation-length advertisement option lets
you “roll up” the /32s into a larger prefix.
format: int32
minimum: 1
type: integer
aggregationLengthV6:
default: 128
description: Optional, defaults to 128 (i.e. no aggregation)
if not specified.
format: int32
type: integer
communities:
description: BGP communities
items:
type: string
type: array
localPref:
description: BGP LOCAL_PREF attribute which is used by BGP best
path algorithm, Path with higher localpref is preferred over
one with lower localpref.
format: int32
type: integer
type: object
type: array
protocol:
description: Protocol can be used to select how the announcement is
done.
enum:
- layer2
- bgp
type: string
required:
- addresses
- protocol
type: object
status:
description: AddressPoolStatus defines the observed state of AddressPool.
type: object
required:
- spec
type: object
served: true
storage: false
subresources:
status: {}
- deprecated: true
deprecationWarning: metallb.io v1beta1 AddressPool is deprecated, consider using
IPAddressPool
name: v1beta1
schema:
openAPIV3Schema:
description: AddressPool represents a pool of IP addresses that can be allocated
to LoadBalancer services. AddressPool is deprecated and being replaced by
IPAddressPool.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: AddressPoolSpec defines the desired state of AddressPool.
properties:
addresses:
description: A list of IP address ranges over which MetalLB has authority.
You can list multiple ranges in a single pool, they will all share
the same settings. Each range can be either a CIDR prefix, or an
explicit start-end range of IPs.
items:
type: string
type: array
autoAssign:
default: true
description: AutoAssign flag used to prevent MetallB from automatic
allocation for a pool.
type: boolean
bgpAdvertisements:
description: Drives how an IP allocated from this pool should translated
into BGP announcements.
items:
properties:
aggregationLength:
default: 32
description: The aggregation-length advertisement option lets
you “roll up” the /32s into a larger prefix.
format: int32
minimum: 1
type: integer
aggregationLengthV6:
default: 128
description: Optional, defaults to 128 (i.e. no aggregation)
if not specified.
format: int32
type: integer
communities:
description: BGP communities to be associated with the given
advertisement.
items:
type: string
type: array
localPref:
description: BGP LOCAL_PREF attribute which is used by BGP best
path algorithm, Path with higher localpref is preferred over
one with lower localpref.
format: int32
type: integer
type: object
type: array
protocol:
description: Protocol can be used to select how the announcement is
done.
enum:
- layer2
- bgp
type: string
required:
- addresses
- protocol
type: object
status:
description: AddressPoolStatus defines the observed state of AddressPool.
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.1
@ -1733,12 +1527,13 @@ spec:
- args:
- --port=7472
- --log-level=info
- --tls-min-version=VersionTLS12
env:
- name: METALLB_ML_SECRET_NAME
value: memberlist
- name: METALLB_DEPLOYMENT
value: controller
image: gcr.io/istio-testing/metallb/controller:v0.13.12
image: gcr.io/istio-testing/metallb/controller:v0.14.3
livenessProbe:
failureThreshold: 3
httpGet:
@ -1760,10 +1555,18 @@ spec:
httpGet:
path: /metrics
port: monitoring
initialDelaySeconds: 10
initialDelaySeconds: 0
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
startupProbe:
httpGet:
path: /metrics
port: monitoring
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
@ -1831,7 +1634,7 @@ spec:
value: app=metallb,component=speaker
- name: METALLB_ML_SECRET_KEY_PATH
value: /etc/ml_secret_key
image: gcr.io/istio-testing/metallb/speaker:v0.13.12
image: gcr.io/istio-testing/metallb/speaker:v0.14.3
livenessProbe:
failureThreshold: 3
httpGet:
@ -1855,10 +1658,19 @@ spec:
httpGet:
path: /metrics
port: monitoring
initialDelaySeconds: 10
initialDelaySeconds: 0
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
startupProbe:
failureThreshold: 3
httpGet:
path: /metrics
port: monitoring
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
@ -1922,26 +1734,6 @@ webhooks:
resources:
- bgppeers
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: metallb-system
path: /validate-metallb-io-v1beta1-addresspool
failurePolicy: Fail
name: addresspoolvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- addresspools
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY
#
@ -36,7 +36,7 @@ MOUNT_DEST="${MOUNT_DEST:-/work}"
read -ra DOCKER_RUN_OPTIONS <<< "${DOCKER_RUN_OPTIONS:-}"
[[ -t 1 ]] && DOCKER_RUN_OPTIONS+=("-it")
[[ -t 0 ]] && DOCKER_RUN_OPTIONS+=("-it")
[[ ${UID} -ne 0 ]] && DOCKER_RUN_OPTIONS+=(-u "${UID}:${DOCKER_GID}")
# $CONTAINER_OPTIONS becomes an empty arg when quoted, so SC2086 is disabled for the
@ -47,7 +47,9 @@ read -ra DOCKER_RUN_OPTIONS <<< "${DOCKER_RUN_OPTIONS:-}"
"${DOCKER_RUN_OPTIONS[@]}" \
--init \
--sig-proxy=true \
--cap-add=SYS_ADMIN \
${DOCKER_SOCKET_MOUNT:--v /var/run/docker.sock:/var/run/docker.sock} \
-e DOCKER_HOST=${DOCKER_SOCKET_HOST:-unix:///var/run/docker.sock} \
$CONTAINER_OPTIONS \
--env-file <(env | grep -v ${ENV_BLOCKLIST}) \
-e IN_BUILD_CONTAINER=1 \

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# shellcheck disable=SC2034
# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY
@ -75,7 +75,7 @@ fi
TOOLS_REGISTRY_PROVIDER=${TOOLS_REGISTRY_PROVIDER:-gcr.io}
PROJECT_ID=${PROJECT_ID:-istio-testing}
if [[ "${IMAGE_VERSION:-}" == "" ]]; then
IMAGE_VERSION=master-19f0fb6c28d080531991023434dfadb2687444e2
IMAGE_VERSION=master-8e6480403f5cf4c9a4cd9d65174d01850e632e1a
fi
if [[ "${IMAGE_NAME:-}" == "" ]]; then
IMAGE_NAME=build-tools
@ -95,6 +95,19 @@ IMG="${IMG:-${TOOLS_REGISTRY_PROVIDER}/${PROJECT_ID}/${IMAGE_NAME}:${IMAGE_VERSI
CONTAINER_CLI="${CONTAINER_CLI:-docker}"
# Try to use the latest cached image we have. Use at your own risk, may have incompatibly-old versions
if [[ "${LATEST_CACHED_IMAGE:-}" != "" ]]; then
prefix="$(<<<"$IMAGE_VERSION" cut -d- -f1)"
query="${TOOLS_REGISTRY_PROVIDER}/${PROJECT_ID}/${IMAGE_NAME}:${prefix}-*"
latest="$("${CONTAINER_CLI}" images --filter=reference="${query}" --format "{{.CreatedAt|json}}~{{.Repository}}:{{.Tag}}~{{.CreatedSince}}" | sort -n -r | head -n1)"
IMG="$(<<<"$latest" cut -d~ -f2)"
if [[ "${IMG}" == "" ]]; then
echo "Attempted to use LATEST_CACHED_IMAGE, but found no images matching ${query}" >&2
exit 1
fi
echo "Using cached image $IMG, created $(<<<"$latest" cut -d~ -f3)" >&2
fi
ENV_BLOCKLIST="${ENV_BLOCKLIST:-^_\|^PATH=\|^GOPATH=\|^GOROOT=\|^SHELL=\|^EDITOR=\|^TMUX=\|^USER=\|^HOME=\|^PWD=\|^TERM=\|^RUBY_\|^GEM_\|^rvm_\|^SSH=\|^TMPDIR=\|^CC=\|^CXX=\|^MAKEFILE_LIST=}"
# Remove functions from the list of exported variables, they mess up with the `env` command.

View File

@ -8,8 +8,11 @@
# leave room for compiler/linker.
# The number 3G is chosen heuristically to both support large VM and small VM with RBE.
# Startup options cannot be selected via config.
# TODO: Adding just to test android
startup --host_jvm_args=-Xmx3g
common --noenable_bzlmod
fetch --color=yes
run --color=yes
@ -19,12 +22,20 @@ build --workspace_status_command="bash bazel/get_workspace_status"
build --incompatible_strict_action_env
build --java_runtime_version=remotejdk_11
build --tool_java_runtime_version=remotejdk_11
build --java_language_version=11
build --tool_java_language_version=11
build --platform_mappings=bazel/platform_mappings
# silence absl logspam.
build --copt=-DABSL_MIN_LOG_LEVEL=4
# Global C++ standard and common warning suppressions
build --cxxopt=-std=c++20 --host_cxxopt=-std=c++20
build --copt=-Wno-deprecated-declarations
build --define envoy_mobile_listener=enabled
build --experimental_repository_downloader_retries=2
build --enable_platform_specific_config
build --incompatible_merge_fixed_and_default_shell_env
# A workaround for slow ICU download.
build --http_timeout_scaling=6.0
# Pass CC, CXX and LLVM_CONFIG variables from the environment.
# We assume they have stable values, so this won't cause action cache misses.
@ -42,10 +53,6 @@ build:windows --action_env=PATH --host_action_env=PATH
# Requires setting `BAZEL_VOLATILE_DIRTY` in the env.
build --action_env=BAZEL_VOLATILE_DIRTY --host_action_env=BAZEL_VOLATILE_DIRTY
# Prevent stamped caches from busting (eg in PRs)
# Requires setting `BAZEL_FAKE_SCM_REVISION` in the env.
build --action_env=BAZEL_FAKE_SCM_REVISION --host_action_env=BAZEL_FAKE_SCM_REVISION
build --test_summary=terse
build:docs-ci --action_env=DOCS_RST_CHECK=1 --host_action_env=DOCS_RST_CHECK=1
@ -55,21 +62,21 @@ build --incompatible_config_setting_private_default_visibility
build --incompatible_enforce_config_setting_visibility
test --test_verbose_timeout_warnings
test --experimental_ui_max_stdouterr_bytes=11712829 #default 1048576
# Allow tags to influence execution requirements
common --experimental_allow_tags_propagation
build:linux --copt=-fdebug-types-section
# Enable position independent code (this is the default on macOS and Windows)
# (Workaround for https://github.com/bazelbuild/rules_foreign_cc/issues/421)
build:linux --copt=-fdebug-types-section
build:linux --copt=-fPIC
build:linux --copt=-Wno-deprecated-declarations
build:linux --cxxopt=-std=c++17 --host_cxxopt=-std=c++17
build:linux --cxxopt=-fsized-deallocation --host_cxxopt=-fsized-deallocation
build:linux --conlyopt=-fexceptions
build:linux --fission=dbg,opt
build:linux --features=per_object_debug_info
build:linux --action_env=BAZEL_LINKLIBS=-l%:libstdc++.a
build:linux --action_env=BAZEL_LINKOPTS=-lm
build:linux --action_env=BAZEL_LINKOPTS=-lm:-fuse-ld=gold
# We already have absl in the build, define absl=1 to tell googletest to use absl for backtrace.
build --define absl=1
@ -81,17 +88,46 @@ build --@com_googlesource_googleurl//build_config:system_icu=0
build:sanitizer --define tcmalloc=disabled
build:sanitizer --linkopt -ldl
# Common flags for Clang
build:clang --action_env=BAZEL_COMPILER=clang
build:clang --action_env=CC=clang --action_env=CXX=clang++
build:clang --linkopt=-fuse-ld=lld
# Common flags for Clang (shared between all clang variants)
build:clang-common --action_env=BAZEL_COMPILER=clang
build:clang-common --linkopt=-fuse-ld=lld
build:clang-common --action_env=CC=clang --host_action_env=CC=clang
build:clang-common --action_env=CXX=clang++ --host_action_env=CXX=clang++
build:clang-common --incompatible_enable_cc_toolchain_resolution=false
# Clang with libc++ (default)
build:clang --config=clang-common
build:clang --config=libc++
build:arm64-clang --config=clang
# Flags for Clang + PCH
build:clang-pch --spawn_strategy=local
build:clang-pch --define=ENVOY_CLANG_PCH=1
# libstdc++ - currently only used for gcc
build:libstdc++ --@envoy//bazel:libc++=false
build:libstdc++ --@envoy//bazel:libstdc++=true
# Use gold linker for gcc compiler.
build:gcc --linkopt=-fuse-ld=gold
build:gcc --config=libstdc++
build:gcc --test_env=HEAPCHECK=
build:gcc --action_env=BAZEL_COMPILER=gcc
build:gcc --action_env=CC=gcc --action_env=CXX=g++
# This is to work around a bug in GCC that makes debug-types-section
# option not play well with fission:
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110885
build:gcc --copt=-fno-debug-types-section
# These trigger errors in multiple places both in Envoy dependecies
# and in Envoy code itself when using GCC.
# And in all cases the reports appear to be clear false positives.
build:gcc --copt=-Wno-error=restrict
build:gcc --copt=-Wno-error=uninitialized
build:gcc --cxxopt=-Wno-missing-requires
build:gcc --cxxopt=-Wno-dangling-reference
build:gcc --cxxopt=-Wno-nonnull-compare
build:gcc --incompatible_enable_cc_toolchain_resolution=false
build:gcc --linkopt=-fuse-ld=gold --host_linkopt=-fuse-ld=gold
# Clang-tidy
# TODO(phlax): enable this, its throwing some errors as well as finding more issues
@ -101,38 +137,40 @@ build:clang-tidy --aspects @envoy_toolshed//format/clang_tidy:clang_tidy.bzl%cla
build:clang-tidy --output_groups=report
build:clang-tidy --build_tag_filters=-notidy
# Basic ASAN/UBSAN that works for gcc
build:asan --action_env=ENVOY_ASAN=1
build:asan --config=sanitizer
# Basic ASAN/UBSAN that works for gcc or llvm
build:asan-common --config=sanitizer
# ASAN install its signal handler, disable ours so the stacktrace will be printed by ASAN
build:asan --define signal_trace=disabled
build:asan --define ENVOY_CONFIG_ASAN=1
build:asan --build_tag_filters=-no_san
build:asan --test_tag_filters=-no_san
build:asan --copt -fsanitize=address,undefined
build:asan --linkopt -fsanitize=address,undefined
# vptr and function sanitizer are enabled in clang-asan if it is set up via bazel/setup_clang.sh.
build:asan --copt -fno-sanitize=vptr,function
build:asan --linkopt -fno-sanitize=vptr,function
build:asan --copt -DADDRESS_SANITIZER=1
build:asan --copt -DUNDEFINED_SANITIZER=1
build:asan --copt -D__SANITIZE_ADDRESS__
build:asan --test_env=ASAN_OPTIONS=handle_abort=1:allow_addr2line=true:check_initialization_order=true:strict_init_order=true:detect_odr_violation=1
build:asan --test_env=UBSAN_OPTIONS=halt_on_error=true:print_stacktrace=1
build:asan --test_env=ASAN_SYMBOLIZER_PATH
build:asan-common --define signal_trace=disabled
build:asan-common --define ENVOY_CONFIG_ASAN=1
build:asan-common --build_tag_filters=-no_san
build:asan-common --test_tag_filters=-no_san
build:asan-common --copt -fsanitize=address,undefined
build:asan-common --linkopt -fsanitize=address,undefined
# vptr and function sanitizer are enabled in asan if it is set up via bazel/setup_clang.sh.
build:asan-common --copt -fno-sanitize=vptr,function
build:asan-common --linkopt -fno-sanitize=vptr,function
build:asan-common --copt -DADDRESS_SANITIZER=1
build:asan-common --copt -DUNDEFINED_SANITIZER=1
build:asan-common --copt -D__SANITIZE_ADDRESS__
build:asan-common --test_env=ASAN_OPTIONS=handle_abort=1:allow_addr2line=true:check_initialization_order=true:strict_init_order=true:detect_odr_violation=1
build:asan-common --test_env=UBSAN_OPTIONS=halt_on_error=true:print_stacktrace=1
build:asan-common --test_env=ASAN_SYMBOLIZER_PATH
# ASAN needs -O1 to get reasonable performance.
build:asan --copt -O1
build:asan --copt -fno-optimize-sibling-calls
build:asan-common --copt -O1
build:asan-common --copt -fno-optimize-sibling-calls
# Clang ASAN/UBSAN
build:clang-asan --config=clang
build:clang-asan --config=asan
build:clang-asan --linkopt -fuse-ld=lld
build:clang-asan --linkopt --rtlib=compiler-rt
build:clang-asan --linkopt --unwindlib=libgcc
# ASAN config with clang runtime
build:asan --config=asan-common
build:asan --linkopt --rtlib=compiler-rt
build:asan --linkopt --unwindlib=libgcc
build:asan --linkopt=-l:libclang_rt.ubsan_standalone.a
build:asan --linkopt=-l:libclang_rt.ubsan_standalone_cxx.a
build:asan --action_env=ENVOY_UBSAN_VPTR=1
build:asan --copt=-fsanitize=vptr,function
build:asan --linkopt=-fsanitize=vptr,function
build:asan --linkopt='-L/opt/llvm/lib/clang/18/lib/x86_64-unknown-linux-gnu'
# macOS
build:macos --cxxopt=-std=c++17 --host_cxxopt=-std=c++17
build:macos --action_env=PATH=/opt/homebrew/bin:/opt/local/bin:/usr/local/bin:/usr/bin:/bin
build:macos --host_action_env=PATH=/opt/homebrew/bin:/opt/local/bin:/usr/local/bin:/usr/bin:/bin
build:macos --define tcmalloc=disabled
@ -147,53 +185,47 @@ build:macos-asan --copt -DGRPC_BAZEL_BUILD
# Dynamic link cause issues like: `dyld: malformed mach-o: load commands size (59272) > 32768`
build:macos-asan --dynamic_mode=off
# Clang TSAN
build:clang-tsan --action_env=ENVOY_TSAN=1
build:clang-tsan --config=sanitizer
build:clang-tsan --define ENVOY_CONFIG_TSAN=1
build:clang-tsan --copt -fsanitize=thread
build:clang-tsan --linkopt -fsanitize=thread
build:clang-tsan --linkopt -fuse-ld=lld
build:clang-tsan --copt -DTHREAD_SANITIZER=1
build:clang-tsan --build_tag_filters=-no_san,-no_tsan
build:clang-tsan --test_tag_filters=-no_san,-no_tsan
# Base TSAN config
build:tsan --action_env=ENVOY_TSAN=1
build:tsan --config=sanitizer
build:tsan --define ENVOY_CONFIG_TSAN=1
build:tsan --copt -fsanitize=thread
build:tsan --linkopt -fsanitize=thread
build:tsan --copt -DTHREAD_SANITIZER=1
build:tsan --build_tag_filters=-no_san,-no_tsan
build:tsan --test_tag_filters=-no_san,-no_tsan
# Needed due to https://github.com/libevent/libevent/issues/777
build:clang-tsan --copt -DEVENT__DISABLE_DEBUG_MODE
build:tsan --copt -DEVENT__DISABLE_DEBUG_MODE
# https://github.com/abseil/abseil-cpp/issues/760
# https://github.com/google/sanitizers/issues/953
build:clang-tsan --test_env="TSAN_OPTIONS=report_atomic_races=0"
build:clang-tsan --test_timeout=120,600,1500,4800
build:tsan --test_env="TSAN_OPTIONS=report_atomic_races=0"
build:tsan --test_timeout=120,600,1500,4800
# Clang MSAN - this is the base config for remote-msan and docker-msan. To run this config without
# our build image, follow https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo
# with libc++ instruction and provide corresponding `--copt` and `--linkopt` as well.
build:clang-msan --action_env=ENVOY_MSAN=1
build:clang-msan --config=sanitizer
build:clang-msan --build_tag_filters=-no_san
build:clang-msan --test_tag_filters=-no_san
build:clang-msan --define ENVOY_CONFIG_MSAN=1
build:clang-msan --copt -fsanitize=memory
build:clang-msan --linkopt -fsanitize=memory
build:clang-msan --linkopt -fuse-ld=lld
build:clang-msan --copt -fsanitize-memory-track-origins=2
build:clang-msan --copt -DMEMORY_SANITIZER=1
build:clang-msan --test_env=MSAN_SYMBOLIZER_PATH
# Base MSAN config
build:msan --action_env=ENVOY_MSAN=1
build:msan --config=sanitizer
build:msan --build_tag_filters=-no_san
build:msan --test_tag_filters=-no_san
build:msan --define ENVOY_CONFIG_MSAN=1
build:msan --copt -fsanitize=memory
build:msan --linkopt -fsanitize=memory
build:msan --copt -fsanitize-memory-track-origins=2
build:msan --copt -DMEMORY_SANITIZER=1
build:msan --test_env=MSAN_SYMBOLIZER_PATH
# MSAN needs -O1 to get reasonable performance.
build:clang-msan --copt -O1
build:clang-msan --copt -fno-optimize-sibling-calls
build:msan --copt -O1
build:msan --copt -fno-optimize-sibling-calls
# Clang with libc++
build:libc++ --config=clang
build:libc++ --action_env=CXXFLAGS=-stdlib=libc++
build:libc++ --action_env=LDFLAGS=-stdlib=libc++
build:libc++ --action_env=BAZEL_CXXOPTS=-stdlib=libc++
build:libc++ --action_env=BAZEL_LINKLIBS=-l%:libc++.a:-l%:libc++abi.a
build:libc++ --action_env=BAZEL_LINKOPTS=-lm:-pthread
build:libc++ --define force_libcpp=enabled
build:libc++ --@envoy//bazel:libc++=true
build:libc++20 --config=libc++
# gRPC has a lot of deprecated-enum-enum-conversion warning. Remove once it is addressed
build:libc++20 --cxxopt=-std=c++20 --copt=-Wno-error=deprecated-enum-enum-conversion
# Optimize build for binary size reduction.
build:sizeopt -c opt --copt -Os
@ -210,7 +242,6 @@ build:coverage --action_env=GCOV=llvm-profdata
build:coverage --copt=-DNDEBUG
# 1.5x original timeout + 300s for trace merger in all categories
build:coverage --test_timeout=390,750,1500,5700
build:coverage --define=dynamic_link_tests=true
build:coverage --define=ENVOY_CONFIG_COVERAGE=1
build:coverage --cxxopt="-DENVOY_CONFIG_COVERAGE=1"
build:coverage --test_env=HEAPCHECK=
@ -229,6 +260,9 @@ build:coverage --define=no_debug_info=1
# `--no-relax` is required for coverage to not err with `relocation R_X86_64_REX_GOTPCRELX`
build:coverage --linkopt=-Wl,-s,--no-relax
build:coverage --test_env=ENVOY_IP_TEST_VERSIONS=v4only
build:coverage --define=dynamic_link_tests=false
# Use custom report generator that also generates HTML
build:coverage --coverage_report_generator=@envoy//tools/coverage:report_generator
build:test-coverage --test_arg="-l trace"
build:test-coverage --test_arg="--log-path /dev/null"
@ -236,62 +270,45 @@ build:test-coverage --test_tag_filters=-nocoverage,-fuzz_target
build:fuzz-coverage --config=plain-fuzzer
build:fuzz-coverage --run_under=@envoy//bazel/coverage:fuzz_coverage_wrapper.sh
build:fuzz-coverage --test_tag_filters=-nocoverage
# Existing fuzz tests don't need a full WASM runtime and in generally we don't really want to
# fuzz dependencies anyways. On the other hand, disabling WASM reduces the build time and
# resources required to build and run the tests.
build:fuzz-coverage --define=wasm=disabled
build:fuzz-coverage --config=fuzz-coverage-config
build:fuzz-coverage-config --//tools/coverage:config=//test:fuzz_coverage_config
build:cache-local --remote_cache=grpc://localhost:9092
# Remote execution: https://docs.bazel.build/versions/master/remote-execution.html
build:rbe-toolchain --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
build:rbe-toolchain --incompatible_enable_cc_toolchain_resolution=false
build:rbe-toolchain-clang --config=rbe-toolchain
build:rbe-toolchain-clang --platforms=@envoy_build_tools//toolchains:rbe_linux_clang_platform
build:rbe-toolchain-clang --host_platform=@envoy_build_tools//toolchains:rbe_linux_clang_platform
build:rbe-toolchain-clang --crosstool_top=@envoy_build_tools//toolchains/configs/linux/clang/cc:toolchain
build:rbe-toolchain-clang --extra_toolchains=@envoy_build_tools//toolchains/configs/linux/clang/config:cc-toolchain
build:rbe-toolchain-clang --action_env=CC=clang --action_env=CXX=clang++ --action_env=PATH=/usr/sbin:/usr/bin:/sbin:/bin:/opt/llvm/bin
build:rbe-toolchain-clang --config=clang
build:rbe-toolchain-clang --platforms=@envoy//bazel/rbe/toolchains:rbe_linux_clang_platform
build:rbe-toolchain-clang --host_platform=@envoy//bazel/rbe/toolchains:rbe_linux_clang_platform
build:rbe-toolchain-clang --crosstool_top=@envoy//bazel/rbe/toolchains/configs/linux/clang/cc:toolchain
build:rbe-toolchain-clang --extra_toolchains=@envoy//bazel/rbe/toolchains/configs/linux/clang/config:cc-toolchain
build:rbe-toolchain-clang --action_env=CC=clang --action_env=CXX=clang++
build:rbe-toolchain-clang-libc++ --config=rbe-toolchain
build:rbe-toolchain-clang-libc++ --platforms=@envoy_build_tools//toolchains:rbe_linux_clang_libcxx_platform
build:rbe-toolchain-clang-libc++ --host_platform=@envoy_build_tools//toolchains:rbe_linux_clang_libcxx_platform
build:rbe-toolchain-clang-libc++ --crosstool_top=@envoy_build_tools//toolchains/configs/linux/clang_libcxx/cc:toolchain
build:rbe-toolchain-clang-libc++ --extra_toolchains=@envoy_build_tools//toolchains/configs/linux/clang_libcxx/config:cc-toolchain
build:rbe-toolchain-clang-libc++ --action_env=CC=clang --action_env=CXX=clang++ --action_env=PATH=/usr/sbin:/usr/bin:/sbin:/bin:/opt/llvm/bin
build:rbe-toolchain-clang-libc++ --action_env=CXXFLAGS=-stdlib=libc++
build:rbe-toolchain-clang-libc++ --action_env=LDFLAGS=-stdlib=libc++
build:rbe-toolchain-clang-libc++ --define force_libcpp=enabled
# Do not inherit from "clang-asan" to avoid picking up flags from local clang.bazelrc.
build:rbe-toolchain-asan --config=asan
build:rbe-toolchain-asan --linkopt -fuse-ld=lld
build:rbe-toolchain-asan --action_env=ENVOY_UBSAN_VPTR=1
build:rbe-toolchain-asan --copt=-fsanitize=vptr,function
build:rbe-toolchain-asan --linkopt=-fsanitize=vptr,function
build:rbe-toolchain-asan --linkopt='-L/opt/llvm/lib/clang/14.0.0/lib/x86_64-unknown-linux-gnu'
build:rbe-toolchain-asan --linkopt=-l:libclang_rt.ubsan_standalone.a
build:rbe-toolchain-asan --linkopt=-l:libclang_rt.ubsan_standalone_cxx.a
build:rbe-toolchain-arm64-clang --config=rbe-toolchain
build:rbe-toolchain-arm64-clang --config=clang
build:rbe-toolchain-arm64-clang --platforms=@envoy//bazel/rbe/toolchains:rbe_linux_arm64_clang_platform
build:rbe-toolchain-arm64-clang --host_platform=@envoy//bazel/rbe/toolchains:rbe_linux_arm64_clang_platform
build:rbe-toolchain-arm64-clang --crosstool_top=@envoy//bazel/rbe/toolchains/configs/linux/clang/cc:toolchain
build:rbe-toolchain-arm64-clang --extra_toolchains=@envoy//bazel/rbe/toolchains/configs/linux/clang/config:cc-toolchain-arm64
build:rbe-toolchain-arm64-clang --action_env=CC=clang --action_env=CXX=clang++
build:rbe-toolchain-msan --linkopt=-L/opt/libcxx_msan/lib
build:rbe-toolchain-msan --linkopt=-Wl,-rpath,/opt/libcxx_msan/lib
build:rbe-toolchain-msan --config=clang-msan
build:rbe-toolchain-tsan --linkopt=-L/opt/libcxx_tsan/lib
build:rbe-toolchain-tsan --linkopt=-Wl,-rpath,/opt/libcxx_tsan/lib
build:rbe-toolchain-tsan --config=clang-tsan
# Sanitizer configs - CI uses the *-common configs directly
# Note: clang config comes from rbe-toolchain-clang to avoid duplication
build:rbe-toolchain-gcc --config=rbe-toolchain
build:rbe-toolchain-gcc --platforms=@envoy_build_tools//toolchains:rbe_linux_gcc_platform
build:rbe-toolchain-gcc --host_platform=@envoy_build_tools//toolchains:rbe_linux_gcc_platform
build:rbe-toolchain-gcc --crosstool_top=@envoy_build_tools//toolchains/configs/linux/gcc/cc:toolchain
build:rbe-toolchain-gcc --extra_toolchains=@envoy_build_tools//toolchains/configs/linux/gcc/config:cc-toolchain
build:rbe-toolchain-msvc-cl --host_platform=@envoy_build_tools//toolchains:rbe_windows_msvc_cl_platform
build:rbe-toolchain-msvc-cl --platforms=@envoy_build_tools//toolchains:rbe_windows_msvc_cl_platform
build:rbe-toolchain-msvc-cl --crosstool_top=@envoy_build_tools//toolchains/configs/windows/msvc-cl/cc:toolchain
build:rbe-toolchain-msvc-cl --extra_toolchains=@envoy_build_tools//toolchains/configs/windows/msvc-cl/config:cc-toolchain
build:rbe-toolchain-clang-cl --host_platform=@envoy_build_tools//toolchains:rbe_windows_clang_cl_platform
build:rbe-toolchain-clang-cl --platforms=@envoy_build_tools//toolchains:rbe_windows_clang_cl_platform
build:rbe-toolchain-clang-cl --crosstool_top=@envoy_build_tools//toolchains/configs/windows/clang-cl/cc:toolchain
build:rbe-toolchain-clang-cl --extra_toolchains=@envoy_build_tools//toolchains/configs/windows/clang-cl/config:cc-toolchain
build:rbe-toolchain-gcc --platforms=@envoy//bazel/rbe/toolchains:rbe_linux_gcc_platform
build:rbe-toolchain-gcc --host_platform=@envoy//bazel/rbe/toolchains:rbe_linux_gcc_platform
build:rbe-toolchain-gcc --crosstool_top=@envoy//bazel/rbe/toolchains/configs/linux/gcc/cc:toolchain
build:rbe-toolchain-gcc --extra_toolchains=@envoy//bazel/rbe/toolchains/configs/linux/gcc/config:cc-toolchain
build:remote --spawn_strategy=remote,sandboxed,local
build:remote --strategy=Javac=remote,sandboxed,local
@ -311,23 +328,26 @@ build:remote-windows --remote_download_toplevel
build:remote-clang --config=remote
build:remote-clang --config=rbe-toolchain-clang
build:remote-clang-libc++ --config=remote
build:remote-clang-libc++ --config=rbe-toolchain-clang-libc++
build:remote-arm64-clang --config=remote
build:remote-arm64-clang --config=rbe-toolchain-arm64-clang
build:remote-gcc --config=remote
build:remote-gcc --config=gcc
build:remote-gcc --config=rbe-toolchain-gcc
build:remote-asan --config=remote
build:remote-asan --config=rbe-toolchain-clang-libc++
build:remote-asan --config=rbe-toolchain-asan
build:remote-asan --config=rbe-toolchain-clang
build:remote-asan --config=asan
build:remote-msan --config=remote
build:remote-msan --config=rbe-toolchain-clang-libc++
build:remote-msan --config=rbe-toolchain-msan
build:remote-msan --config=rbe-toolchain-clang
build:remote-msan --config=msan
build:remote-tsan --config=remote
build:remote-tsan --config=rbe-toolchain-clang-libc++
build:remote-tsan --config=rbe-toolchain-tsan
build:remote-tsan --config=rbe-toolchain-clang
build:remote-tsan --config=tsan
build:remote-msvc-cl --config=remote-windows
build:remote-msvc-cl --config=msvc-cl
@ -351,14 +371,15 @@ build:compile-time-options --define=deprecated_features=disabled
build:compile-time-options --define=tcmalloc=gperftools
build:compile-time-options --define=zlib=ng
build:compile-time-options --define=uhv=enabled
build:compile-time-options --config=libc++20
# gRPC has a lot of deprecated-enum-enum-conversion warnings with C++20
build:compile-time-options --copt=-Wno-error=deprecated-enum-enum-conversion
build:compile-time-options --test_env=ENVOY_HAS_EXTRA_EXTENSIONS=true
build:compile-time-options --@envoy//bazel:http3=False
build:compile-time-options --@envoy//source/extensions/filters/http/kill_request:enabled
# Docker sandbox
# NOTE: Update this from https://github.com/envoyproxy/envoy-build-tools/blob/main/toolchains/rbe_toolchains_config.bzl#L8
build:docker-sandbox --experimental_docker_image=envoyproxy/envoy-build-ubuntu:0ca52447572ee105a4730da5e76fe47c9c5a7c64@sha256:d736c58f06f36848e7966752cc7e01519cc1b5101a178d5c6634807e8ac3deab
build:docker-sandbox --experimental_docker_image=envoyproxy/envoy-build-ubuntu:f4a881a1205e8e6db1a57162faf3df7aed88eae8@sha256:b10346fe2eee41733dbab0e02322c47a538bf3938d093a5daebad9699860b814
build:docker-sandbox --spawn_strategy=docker
build:docker-sandbox --strategy=Javac=docker
build:docker-sandbox --strategy=Closure=docker
@ -370,39 +391,37 @@ build:docker-sandbox --experimental_enable_docker_sandbox
build:docker-clang --config=docker-sandbox
build:docker-clang --config=rbe-toolchain-clang
build:docker-clang-libc++ --config=docker-sandbox
build:docker-clang-libc++ --config=rbe-toolchain-clang-libc++
build:docker-gcc --config=docker-sandbox
build:docker-gcc --config=gcc
build:docker-gcc --config=rbe-toolchain-gcc
build:docker-asan --config=docker-sandbox
build:docker-asan --config=rbe-toolchain-clang-libc++
build:docker-asan --config=rbe-toolchain-asan
build:docker-asan --config=rbe-toolchain-clang
build:docker-asan --config=asan
build:docker-msan --config=docker-sandbox
build:docker-msan --config=rbe-toolchain-clang-libc++
build:docker-msan --config=rbe-toolchain-msan
build:docker-msan --config=rbe-toolchain-clang
build:docker-msan --config=msan
build:docker-tsan --config=docker-sandbox
build:docker-tsan --config=rbe-toolchain-clang-libc++
build:docker-tsan --config=rbe-toolchain-tsan
build:docker-tsan --config=rbe-toolchain-clang
build:docker-tsan --config=tsan
# CI configurations
build:remote-ci --config=ci
build:remote-ci --remote_download_minimal
# Note this config is used by mobile CI also.
build:ci --noshow_progress
build:ci --noshow_loading_progress
build:ci --test_output=errors
common:ci --noshow_progress
common:ci --noshow_loading_progress
common:ci --test_output=errors
# Fuzz builds
# Shared fuzzing configuration.
build:fuzzing --define=ENVOY_CONFIG_ASAN=1
build:fuzzing --copt=-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
build:fuzzing --config=libc++
# Fuzzing without ASAN. This is useful for profiling fuzzers without any ASAN artifacts.
build:plain-fuzzer --config=fuzzing
@ -413,13 +432,16 @@ build:plain-fuzzer --define=FUZZING_ENGINE=libfuzzer
build:plain-fuzzer --copt=-fsanitize=fuzzer-no-link
build:plain-fuzzer --linkopt=-fsanitize=fuzzer-no-link
# ASAN fuzzer
build:asan-fuzzer --config=plain-fuzzer
build:asan-fuzzer --config=clang-asan
build:asan-fuzzer --config=asan
build:asan-fuzzer --copt=-fno-omit-frame-pointer
# Remove UBSAN halt_on_error to avoid crashing on protobuf errors.
build:asan-fuzzer --test_env=UBSAN_OPTIONS=print_stacktrace=1
build:asan-fuzzer --linkopt=-lc++
build:oss-fuzz --config=fuzzing
build:oss-fuzz --config=libc++
build:oss-fuzz --define=FUZZING_ENGINE=oss-fuzz
build:oss-fuzz --@rules_fuzzing//fuzzing:cc_engine_instrumentation=oss-fuzz
build:oss-fuzz --@rules_fuzzing//fuzzing:cc_engine_sanitizer=none
@ -496,6 +518,7 @@ build:rbe-google --config=cache-google
build:rbe-google-bes --bes_backend=grpcs://buildeventservice.googleapis.com
build:rbe-google-bes --bes_results_url=https://source.cloud.google.com/results/invocations/
build:rbe-google-bes --bes_upload_mode=fully_async
# RBE (Engflow mobile)
build:rbe-engflow --google_default_credentials=false
@ -504,22 +527,41 @@ build:rbe-engflow --remote_executor=grpcs://envoy.cluster.engflow.com
build:rbe-engflow --bes_backend=grpcs://envoy.cluster.engflow.com/
build:rbe-engflow --bes_results_url=https://envoy.cluster.engflow.com/invocation/
build:rbe-engflow --credential_helper=*.engflow.com=%workspace%/bazel/engflow-bazel-credential-helper.sh
build:rbe-engflow --grpc_keepalive_time=30s
build:rbe-engflow --grpc_keepalive_time=60s
build:rbe-engflow --grpc_keepalive_timeout=30s
build:rbe-engflow --remote_timeout=3600s
build:rbe-engflow --bes_timeout=3600s
build:rbe-engflow --bes_upload_mode=fully_async
build:rbe-engflow --nolegacy_important_outputs
build:rbe-envoy-engflow --google_default_credentials=false
build:rbe-envoy-engflow --remote_cache=grpcs://morganite.cluster.engflow.com
build:rbe-envoy-engflow --remote_executor=grpcs://morganite.cluster.engflow.com
build:rbe-envoy-engflow --bes_backend=grpcs://morganite.cluster.engflow.com/
build:rbe-envoy-engflow --bes_results_url=https://morganite.cluster.engflow.com/invocation/
build:rbe-envoy-engflow --credential_helper=*.engflow.com=%workspace%/bazel/engflow-bazel-credential-helper.sh
build:rbe-envoy-engflow --grpc_keepalive_time=30s
build:rbe-envoy-engflow --remote_timeout=3600s
build:rbe-envoy-engflow --bes_timeout=3600s
build:rbe-envoy-engflow --bes_upload_mode=fully_async
build:rbe-envoy-engflow --remote_default_exec_properties=container-image=docker://docker.io/envoyproxy/envoy-build-ubuntu:0ca52447572ee105a4730da5e76fe47c9c5a7c64@sha256:d736c58f06f36848e7966752cc7e01519cc1b5101a178d5c6634807e8ac3deab
# RBE (Engflow Envoy)
common:common-envoy-engflow --google_default_credentials=false
common:common-envoy-engflow --credential_helper=*.engflow.com=%workspace%/bazel/engflow-bazel-credential-helper.sh
common:common-envoy-engflow --grpc_keepalive_time=60s
common:common-envoy-engflow --grpc_keepalive_timeout=30s
common:cache-envoy-engflow --remote_cache=grpcs://mordenite.cluster.engflow.com
common:cache-envoy-engflow --remote_timeout=3600s
# common:cache-envoy-engflow --remote_instance_name=llvm-18
common:bes-envoy-engflow --bes_backend=grpcs://mordenite.cluster.engflow.com/
common:bes-envoy-engflow --bes_results_url=https://mordenite.cluster.engflow.com/invocation/
common:bes-envoy-engflow --bes_timeout=3600s
common:bes-envoy-engflow --bes_upload_mode=fully_async
common:bes-envoy-engflow --nolegacy_important_outputs
common:rbe-envoy-engflow --remote_executor=grpcs://mordenite.cluster.engflow.com
common:rbe-envoy-engflow --remote_default_exec_properties=container-image=docker://gcr.io/envoy-ci/envoy-build@sha256:95d7afdea0f0f8881e88fa5e581db4f50907d0745ac8d90e00357ac1a316abe5
common:rbe-envoy-engflow --jobs=200
common:rbe-envoy-engflow --define=engflow_rbe=true
common:remote-envoy-engflow --config=common-envoy-engflow
common:remote-envoy-engflow --config=cache-envoy-engflow
common:remote-envoy-engflow --config=rbe-envoy-engflow
common:remote-cache-envoy-engflow --config=common-envoy-engflow
common:remote-cache-envoy-engflow --config=cache-envoy-engflow
# Specifies the rustfmt.toml for all rustfmt_test targets.
build --@rules_rust//rust/settings:rustfmt.toml=//:rustfmt.toml
#############################################################################
# debug: Various Bazel debugging flags
@ -543,6 +585,7 @@ common:debug --config=debug-sandbox
common:debug --config=debug-coverage
common:debug --config=debug-tests
try-import %workspace%/repo.bazelrc
try-import %workspace%/clang.bazelrc
try-import %workspace%/user.bazelrc
try-import %workspace%/local_tsan.bazelrc

View File

@ -1,27 +0,0 @@
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_library",
)
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
envoy_cc_library(
name = "access_log_policy_lib",
srcs = [
"config.cc",
"plugin.cc",
],
hdrs = [
"plugin.h",
],
repository = "@envoy",
deps = [
"//extensions/access_log_policy/config/v1alpha1:access_log_policy_config_cc_proto",
"//extensions/common:context",
"//extensions/common:istio_dimensions",
"@envoy//source/common/common:base64_lib",
"@proxy_wasm_cpp_host//:null_lib",
],
)

View File

@ -1,33 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/access_log_policy/plugin.h"
#include "source/common/common/base64.h"
namespace proxy_wasm {
namespace null_plugin {
namespace AccessLogPolicy {
namespace Plugin {
NullPluginRegistry* context_registry_{};
} // namespace Plugin
// Registration glue
RegisterNullVmPluginFactory register_access_log_policy_filter("envoy.wasm.access_log_policy", []() {
return std::make_unique<NullPlugin>(Plugin::context_registry_);
});
} // namespace AccessLogPolicy
} // namespace null_plugin
} // namespace proxy_wasm

View File

@ -1,2 +0,0 @@
access_log_policy_config.pb.h
access_log_policy_config.pb.cc

View File

@ -1,33 +0,0 @@
# Copyright 2019 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
cc_proto_library(
name = "access_log_policy_config_cc_proto",
deps = ["access_log_policy_config_proto"],
)
proto_library(
name = "access_log_policy_config_proto",
srcs = ["access_log_policy_config.proto"],
deps = [
"@com_google_protobuf//:duration_proto",
],
)

View File

@ -1,62 +0,0 @@
---
title: AccessLogPolicy Config
description: Configuration for AccessLogPolicy Filter.
location: https://istio.io/docs/reference/config/proxy_extensions/accesslogpolicy.html
layout: protoc-gen-docs
generator: protoc-gen-docs
weight: 20
number_of_entries: 1
---
<p>Accesslog Policy plugin is a stateful http log sampler.
It decides whether a request is logged based on the following rules.</p>
<ol>
<li>All requests resulting in errors are logged.</li>
<li>First successful request within log_window_duration from a specific
source ip (source principal) is logged.
The plugin records its decision in the istio.access_log_policy attribute with
a value of &ldquo;no&rdquo;. A downstream plugin may honor the the attribute. For
example, Stackdriver plugin will not produce an access log entry if this
attribute is set.</li>
</ol>
<h2 id="AccessLogPolicyConfig">AccessLogPolicyConfig</h2>
<section>
<p>Top level Config for Access Log Policy Config Filter.</p>
<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="AccessLogPolicyConfig-log_window_duration">
<td><code>log_window_duration</code></td>
<td><code><a href="https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#duration">Duration</a></code></td>
<td>
<p>Optional. Allows specifying logging window for successful requests.
The default duration is <code>12h</code>.</p>
</td>
<td>
No
</td>
</tr>
<tr id="AccessLogPolicyConfig-max_client_cache_size">
<td><code>max_client_cache_size</code></td>
<td><code>int32</code></td>
<td>
<p>Optional. Allows specifying max client cache size.
The default is 500 entries.</p>
</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>

View File

@ -1,49 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
syntax = "proto3";
// clang-format off
// $title: AccessLogPolicy Config
// $description: Configuration for AccessLogPolicy Filter.
// $location: https://istio.io/docs/reference/config/proxy_extensions/accesslogpolicy.html
// $weight: 20
// clang-format on
// Accesslog Policy plugin is a stateful http log sampler.
// It decides whether a request is logged based on the following rules.
// 1. All requests resulting in errors are logged.
// 2. First successful request within log_window_duration from a specific
// source ip (source principal) is logged.
// The plugin records its decision in the istio.access_log_policy attribute with
// a value of "no". A downstream plugin may honor the the attribute. For
// example, Stackdriver plugin will not produce an access log entry if this
// attribute is set.
package accesslogpolicy.config.v1alpha1;
import "google/protobuf/duration.proto";
// Top level Config for Access Log Policy Config Filter.
message AccessLogPolicyConfig {
// next id: 3
// Optional. Allows specifying logging window for successful requests.
// The default duration is `12h`.
google.protobuf.Duration log_window_duration = 1;
// Optional. Allows specifying max client cache size.
// The default is 500 entries.
int32 max_client_cache_size = 2;
}

View File

@ -1,174 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/access_log_policy/plugin.h"
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "extensions/common/istio_dimensions.h"
#include "google/protobuf/util/json_util.h"
#include "google/protobuf/util/time_util.h"
#ifndef NULL_PLUGIN
#include "base64.h"
#else
#include "source/common/common/base64.h"
namespace proxy_wasm {
namespace null_plugin {
namespace AccessLogPolicy {
namespace Plugin {
using google::protobuf::util::JsonParseOptions;
using proxy_wasm::WasmHeaderMapType;
PROXY_WASM_NULL_PLUGIN_REGISTRY;
#endif
namespace {
bool setFilterStateValue(bool log) {
auto r = setFilterStateStringValue(::Wasm::Common::kAccessLogPolicyKey, log ? "yes" : "no");
if (r != WasmResult::Ok) {
logWarn(toString(r));
return false;
}
return true;
}
} // namespace
constexpr long long kDefaultLogWindowDurationNanoseconds = 43200000000000; // 12h
constexpr std::string_view kSource = "source";
constexpr std::string_view kAddress = "address";
constexpr std::string_view kConnection = "connection";
constexpr std::string_view kUriSanPeerCertificate = "uri_san_peer_certificate";
constexpr std::string_view kResponse = "response";
constexpr std::string_view kCode = "code";
constexpr std::string_view kGrpcStatus = "grpc_status";
static RegisterContextFactory register_AccessLogPolicy(CONTEXT_FACTORY(PluginContext),
ROOT_FACTORY(PluginRootContext));
bool PluginRootContext::onConfigure(size_t size) {
initialized_ = configure(size);
return true;
}
bool PluginRootContext::configure(size_t configuration_size) {
auto configuration_data =
getBufferBytes(WasmBufferType::PluginConfiguration, 0, configuration_size);
auto configuration = configuration_data->toString();
JsonParseOptions json_options;
json_options.ignore_unknown_fields = true;
const auto status = JsonStringToMessage(configuration, &config_, json_options);
if (!status.ok()) {
logWarn("Cannot parse AccessLog plugin configuration JSON string " + configuration + ", " +
std::string(status.message()));
return false;
}
if (config_.has_log_window_duration()) {
log_time_duration_nanos_ =
::google::protobuf::util::TimeUtil::DurationToNanoseconds(config_.log_window_duration());
} else {
log_time_duration_nanos_ = kDefaultLogWindowDurationNanoseconds;
}
if (config_.max_client_cache_size() > 0) {
max_client_cache_size_ = config_.max_client_cache_size();
}
return true;
}
void PluginRootContext::updateLastLogTimeNanos(const Wasm::Common::IstioDimensions& key,
long long last_log_time_nanos) {
if (int32_t(cache_.size()) > max_client_cache_size_) {
auto it = cache_.begin();
cache_.erase(cache_.begin(), std::next(it, max_client_cache_size_ / 4));
logDebug(absl::StrCat("cleaned cache, new cache_size:", cache_.size()));
}
cache_[key] = last_log_time_nanos;
}
void PluginContext::onLog() {
if (!rootContext()->initialized()) {
return;
}
// Check if request is a failure.
if (isRequestFailed()) {
LOG_TRACE("Setting logging to true as we got error log");
setFilterStateValue(true);
return;
}
// If request is not a failure, check cache to see if it should be logged or
// not, based on last time a successful request was logged for this client ip
// and principal combination.
std::string source_ip = "";
getValue({kSource, kAddress}, &source_ip);
std::string source_principal = "";
getValue({kConnection, kUriSanPeerCertificate}, &source_principal);
istio_dimensions_.set_downstream_ip(source_ip);
istio_dimensions_.set_source_principal(source_principal);
long long last_log_time_nanos = lastLogTimeNanos();
auto cur = static_cast<long long>(getCurrentTimeNanoseconds());
if ((cur - last_log_time_nanos) > logTimeDurationNanos()) {
LOG_TRACE(
absl::StrCat("Setting logging to true as its outside of log windown. SourceIp: ", source_ip,
" SourcePrincipal: ", source_principal, " Window: ", logTimeDurationNanos()));
if (setFilterStateValue(true)) {
updateLastLogTimeNanos(cur);
}
return;
}
setFilterStateValue(false);
}
bool PluginContext::isRequestFailed() {
// Check if HTTP request is a failure.
int64_t http_response_code = 0;
if (getValue({kResponse, kCode}, &http_response_code) && http_response_code >= 400) {
return true;
}
// Check if gRPC request is a failure.
int64_t grpc_response_code = 0;
if (::Wasm::Common::kGrpcContentTypes.count(
getHeaderMapValue(WasmHeaderMapType::RequestHeaders,
::Wasm::Common::kContentTypeHeaderKey)
->toString()) != 0 &&
getValue({kResponse, kGrpcStatus}, &grpc_response_code) && grpc_response_code != 0) {
return true;
}
return false;
}
#ifdef NULL_PLUGIN
} // namespace Plugin
} // namespace AccessLogPolicy
} // namespace null_plugin
} // namespace proxy_wasm
#endif

View File

@ -1,106 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "absl/container/flat_hash_map.h"
#include "extensions/access_log_policy/config/v1alpha1/access_log_policy_config.pb.h"
#include "extensions/common/context.h"
#include "extensions/common/istio_dimensions.h"
#ifndef NULL_PLUGIN
#include <assert.h>
#define ASSERT(_X) assert(_X)
#include "proxy_wasm_intrinsics.h"
static const std::string EMPTY_STRING;
#else
#include "include/proxy-wasm/null_plugin.h"
namespace proxy_wasm {
namespace null_plugin {
namespace AccessLogPolicy {
namespace Plugin {
#endif
const size_t DefaultClientCacheMaxSize = 500;
// PluginRootContext is the root context for all streams processed by the
// thread. It has the same lifetime as the filter instance and acts as target
// for interactions that outlives individual stream, e.g. timer, async calls.
class PluginRootContext : public RootContext {
public:
PluginRootContext(uint32_t id, std::string_view root_id) : RootContext(id, root_id) {}
~PluginRootContext() = default;
bool onConfigure(size_t) override;
bool configure(size_t);
long long lastLogTimeNanos(const Wasm::Common::IstioDimensions& key) {
if (cache_.contains(key)) {
return cache_[key];
}
return 0;
}
void updateLastLogTimeNanos(const Wasm::Common::IstioDimensions& key,
long long last_log_time_nanos);
long long logTimeDurationNanos() { return log_time_duration_nanos_; };
bool initialized() const { return initialized_; };
private:
accesslogpolicy::config::v1alpha1::AccessLogPolicyConfig config_;
// Cache storing last log time by a client.
absl::flat_hash_map<Wasm::Common::IstioDimensions, long long> cache_;
int32_t max_client_cache_size_ = DefaultClientCacheMaxSize;
long long log_time_duration_nanos_;
bool initialized_ = false;
};
// Per-stream context.
class PluginContext : public Context {
public:
explicit PluginContext(uint32_t id, RootContext* root) : Context(id, root) {}
void onLog() override;
private:
inline PluginRootContext* rootContext() {
return dynamic_cast<PluginRootContext*>(this->root());
};
inline long long lastLogTimeNanos() {
return rootContext()->lastLogTimeNanos(istio_dimensions_);
};
inline void updateLastLogTimeNanos(long long last_log_time_nanos) {
rootContext()->updateLastLogTimeNanos(istio_dimensions_, last_log_time_nanos);
};
inline long long logTimeDurationNanos() { return rootContext()->logTimeDurationNanos(); };
bool isRequestFailed();
Wasm::Common::IstioDimensions istio_dimensions_;
};
#ifdef NULL_PLUGIN
} // namespace Plugin
} // namespace AccessLogPolicy
} // namespace null_plugin
} // namespace proxy_wasm
#endif

View File

@ -20,163 +20,21 @@ load(
"envoy_cc_library",
"envoy_cc_test",
)
load(
"@com_github_google_flatbuffers//:build_defs.bzl",
"DEFAULT_FLATC_ARGS",
"flatbuffer_library_public",
)
load(
"@envoy//test/extensions:extensions_build_system.bzl",
"envoy_extension_cc_benchmark_binary",
)
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
envoy_cc_library(
name = "context",
srcs = [
"context.cc",
],
hdrs = [
"context.h",
"istio_dimensions.h",
],
repository = "@envoy",
deps = [
":node_info_fb_cc",
":util",
"@proxy_wasm_cpp_host//:null_lib",
],
)
envoy_cc_library(
name = "proto_util",
srcs = [
"proto_util.cc",
],
hdrs = [
"proto_util.h",
],
repository = "@envoy",
deps = [
":node_info_fb_cc",
":util",
"@com_google_protobuf//:protobuf",
"@proxy_wasm_cpp_host//:null_lib",
],
)
envoy_cc_library(
name = "util",
srcs = [
"util.cc",
],
hdrs = [
"util.h",
],
repository = "@envoy",
deps = [
"@proxy_wasm_cpp_host//:null_lib",
],
)
envoy_cc_library(
name = "istio_dimensions",
hdrs = [
"istio_dimensions.h",
],
repository = "@envoy",
)
envoy_cc_test(
name = "proto_util_test",
size = "small",
srcs = ["proto_util_test.cc"],
repository = "@envoy",
deps = [
":node_info_fb_cc",
":proto_util",
"@com_google_protobuf//:protobuf",
],
)
envoy_cc_test(
name = "util_test",
size = "small",
srcs = ["util_test.cc"],
repository = "@envoy",
deps = [
":util",
],
)
envoy_cc_test(
name = "istio_dimensions_test",
size = "small",
srcs = ["istio_dimensions_test.cc"],
external_deps = ["abseil_hash_testing"],
repository = "@envoy",
deps = [
":istio_dimensions",
],
)
envoy_extension_cc_benchmark_binary(
name = "proto_util_speed_test",
srcs = ["proto_util_speed_test.cc"],
extension_names = ["envoy.wasm.runtime.null"],
external_deps = [
"benchmark",
],
repository = "@envoy",
deps = [
":metadata_object_lib",
":node_info_fb_cc",
":proto_util",
"@envoy//source/common/stream_info:filter_state_lib",
"@envoy//source/extensions/filters/common/expr:cel_state_lib",
"@envoy//test/test_common:status_utility_lib",
],
)
flatbuffer_library_public(
name = "node_info_fbs",
srcs = ["node_info.fbs"],
outs = [
"node_info_bfbs_generated.h",
"node_info_generated.h",
],
flatc_args = DEFAULT_FLATC_ARGS + ["--bfbs-gen-embed"],
language_flag = "-c",
)
cc_library(
name = "node_info_fb_cc",
srcs = [":node_info_fbs"],
hdrs = [":node_info_fbs"],
features = ["-parse_headers"],
linkstatic = True,
deps = [
"@com_github_google_flatbuffers//:flatbuffers",
"@com_github_google_flatbuffers//:runtime_cc",
],
)
envoy_cc_library(
name = "metadata_object_lib",
srcs = ["metadata_object.cc"],
hdrs = ["metadata_object.h"],
repository = "@envoy",
deps = [
":node_info_fb_cc",
"@com_github_google_flatbuffers//:flatbuffers",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/types:optional",
"@envoy//envoy/common:hashable_interface",
"@envoy//envoy/network:filter_interface",
"@envoy//envoy/ssl:connection_interface",
"@envoy//envoy/registry",
"@envoy//envoy/stream_info:filter_state_interface",
"@envoy//source/common/common:hash_lib",
],
@ -188,6 +46,6 @@ envoy_cc_test(
repository = "@envoy",
deps = [
":metadata_object_lib",
"@envoy//test/mocks/ssl:ssl_mocks",
"@envoy//envoy/registry",
],
)

View File

@ -1,569 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/common/context.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "extensions/common/node_info_bfbs_generated.h"
#include "extensions/common/util.h"
#include "flatbuffers/util.h"
// WASM_PROLOG
#ifndef NULL_PLUGIN
#include "proxy_wasm_intrinsics.h"
#else // NULL_PLUGIN
#include "include/proxy-wasm/null_plugin.h"
using proxy_wasm::WasmHeaderMapType;
using proxy_wasm::null_plugin::getHeaderMapValue;
using proxy_wasm::null_plugin::getProperty;
using proxy_wasm::null_plugin::getValue;
#endif // NULL_PLUGIN
// END WASM_PROLOG
namespace Wasm {
namespace Common {
const char kBlackHoleCluster[] = "BlackHoleCluster";
const char kPassThroughCluster[] = "PassthroughCluster";
const char kBlackHoleRouteName[] = "block_all";
const char kPassThroughRouteName[] = "allow_any";
const char kInboundPassthroughClusterIpv4[] = "InboundPassthroughClusterIpv4";
const char kInboundPassthroughClusterIpv6[] = "InboundPassthroughClusterIpv6";
// Well-known name for the grpc_stats filter.
constexpr std::string_view GrpcStatsName = "envoy.filters.http.grpc_stats";
namespace {
// Get destination service host and name based on destination cluster metadata
// and host header.
// * If cluster name is one of passthrough and blackhole clusters, use cluster
// name as destination service name and host header as destination host.
// * Otherwise, try fetching cluster metadata for destination service name and
// host. If cluster metadata is not available, set destination service name
// the same as destination service host.
void populateDestinationService(bool outbound, bool use_host_header, RequestInfo* request_info) {
if (use_host_header) {
request_info->destination_service_host = request_info->url_host;
} else {
request_info->destination_service_host = outbound ? "unknown" : getServiceNameFallback();
}
// override the cluster name if this is being sent to the
// blackhole or passthrough cluster
const std::string& route_name = request_info->route_name;
if (route_name == kBlackHoleRouteName) {
request_info->destination_service_name = kBlackHoleCluster;
return;
} else if (route_name == kPassThroughRouteName) {
request_info->destination_service_name = kPassThroughCluster;
return;
}
const std::string& cluster_name = request_info->upstream_cluster;
if (cluster_name == kBlackHoleCluster || cluster_name == kPassThroughCluster ||
cluster_name == kInboundPassthroughClusterIpv4 ||
cluster_name == kInboundPassthroughClusterIpv6) {
request_info->destination_service_name = cluster_name;
return;
}
// Get destination service name and host from cluster labels, which is
// formatted as follow: cluster_metadata:
// filter_metadata:
// istio:
// services:
// - host: a.default
// name: a
// namespace: default
// - host: b.default
// name: b
// namespace: default
// Multiple services could be added to a inbound cluster when they are bound
// to the same port. Currently we use the first service in the list (the
// oldest service) to get destination service information. Ideally client will
// forward the canonical host to the server side so that it could accurately
// identify the intended host.
if (getValue({"cluster_metadata", "filter_metadata", "istio", "services", "0", "name"},
&request_info->destination_service_name)) {
getValue({"cluster_metadata", "filter_metadata", "istio", "services", "0", "host"},
&request_info->destination_service_host);
} else {
// if cluster metadata cannot be found, fallback to destination service
// host. If host header fallback is enabled, this will be host header. If
// host header fallback is disabled, this will be unknown. This could happen
// if a request does not route to any cluster.
request_info->destination_service_name = request_info->destination_service_host;
}
}
} // namespace
void populateRequestInfo(bool outbound, bool use_host_header_fallback, RequestInfo* request_info) {
if (request_info->is_populated) {
return;
}
request_info->is_populated = true;
getValue({"cluster_name"}, &request_info->upstream_cluster);
getValue({"route_name"}, &request_info->route_name);
// Fill in request info.
// Get destination service name and host based on cluster name and host
// header.
populateDestinationService(outbound, use_host_header_fallback, request_info);
uint64_t destination_port = 0;
if (outbound) {
getValue({"upstream", "port"}, &destination_port);
getValue({"upstream", "uri_san_peer_certificate"}, &request_info->destination_principal);
getValue({"upstream", "uri_san_local_certificate"}, &request_info->source_principal);
} else {
getValue({"destination", "port"}, &destination_port);
bool mtls = false;
if (getValue({"connection", "mtls"}, &mtls)) {
request_info->service_auth_policy =
mtls ? ::Wasm::Common::ServiceAuthenticationPolicy::MutualTLS
: ::Wasm::Common::ServiceAuthenticationPolicy::None;
}
getValue({"connection", "uri_san_local_certificate"}, &request_info->destination_principal);
getValue({"connection", "uri_san_peer_certificate"}, &request_info->source_principal);
}
request_info->destination_port = destination_port;
}
std::string_view AuthenticationPolicyString(ServiceAuthenticationPolicy policy) {
switch (policy) {
case ServiceAuthenticationPolicy::None:
return kNone;
case ServiceAuthenticationPolicy::MutualTLS:
return kMutualTLS;
default:
break;
}
return {};
}
std::string_view TCPConnectionStateString(TCPConnectionState state) {
switch (state) {
case TCPConnectionState::Open:
return kOpen;
case TCPConnectionState::Connected:
return kConnected;
case TCPConnectionState::Close:
return kClose;
default:
break;
}
return {};
}
std::string_view ProtocolString(Protocol protocol) {
switch (protocol) {
case Protocol::TCP:
return kProtocolTCP;
case Protocol::HTTP:
return kProtocolHTTP;
case Protocol::GRPC:
return kProtocolGRPC;
default:
break;
}
return {};
}
// Retrieves the traffic direction from the configuration context.
TrafficDirection getTrafficDirection() {
int64_t direction;
if (getValue({"listener_direction"}, &direction)) {
return static_cast<TrafficDirection>(direction);
}
return TrafficDirection::Unspecified;
}
flatbuffers::DetachedBuffer extractEmptyNodeFlatBuffer() {
flatbuffers::FlatBufferBuilder fbb;
FlatNodeBuilder node(fbb);
auto data = node.Finish();
fbb.Finish(data);
return fbb.Release();
}
flatbuffers::DetachedBuffer extractLocalNodeFlatBuffer() {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::Offset<flatbuffers::String> name, namespace_, owner, workload_name, istio_version,
mesh_id, cluster_id;
std::vector<flatbuffers::Offset<KeyVal>> labels, platform_metadata;
std::vector<flatbuffers::Offset<flatbuffers::String>> app_containers;
std::vector<flatbuffers::Offset<flatbuffers::String>> ip_addrs;
std::string value;
if (getValue({"node", "metadata", "NAME"}, &value)) {
name = fbb.CreateString(value);
}
if (getValue({"node", "metadata", "NAMESPACE"}, &value)) {
namespace_ = fbb.CreateString(value);
}
if (getValue({"node", "metadata", "OWNER"}, &value)) {
owner = fbb.CreateString(value);
}
if (getValue({"node", "metadata", "WORKLOAD_NAME"}, &value)) {
workload_name = fbb.CreateString(value);
}
if (getValue({"node", "metadata", "ISTIO_VERSION"}, &value)) {
istio_version = fbb.CreateString(value);
}
if (getValue({"node", "metadata", "MESH_ID"}, &value)) {
mesh_id = fbb.CreateString(value);
}
if (getValue({"node", "metadata", "CLUSTER_ID"}, &value)) {
cluster_id = fbb.CreateString(value);
}
{
auto buf = getProperty({"node", "metadata", "LABELS"});
if (buf.has_value()) {
for (const auto& [key, val] : buf.value()->pairs()) {
labels.push_back(CreateKeyVal(fbb, fbb.CreateString(key), fbb.CreateString(val)));
}
}
}
{
auto buf = getProperty({"node", "metadata", "PLATFORM_METADATA"});
if (buf.has_value()) {
for (const auto& [key, val] : buf.value()->pairs()) {
platform_metadata.push_back(
CreateKeyVal(fbb, fbb.CreateString(key), fbb.CreateString(val)));
}
}
}
if (getValue({"node", "metadata", "APP_CONTAINERS"}, &value)) {
std::vector<absl::string_view> containers = absl::StrSplit(value, ',');
for (const auto& container : containers) {
app_containers.push_back(fbb.CreateString(toStdStringView(container)));
}
}
if (getValue({"node", "metadata", "INSTANCE_IPS"}, &value)) {
std::vector<absl::string_view> ips = absl::StrSplit(value, ',');
for (const auto& ip : ips) {
ip_addrs.push_back(fbb.CreateString(toStdStringView(ip)));
}
}
auto labels_offset = fbb.CreateVectorOfSortedTables(&labels);
auto platform_metadata_offset = fbb.CreateVectorOfSortedTables(&platform_metadata);
auto app_containers_offset = fbb.CreateVector(app_containers);
auto ip_addrs_offset = fbb.CreateVector(ip_addrs);
FlatNodeBuilder node(fbb);
node.add_name(name);
node.add_namespace_(namespace_);
node.add_owner(owner);
node.add_workload_name(workload_name);
node.add_istio_version(istio_version);
node.add_mesh_id(mesh_id);
node.add_cluster_id(cluster_id);
node.add_labels(labels_offset);
node.add_platform_metadata(platform_metadata_offset);
node.add_app_containers(app_containers_offset);
node.add_instance_ips(ip_addrs_offset);
auto data = node.Finish();
fbb.Finish(data);
return fbb.Release();
}
namespace {
bool extractPeerMetadataFromUpstreamMetadata(const std::string& metadata_type,
flatbuffers::FlatBufferBuilder& fbb) {
std::string endpoint_labels;
if (!getValue({metadata_type, "filter_metadata", "istio", "workload"}, &endpoint_labels)) {
return false;
}
std::vector<absl::string_view> parts = absl::StrSplit(endpoint_labels, ';');
// workload label should semicolon separated four parts string:
// workload_name;namespace;canonical_service;canonical_revision;cluster_id.
if (parts.size() < 5) {
return false;
}
flatbuffers::Offset<flatbuffers::String> workload_name, namespace_, cluster_id;
std::vector<flatbuffers::Offset<KeyVal>> labels;
workload_name = fbb.CreateString(toStdStringView(parts[0]));
namespace_ = fbb.CreateString(toStdStringView(parts[1]));
if (!parts[2].empty()) {
labels.push_back(CreateKeyVal(fbb, fbb.CreateString(kCanonicalServiceLabelName),
fbb.CreateString(toStdStringView(parts[2]))));
}
if (!parts[3].empty()) {
labels.push_back(CreateKeyVal(fbb, fbb.CreateString(kCanonicalServiceRevisionLabelName),
fbb.CreateString(toStdStringView(parts[3]))));
}
if (parts.size() >= 5) {
// In case newer proxy runs with old control plane, only extract cluster
// name if there are the fifth part.
cluster_id = fbb.CreateString(toStdStringView(parts[4]));
}
auto labels_offset = fbb.CreateVectorOfSortedTables(&labels);
FlatNodeBuilder node(fbb);
node.add_workload_name(workload_name);
node.add_namespace_(namespace_);
if (!cluster_id.IsNull()) {
node.add_cluster_id(cluster_id);
}
node.add_labels(labels_offset);
auto data = node.Finish();
fbb.Finish(data);
return true;
}
} // namespace
bool extractPeerMetadataFromUpstreamClusterMetadata(flatbuffers::FlatBufferBuilder& fbb) {
return extractPeerMetadataFromUpstreamMetadata("cluster_metadata", fbb);
}
bool extractPeerMetadataFromUpstreamHostMetadata(flatbuffers::FlatBufferBuilder& fbb) {
return extractPeerMetadataFromUpstreamMetadata("upstream_host_metadata", fbb);
}
PeerNodeInfo::PeerNodeInfo(const std::string_view peer_metadata_id_key,
const std::string_view peer_metadata_key) {
// Attempt to read from filter_state first.
found_ = getValue({peer_metadata_id_key}, &peer_id_);
if (found_) {
if (getValue({peer_metadata_key}, &peer_node_)) {
return;
}
}
// Sentinel value is preserved as ID to implement maybeWaiting.
found_ = false;
if (getValue({kMetadataNotFoundValue}, &peer_id_)) {
peer_id_ = kMetadataNotFoundValue;
}
// Downstream peer metadata will never be in localhost endpoint. Skip
// looking for it.
if (peer_metadata_id_key == kDownstreamMetadataIdKey) {
fallback_peer_node_ = extractEmptyNodeFlatBuffer();
return;
}
// Construct a fallback peer node metadata based on endpoint labels if it is
// not in filter state. This may happen before metadata is received as well.
flatbuffers::FlatBufferBuilder fbb;
if (extractPeerMetadataFromUpstreamHostMetadata(fbb)) {
fallback_peer_node_ = fbb.Release();
} else {
fallback_peer_node_ = extractEmptyNodeFlatBuffer();
}
}
const ::Wasm::Common::FlatNode& PeerNodeInfo::get() const {
if (found_) {
return *flatbuffers::GetRoot<::Wasm::Common::FlatNode>(
reinterpret_cast<const uint8_t*>(peer_node_.data()));
}
return *flatbuffers::GetRoot<::Wasm::Common::FlatNode>(fallback_peer_node_.data());
}
// Host header is used if use_host_header_fallback==true.
void populateHTTPRequestInfo(bool outbound, bool use_host_header_fallback,
RequestInfo* request_info) {
populateRequestProtocol(request_info);
getValue({"request", "url_path"}, &request_info->url_path);
populateRequestInfo(outbound, use_host_header_fallback, request_info);
int64_t response_code = 0;
if (getValue({"response", "code"}, &response_code)) {
request_info->response_code = response_code;
}
uint64_t response_flags = 0;
if (getValue({"response", "flags"}, &response_flags)) {
request_info->response_flag = parseResponseFlag(response_flags);
}
if (request_info->request_protocol == Protocol::GRPC) {
int64_t grpc_status_code = 2;
getValue({"response", "grpc_status"}, &grpc_status_code);
request_info->grpc_status = grpc_status_code;
populateGRPCInfo(request_info);
}
std::string operation_id;
request_info->request_operation =
getValue({::Wasm::Common::kRequestOperationKey}, &operation_id)
? operation_id
: getHeaderMapValue(WasmHeaderMapType::RequestHeaders, kMethodHeaderKey)->toString();
getValue({"request", "time"}, &request_info->start_time);
getValue({"request", "duration"}, &request_info->duration);
getValue({"request", "total_size"}, &request_info->request_size);
getValue({"response", "total_size"}, &request_info->response_size);
}
std::string_view nodeInfoSchema() {
return std::string_view(reinterpret_cast<const char*>(FlatNodeBinarySchema::data()),
FlatNodeBinarySchema::size());
}
void populateExtendedHTTPRequestInfo(RequestInfo* request_info) {
populateExtendedRequestInfo(request_info);
if (getValue({"request", "referer"}, &request_info->referer)) {
sanitizeBytes(&request_info->referer);
}
if (getValue({"request", "useragent"}, &request_info->user_agent)) {
sanitizeBytes(&request_info->user_agent);
}
if (getValue({"request", "id"}, &request_info->request_id)) {
sanitizeBytes(&request_info->request_id);
}
std::string trace_sampled;
if (getValue({"request", "headers", "x-b3-sampled"}, &trace_sampled) && trace_sampled == "1") {
if (getValue({"request", "headers", "x-b3-traceid"}, &request_info->b3_trace_id)) {
sanitizeBytes(&request_info->b3_trace_id);
}
if (getValue({"request", "headers", "x-b3-spanid"}, &request_info->b3_span_id)) {
sanitizeBytes(&request_info->b3_span_id);
}
request_info->b3_trace_sampled = true;
}
getValue({"request", "path"}, &request_info->path);
getValue({"request", "host"}, &request_info->url_host);
getValue({"request", "scheme"}, &request_info->url_scheme);
std::string response_details;
getValue({"response", "code_details"}, &response_details);
if (!response_details.empty()) {
request_info->response_details = response_details;
}
}
void populateExtendedRequestInfo(RequestInfo* request_info) {
getValue({"source", "address"}, &request_info->source_address);
getValue({"destination", "address"}, &request_info->destination_address);
getValue({"source", "port"}, &request_info->source_port);
getValue({"connection_id"}, &request_info->connection_id);
getValue({"upstream", "address"}, &request_info->upstream_host);
getValue({"connection", "requested_server_name"}, &request_info->requested_server_name);
auto envoy_original_path =
getHeaderMapValue(WasmHeaderMapType::RequestHeaders, kEnvoyOriginalPathKey);
request_info->x_envoy_original_path = envoy_original_path ? envoy_original_path->toString() : "";
sanitizeBytes(&request_info->x_envoy_original_path);
auto envoy_original_dst_host =
getHeaderMapValue(WasmHeaderMapType::RequestHeaders, kEnvoyOriginalDstHostKey);
request_info->x_envoy_original_dst_host =
envoy_original_dst_host ? envoy_original_dst_host->toString() : "";
sanitizeBytes(&request_info->x_envoy_original_dst_host);
getValue({"upstream", "transport_failure_reason"},
&request_info->upstream_transport_failure_reason);
std::string response_details;
getValue({"connection", "termination_details"}, &response_details);
if (!response_details.empty()) {
request_info->response_details = response_details;
}
}
void populateTCPRequestInfo(bool outbound, RequestInfo* request_info) {
// host_header_fallback is for HTTP/gRPC only.
populateRequestInfo(outbound, false, request_info);
uint64_t response_flags = 0;
if (getValue({"response", "flags"}, &response_flags)) {
request_info->response_flag = parseResponseFlag(response_flags);
}
request_info->request_protocol = Protocol::TCP;
}
void populateRequestProtocol(RequestInfo* request_info) {
if (kGrpcContentTypes.count(
getHeaderMapValue(WasmHeaderMapType::RequestHeaders, kContentTypeHeaderKey)
->toString()) != 0) {
request_info->request_protocol = Protocol::GRPC;
} else {
// TODO Add http/1.1, http/1.0, http/2 in a separate attribute.
// http|grpc classification is compatible with Mixerclient
request_info->request_protocol = Protocol::HTTP;
}
}
bool populateGRPCInfo(RequestInfo* request_info) {
std::string value;
if (!getValue({"filter_state", GrpcStatsName}, &value)) {
return false;
}
// The expected byte serialization of grpc_stats filter is "x,y" where "x"
// is the request message count and "y" is the response message count.
std::vector<absl::string_view> parts = absl::StrSplit(value, ',');
if (parts.size() == 2) {
return absl::SimpleAtoi(parts[0], &request_info->request_message_count) &&
absl::SimpleAtoi(parts[1], &request_info->response_message_count);
}
return false;
}
bool getAuditPolicy() {
bool shouldAudit = false;
if (!getValue<bool>({"metadata", "filter_metadata", "envoy.common", "access_log_hint"},
&shouldAudit)) {
return false;
}
return shouldAudit;
}
bool sanitizeBytes(std::string* buf) {
char* start = buf->data();
const char* const end = start + buf->length();
bool modified = false;
while (start < end) {
char* s = start;
if (flatbuffers::FromUTF8(const_cast<const char**>(&s)) < 0) {
*start = ' ';
start += 1;
modified = true;
} else {
start = s;
}
}
return modified;
}
// Used for `destination_service` fallback. Unlike elsewhere when that fallback
// to workload name, this falls back to "unknown" when the canonical name label
// is not found. This preserves the existing behavior for `destination_service`
// labeling. Using a workload name as a service name could be potentially
// problematic.
std::string getServiceNameFallback() {
auto buf = getProperty({"node", "metadata", "LABELS"});
if (buf.has_value()) {
for (const auto& [key, val] : buf.value()->pairs())
if (key == ::Wasm::Common::kCanonicalServiceLabelName.data()) {
return std::string(val);
}
}
return "unknown";
}
} // namespace Common
} // namespace Wasm

View File

@ -1,302 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <set>
#include "extensions/common/node_info_generated.h"
#include "flatbuffers/flatbuffers.h"
namespace Wasm {
namespace Common {
// Node metadata
constexpr std::string_view WholeNodeKey = ".";
constexpr std::string_view kUpstreamMetadataIdKey = "upstream_peer_id";
constexpr std::string_view kUpstreamMetadataKey = "upstream_peer";
constexpr std::string_view kDownstreamMetadataIdKey = "downstream_peer_id";
constexpr std::string_view kDownstreamMetadataKey = "downstream_peer";
// Sentinel key in the filter state, indicating that the peer metadata is
// decidedly absent. This is different from a missing peer metadata ID key
// which could indicate that the metadata is not received yet.
const std::string kMetadataNotFoundValue = "envoy.wasm.metadata_exchange.peer_unknown";
constexpr std::string_view kAccessLogPolicyKey = "istio.access_log_policy";
constexpr std::string_view kRequestOperationKey = "istio_operationId";
// Header keys
constexpr std::string_view kAuthorityHeaderKey = ":authority";
constexpr std::string_view kMethodHeaderKey = ":method";
constexpr std::string_view kContentTypeHeaderKey = "content-type";
constexpr std::string_view kEnvoyOriginalDstHostKey = "x-envoy-original-dst-host";
constexpr std::string_view kEnvoyOriginalPathKey = "x-envoy-original-path";
constexpr std::string_view kProtocolHTTP = "http";
constexpr std::string_view kProtocolGRPC = "grpc";
constexpr std::string_view kProtocolTCP = "tcp";
constexpr std::string_view kCanonicalServiceLabelName = "service.istio.io/canonical-name";
constexpr std::string_view kCanonicalServiceRevisionLabelName =
"service.istio.io/canonical-revision";
constexpr std::string_view kLatest = "latest";
const std::set<std::string> kGrpcContentTypes{"application/grpc", "application/grpc+proto",
"application/grpc+json"};
enum class ServiceAuthenticationPolicy : uint8_t {
Unspecified = 0,
None = 1,
MutualTLS = 2,
};
enum class TCPConnectionState : uint8_t {
Unspecified = 0,
Open = 1,
Connected = 2,
Close = 3,
};
enum class Protocol : uint32_t {
Unspecified = 0x0,
TCP = 0x1,
HTTP = 0x2,
GRPC = 0x4,
};
constexpr std::string_view kMutualTLS = "MUTUAL_TLS";
constexpr std::string_view kNone = "NONE";
constexpr std::string_view kOpen = "OPEN";
constexpr std::string_view kConnected = "CONNECTED";
constexpr std::string_view kClose = "CLOSE";
std::string_view AuthenticationPolicyString(ServiceAuthenticationPolicy policy);
std::string_view TCPConnectionStateString(TCPConnectionState state);
std::string_view ProtocolString(Protocol protocol);
// RequestInfo represents the information collected from filter stream
// callbacks. This is used to fill metrics and logs.
struct RequestInfo {
// Start timestamp in nanoseconds.
int64_t start_time;
// The total duration of the request in nanoseconds.
int64_t duration;
// Request total size in bytes, include header, body, and trailer.
int64_t request_size = 0;
// Response total size in bytes, include header, body, and trailer.
int64_t response_size = 0;
// Destination port that the request targets.
uint32_t destination_port = 0;
// Source port of the client.
uint64_t source_port = 0;
// Protocol used the request (HTTP/1.1, gRPC, etc).
Protocol request_protocol = Protocol::Unspecified;
// Response code of the request.
uint32_t response_code = 0;
// gRPC status code for the request.
uint32_t grpc_status = 2;
// Response flag giving additional information - NR, UAEX etc.
std::string response_flag;
// Host name of destination service.
std::string destination_service_host;
// Short name of destination service.
std::string destination_service_name;
// Operation of the request, i.e. HTTP method or gRPC API method.
std::string request_operation;
std::string upstream_transport_failure_reason;
// Service authentication policy (NONE, MUTUAL_TLS)
ServiceAuthenticationPolicy service_auth_policy = ServiceAuthenticationPolicy::Unspecified;
// Principal of source and destination workload extracted from TLS
// certificate.
std::string source_principal;
std::string destination_principal;
// Connection id of the TCP connection.
uint64_t connection_id;
// The following fields will only be populated by calling
// populateExtendedHTTPRequestInfo.
std::string source_address;
std::string destination_address;
std::string response_details;
// Additional fields for access log.
std::string route_name;
std::string upstream_host;
std::string upstream_cluster;
std::string requested_server_name;
std::string x_envoy_original_path;
std::string x_envoy_original_dst_host;
// Important Headers.
std::string referer;
std::string user_agent;
std::string request_id;
std::string b3_trace_id;
std::string b3_span_id;
bool b3_trace_sampled = false;
// HTTP URL related attributes.
// The path portion of the URL including the query string.
std::string path;
// The path portion of the URL without the query string.
std::string url_path;
std::string url_host;
std::string url_scheme;
// TCP variables.
uint8_t tcp_connections_opened = 0;
uint8_t tcp_connections_closed = 0;
uint64_t tcp_sent_bytes = 0;
uint64_t tcp_received_bytes = 0;
uint64_t tcp_total_sent_bytes = 0;
uint64_t tcp_total_received_bytes = 0;
TCPConnectionState tcp_connection_state = TCPConnectionState::Unspecified;
bool is_populated = false;
bool log_sampled = false;
// gRPC variables.
uint64_t request_message_count = 0;
uint64_t response_message_count = 0;
uint64_t last_request_message_count = 0;
uint64_t last_response_message_count = 0;
};
// RequestContext contains all the information available in the request.
// Some or all part may be populated depending on need.
struct RequestContext {
const bool outbound;
const Common::RequestInfo& request;
};
// TrafficDirection is a mirror of envoy xDS traffic direction.
enum class TrafficDirection : int64_t {
Unspecified = 0,
Inbound = 1,
Outbound = 2,
};
// Retrieves the traffic direction from the configuration context.
TrafficDirection getTrafficDirection();
// Convenience routine to create an empty node flatbuffer.
flatbuffers::DetachedBuffer extractEmptyNodeFlatBuffer();
// Extract local node metadata into a flatbuffer. Detached buffer owns the
// underlying heap-allocated memory. Note that std::string is inappropriate here
// because its memory is inlined for short strings and causes a misaligned
// address access.
flatbuffers::DetachedBuffer extractLocalNodeFlatBuffer();
// Extract upstream peer metadata from upstream host metadata.
// Returns true if the metadata is found in the upstream host metadata.
bool extractPeerMetadataFromUpstreamHostMetadata(flatbuffers::FlatBufferBuilder& fbb);
// Extract upstream peer metadata from upstream cluster metadata.
// Returns true if the metadata is found in the upstream cluster metadata.
bool extractPeerMetadataFromUpstreamClusterMetadata(flatbuffers::FlatBufferBuilder& fbb);
// Returns flatbuffer schema for node info.
std::string_view nodeInfoSchema();
class PeerNodeInfo {
public:
explicit PeerNodeInfo(const std::string_view peer_metadata_id_key,
const std::string_view peer_metadata_key);
PeerNodeInfo() = delete;
const ::Wasm::Common::FlatNode& get() const;
const std::string& id() const { return peer_id_; }
// Found indicates whether both ID and metadata is available.
bool found() const { return found_; }
// Maybe waiting indicates that the metadata is not found but may arrive
// later.
bool maybeWaiting() const {
return !found_ && peer_id_ != ::Wasm::Common::kMetadataNotFoundValue;
}
private:
bool found_;
std::string peer_id_;
std::string peer_node_;
flatbuffers::DetachedBuffer fallback_peer_node_;
};
// Populate shared information between all protocols.
// Requires that the connections are established both downstrean and upstream.
// Caches computation using is_populated field.
void populateRequestInfo(bool outbound, bool use_host_header_fallback, RequestInfo* request_info);
// populateHTTPRequestInfo populates the RequestInfo struct. It needs access to
// the request context.
void populateHTTPRequestInfo(bool outbound, bool use_host_header, RequestInfo* request_info);
// populateExtendedHTTPRequestInfo populates the extra fields in RequestInfo
// struct, includes trace headers, request id headers, and url.
void populateExtendedHTTPRequestInfo(RequestInfo* request_info);
// populateExtendedRequestInfo populates the extra fields in RequestInfo
// source address, destination address.
void populateExtendedRequestInfo(RequestInfo* request_info);
// populateTCPRequestInfo populates the RequestInfo struct. It needs access to
// the request context.
void populateTCPRequestInfo(bool outbound, RequestInfo* request_info);
// Detect HTTP and gRPC request protocols.
void populateRequestProtocol(RequestInfo* request_info);
// populateGRPCInfo fills gRPC-related information, such as message counts.
// Returns true if all information is filled.
bool populateGRPCInfo(RequestInfo* request_info);
// Read value of 'access_log_hint' key from envoy dynamic metadata which
// determines whether to audit a request or not.
bool getAuditPolicy();
// Returns a string view stored in a flatbuffers string.
static inline std::string_view GetFromFbStringView(const flatbuffers::String* str) {
return str ? std::string_view(str->c_str(), str->size()) : std::string_view();
}
// Sanitizes a possible UTF-8 byte buffer to a UTF-8 string.
// Invalid byte sequences are replaced by spaces.
// Returns true if the string was modified.
bool sanitizeBytes(std::string* buf);
std::string getServiceNameFallback();
} // namespace Common
} // namespace Wasm

View File

@ -1,103 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <set>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_replace.h"
namespace Wasm {
namespace Common {
#define STD_ISTIO_DIMENSIONS(FIELD_FUNC) \
FIELD_FUNC(downstream_ip) \
FIELD_FUNC(reporter) \
FIELD_FUNC(source_workload) \
FIELD_FUNC(source_workload_namespace) \
FIELD_FUNC(source_principal) \
FIELD_FUNC(source_app) \
FIELD_FUNC(source_version) \
FIELD_FUNC(source_canonical_service) \
FIELD_FUNC(source_canonical_revision) \
FIELD_FUNC(destination_workload) \
FIELD_FUNC(destination_workload_namespace) \
FIELD_FUNC(destination_principal) \
FIELD_FUNC(destination_app) \
FIELD_FUNC(destination_version) \
FIELD_FUNC(destination_service) \
FIELD_FUNC(destination_service_name) \
FIELD_FUNC(destination_service_namespace) \
FIELD_FUNC(destination_canonical_service) \
FIELD_FUNC(destination_canonical_revision) \
FIELD_FUNC(destination_port) \
FIELD_FUNC(request_protocol) \
FIELD_FUNC(response_code) \
FIELD_FUNC(grpc_response_status) \
FIELD_FUNC(response_flags) \
FIELD_FUNC(connection_security_policy)
// A structure that can hold multiple Istio dimensions(metadata variables).
// This could be use to key caches based on Istio dimensions for various
// filters.
// Note: This is supposed to be used with absl::flat_hash_map only.
// TODO: Add support for evaluating dynamic Istio dimensions.
struct IstioDimensions {
#define DEFINE_FIELD(name) std::string(name);
STD_ISTIO_DIMENSIONS(DEFINE_FIELD)
#undef DEFINE_FIELD
bool outbound = false;
#define SET_FIELD(name) \
IstioDimensions& set_##name(std::string value) { \
name = value; \
return *this; \
}
STD_ISTIO_DIMENSIONS(SET_FIELD)
#undef SET_FIELD
IstioDimensions& set_outbound(bool value) {
outbound = value;
return *this;
}
std::string to_string() const {
#define TO_STRING(name) "\"", #name, "\":\"", name, "\" ,",
return absl::StrCat("{" STD_ISTIO_DIMENSIONS(TO_STRING) "\"outbound\": ", outbound, "}");
#undef TO_STRING
}
// This function is required to make IstioDimensions type hashable.
template <typename H> friend H AbslHashValue(H h, IstioDimensions d) {
#define TO_HASH_VALUE(name) , d.name
return H::combine(std::move(h) STD_ISTIO_DIMENSIONS(TO_HASH_VALUE), d.outbound);
#undef TO_HASH_VALUE
}
// This function is required to make IstioDimensions type hashable.
friend bool operator==(const IstioDimensions& lhs, const IstioDimensions& rhs) {
return (
#define COMPARE(name) lhs.name == rhs.name&&
STD_ISTIO_DIMENSIONS(COMPARE) lhs.outbound == rhs.outbound);
#undef COMPARE
}
};
} // namespace Common
} // namespace Wasm

View File

@ -1,57 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/common/istio_dimensions.h"
#include "absl/hash/hash_testing.h"
#include "gtest/gtest.h"
namespace Wasm {
namespace Common {
namespace {
TEST(WasmCommonIstioDimensionsTest, VerifyHashing) {
EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
IstioDimensions{},
IstioDimensions().set_request_protocol("wrpc"),
IstioDimensions().set_request_protocol("grpc").set_response_code("200"),
IstioDimensions().set_request_protocol("grpc").set_response_code("400"),
IstioDimensions().set_source_app("app_source").set_request_protocol("grpc"),
IstioDimensions()
.set_source_app("app_source")
.set_source_version("v2")
.set_request_protocol("grpc"),
IstioDimensions()
.set_source_app("app_source")
.set_source_version("v2")
.set_request_protocol("grpc")
.set_outbound(true),
IstioDimensions()
.set_source_app("app_source")
.set_source_version("v2")
.set_request_protocol("grpc")
.set_outbound(true),
IstioDimensions()
.set_source_app("app_source")
.set_source_version("v2")
.set_request_protocol("grpc")
.set_grpc_response_status("12")
.set_outbound(true),
}));
}
} // namespace
} // namespace Common
} // namespace Wasm

View File

@ -14,24 +14,26 @@
#include "extensions/common/metadata_object.h"
#include "absl/strings/str_join.h"
#include "flatbuffers/flatbuffers.h"
#include "envoy/registry/registry.h"
#include "source/common/common/hash.h"
#include "source/common/protobuf/utility.h"
#include "absl/strings/str_join.h"
namespace Istio {
namespace Common {
namespace {
static absl::flat_hash_map<absl::string_view, BaggageToken> ALL_BAGGAGE_TOKENS = {
{NamespaceNameToken, BaggageToken::NamespaceName},
{ClusterNameToken, BaggageToken::ClusterName},
{ServiceNameToken, BaggageToken::ServiceName},
{ServiceVersionToken, BaggageToken::ServiceVersion},
{PodNameToken, BaggageToken::PodName},
{DeploymentNameToken, BaggageToken::DeploymentName},
{JobNameToken, BaggageToken::JobName},
{CronJobNameToken, BaggageToken::CronJobName},
{AppNameToken, BaggageToken::AppName},
{AppVersionToken, BaggageToken::AppVersion},
{WorkloadNameToken, BaggageToken::WorkloadName},
{WorkloadTypeToken, BaggageToken::WorkloadType},
{InstanceNameToken, BaggageToken::InstanceName},
};
static absl::flat_hash_map<absl::string_view, WorkloadType> ALL_WORKLOAD_TOKENS = {
@ -41,9 +43,283 @@ static absl::flat_hash_map<absl::string_view, WorkloadType> ALL_WORKLOAD_TOKENS
{CronJobSuffix, WorkloadType::CronJob},
};
WorkloadMetadataObject WorkloadMetadataObject::fromBaggage(absl::string_view baggage_header_value) {
// TODO: check for well-formed-ness of the baggage string: duplication,
// inconsistency
absl::optional<absl::string_view> toSuffix(WorkloadType workload_type) {
switch (workload_type) {
case WorkloadType::Deployment:
return DeploymentSuffix;
case WorkloadType::CronJob:
return CronJobSuffix;
case WorkloadType::Job:
return JobSuffix;
case WorkloadType::Pod:
return PodSuffix;
case WorkloadType::Unknown:
return {};
}
}
} // namespace
Envoy::ProtobufTypes::MessagePtr WorkloadMetadataObject::serializeAsProto() const {
auto message = std::make_unique<Envoy::ProtobufWkt::Struct>();
const auto suffix = toSuffix(workload_type_);
if (suffix) {
(*message->mutable_fields())[WorkloadTypeToken].set_string_value(*suffix);
}
if (!workload_name_.empty()) {
(*message->mutable_fields())[WorkloadNameToken].set_string_value(workload_name_);
}
if (!cluster_name_.empty()) {
(*message->mutable_fields())[InstanceNameToken].set_string_value(instance_name_);
}
if (!cluster_name_.empty()) {
(*message->mutable_fields())[ClusterNameToken].set_string_value(cluster_name_);
}
if (!namespace_name_.empty()) {
(*message->mutable_fields())[NamespaceNameToken].set_string_value(namespace_name_);
}
if (!canonical_name_.empty()) {
(*message->mutable_fields())[ServiceNameToken].set_string_value(canonical_name_);
}
if (!canonical_revision_.empty()) {
(*message->mutable_fields())[ServiceVersionToken].set_string_value(canonical_revision_);
}
if (!app_name_.empty()) {
(*message->mutable_fields())[AppNameToken].set_string_value(app_name_);
}
if (!app_version_.empty()) {
(*message->mutable_fields())[AppVersionToken].set_string_value(app_version_);
}
if (!identity_.empty()) {
(*message->mutable_fields())[IdentityToken].set_string_value(identity_);
}
if (!labels_.empty()) {
auto* labels = (*message->mutable_fields())[LabelsToken].mutable_struct_value();
for (const auto& l : labels_) {
(*labels->mutable_fields())[std::string(l.first)].set_string_value(std::string(l.second));
}
}
return message;
}
std::vector<std::pair<absl::string_view, absl::string_view>>
WorkloadMetadataObject::serializeAsPairs() const {
std::vector<std::pair<absl::string_view, absl::string_view>> parts;
const auto suffix = toSuffix(workload_type_);
if (suffix) {
parts.push_back({WorkloadTypeToken, *suffix});
}
if (!workload_name_.empty()) {
parts.push_back({WorkloadNameToken, workload_name_});
}
if (!instance_name_.empty()) {
parts.push_back({InstanceNameToken, instance_name_});
}
if (!cluster_name_.empty()) {
parts.push_back({ClusterNameToken, cluster_name_});
}
if (!namespace_name_.empty()) {
parts.push_back({NamespaceNameToken, namespace_name_});
}
if (!canonical_name_.empty()) {
parts.push_back({ServiceNameToken, canonical_name_});
}
if (!canonical_revision_.empty()) {
parts.push_back({ServiceVersionToken, canonical_revision_});
}
if (!app_name_.empty()) {
parts.push_back({AppNameToken, app_name_});
}
if (!app_version_.empty()) {
parts.push_back({AppVersionToken, app_version_});
}
if (!labels_.empty()) {
for (const auto& l : labels_) {
parts.push_back({absl::StrCat("labels[]", l.first), absl::string_view(l.second)});
}
}
return parts;
}
absl::optional<std::string> WorkloadMetadataObject::serializeAsString() const {
const auto parts = serializeAsPairs();
return absl::StrJoin(parts, ",", absl::PairFormatter("="));
}
absl::optional<uint64_t> WorkloadMetadataObject::hash() const {
return Envoy::HashUtil::xxHash64(*serializeAsString());
}
absl::optional<std::string> WorkloadMetadataObject::owner() const {
const auto suffix = toSuffix(workload_type_);
if (suffix) {
return absl::StrCat(OwnerPrefix, namespace_name_, "/", *suffix, "s/", workload_name_);
}
return {};
}
WorkloadType fromSuffix(absl::string_view suffix) {
const auto it = ALL_WORKLOAD_TOKENS.find(suffix);
if (it != ALL_WORKLOAD_TOKENS.end()) {
return it->second;
}
return WorkloadType::Unknown;
}
WorkloadType parseOwner(absl::string_view owner, absl::string_view workload) {
// Strip "s/workload_name" and check for workload type.
if (owner.size() > workload.size() + 2) {
owner.remove_suffix(workload.size() + 2);
size_t last = owner.rfind('/');
if (last != absl::string_view::npos) {
return fromSuffix(owner.substr(last + 1));
}
}
return WorkloadType::Unknown;
}
google::protobuf::Struct convertWorkloadMetadataToStruct(const WorkloadMetadataObject& obj) {
google::protobuf::Struct metadata;
if (!obj.instance_name_.empty()) {
(*metadata.mutable_fields())[InstanceMetadataField].set_string_value(obj.instance_name_);
}
if (!obj.namespace_name_.empty()) {
(*metadata.mutable_fields())[NamespaceMetadataField].set_string_value(obj.namespace_name_);
}
if (!obj.workload_name_.empty()) {
(*metadata.mutable_fields())[WorkloadMetadataField].set_string_value(obj.workload_name_);
}
if (!obj.cluster_name_.empty()) {
(*metadata.mutable_fields())[ClusterMetadataField].set_string_value(obj.cluster_name_);
}
auto* labels = (*metadata.mutable_fields())[LabelsMetadataField].mutable_struct_value();
if (!obj.canonical_name_.empty()) {
(*labels->mutable_fields())[CanonicalNameLabel].set_string_value(obj.canonical_name_);
}
if (!obj.canonical_revision_.empty()) {
(*labels->mutable_fields())[CanonicalRevisionLabel].set_string_value(obj.canonical_revision_);
}
if (!obj.app_name_.empty()) {
(*labels->mutable_fields())[AppNameLabel].set_string_value(obj.app_name_);
}
if (!obj.app_version_.empty()) {
(*labels->mutable_fields())[AppVersionLabel].set_string_value(obj.app_version_);
}
if (!obj.getLabels().empty()) {
for (const auto& lbl : obj.getLabels()) {
(*labels->mutable_fields())[std::string(lbl.first)].set_string_value(std::string(lbl.second));
}
}
if (const auto owner = obj.owner(); owner.has_value()) {
(*metadata.mutable_fields())[OwnerMetadataField].set_string_value(*owner);
}
return metadata;
}
// Convert struct to a metadata object.
std::unique_ptr<WorkloadMetadataObject>
convertStructToWorkloadMetadata(const google::protobuf::Struct& metadata) {
return convertStructToWorkloadMetadata(metadata, {});
}
std::unique_ptr<WorkloadMetadataObject>
convertStructToWorkloadMetadata(const google::protobuf::Struct& metadata,
const absl::flat_hash_set<std::string>& additional_labels) {
absl::string_view instance, namespace_name, owner, workload, cluster, canonical_name,
canonical_revision, app_name, app_version;
std::vector<std::pair<std::string, std::string>> labels;
for (const auto& it : metadata.fields()) {
if (it.first == InstanceMetadataField) {
instance = it.second.string_value();
} else if (it.first == NamespaceMetadataField) {
namespace_name = it.second.string_value();
} else if (it.first == OwnerMetadataField) {
owner = it.second.string_value();
} else if (it.first == WorkloadMetadataField) {
workload = it.second.string_value();
} else if (it.first == ClusterMetadataField) {
cluster = it.second.string_value();
} else if (it.first == LabelsMetadataField) {
for (const auto& labels_it : it.second.struct_value().fields()) {
if (labels_it.first == CanonicalNameLabel) {
canonical_name = labels_it.second.string_value();
} else if (labels_it.first == CanonicalRevisionLabel) {
canonical_revision = labels_it.second.string_value();
} else if (labels_it.first == AppNameLabel) {
app_name = labels_it.second.string_value();
} else if (labels_it.first == AppVersionLabel) {
app_version = labels_it.second.string_value();
} else if (!additional_labels.empty() &&
additional_labels.contains(std::string(labels_it.first))) {
labels.push_back(
{std::string(labels_it.first), std::string(labels_it.second.string_value())});
}
}
}
}
auto obj = std::make_unique<WorkloadMetadataObject>(instance, cluster, namespace_name, workload,
canonical_name, canonical_revision, app_name,
app_version, parseOwner(owner, workload), "");
obj->setLabels(labels);
return obj;
}
absl::optional<WorkloadMetadataObject>
convertEndpointMetadata(const std::string& endpoint_encoding) {
std::vector<absl::string_view> parts = absl::StrSplit(endpoint_encoding, ';');
if (parts.size() < 5) {
return {};
}
return absl::make_optional<WorkloadMetadataObject>("", parts[4], parts[1], parts[0], parts[2],
parts[3], "", "", WorkloadType::Unknown, "");
}
std::string serializeToStringDeterministic(const google::protobuf::Struct& metadata) {
std::string out;
{
google::protobuf::io::StringOutputStream md(&out);
google::protobuf::io::CodedOutputStream mcs(&md);
mcs.SetSerializationDeterministic(true);
if (!metadata.SerializeToCodedStream(&mcs)) {
out.clear();
}
}
return out;
}
WorkloadMetadataObject::FieldType
WorkloadMetadataObject::getField(absl::string_view field_name) const {
const auto it = ALL_BAGGAGE_TOKENS.find(field_name);
if (it != ALL_BAGGAGE_TOKENS.end()) {
switch (it->second) {
case BaggageToken::NamespaceName:
return namespace_name_;
case BaggageToken::ClusterName:
return cluster_name_;
case BaggageToken::ServiceName:
return canonical_name_;
case BaggageToken::ServiceVersion:
return canonical_revision_;
case BaggageToken::AppName:
return app_name_;
case BaggageToken::AppVersion:
return app_version_;
case BaggageToken::WorkloadName:
return workload_name_;
case BaggageToken::WorkloadType:
if (const auto value = toSuffix(workload_type_); value.has_value()) {
return *value;
}
case BaggageToken::InstanceName:
return instance_name_;
}
}
return {};
}
std::unique_ptr<WorkloadMetadataObject> convertBaggageToWorkloadMetadata(absl::string_view data) {
absl::string_view instance;
absl::string_view cluster;
absl::string_view workload;
@ -52,11 +328,10 @@ WorkloadMetadataObject WorkloadMetadataObject::fromBaggage(absl::string_view bag
absl::string_view canonical_revision;
absl::string_view app_name;
absl::string_view app_version;
WorkloadType workload_type = WorkloadType::Pod;
std::vector<absl::string_view> properties = absl::StrSplit(baggage_header_value, ',');
WorkloadType workload_type = WorkloadType::Unknown;
std::vector<absl::string_view> properties = absl::StrSplit(data, ',');
for (absl::string_view property : properties) {
std::pair<absl::string_view, absl::string_view> parts = absl::StrSplit(property, "=");
std::pair<absl::string_view, absl::string_view> parts = absl::StrSplit(property, '=');
const auto it = ALL_BAGGAGE_TOKENS.find(parts.first);
if (it != ALL_BAGGAGE_TOKENS.end()) {
switch (it->second) {
@ -72,240 +347,27 @@ WorkloadMetadataObject WorkloadMetadataObject::fromBaggage(absl::string_view bag
case BaggageToken::ServiceVersion:
canonical_revision = parts.second;
break;
case BaggageToken::PodName:
workload_type = WorkloadType::Pod;
instance = parts.second;
workload = parts.second;
break;
case BaggageToken::DeploymentName:
workload_type = WorkloadType::Deployment;
workload = parts.second;
break;
case BaggageToken::JobName:
workload_type = WorkloadType::Job;
instance = parts.second;
workload = parts.second;
break;
case BaggageToken::CronJobName:
workload_type = WorkloadType::CronJob;
workload = parts.second;
break;
case BaggageToken::AppName:
app_name = parts.second;
break;
case BaggageToken::AppVersion:
app_version = parts.second;
break;
case BaggageToken::WorkloadName:
workload = parts.second;
break;
case BaggageToken::WorkloadType:
workload_type = fromSuffix(parts.second);
break;
case BaggageToken::InstanceName:
instance = parts.second;
break;
}
}
}
return WorkloadMetadataObject(instance, cluster, namespace_name, workload, canonical_name,
canonical_revision, app_name, app_version, workload_type);
}
std::string WorkloadMetadataObject::baggage() const {
absl::string_view workload_type = PodSuffix;
switch (workload_type_) {
case WorkloadType::Deployment:
workload_type = DeploymentSuffix;
break;
case WorkloadType::CronJob:
workload_type = CronJobSuffix;
break;
case WorkloadType::Job:
workload_type = JobSuffix;
break;
case WorkloadType::Pod:
workload_type = PodSuffix;
break;
default:
break;
}
std::vector<absl::string_view> parts;
parts.push_back("k8s.");
parts.push_back(workload_type);
parts.push_back(".name=");
parts.push_back(workload_name_);
if (!cluster_name_.empty()) {
parts.push_back(",");
parts.push_back(ClusterNameToken);
parts.push_back("=");
parts.push_back(cluster_name_);
}
if (!namespace_name_.empty()) {
parts.push_back(",");
parts.push_back(NamespaceNameToken);
parts.push_back("=");
parts.push_back(namespace_name_);
}
if (!canonical_name_.empty()) {
parts.push_back(",");
parts.push_back(ServiceNameToken);
parts.push_back("=");
parts.push_back(canonical_name_);
}
if (!canonical_revision_.empty()) {
parts.push_back(",");
parts.push_back(ServiceVersionToken);
parts.push_back("=");
parts.push_back(canonical_revision_);
}
if (!app_name_.empty()) {
parts.push_back(",");
parts.push_back(AppNameToken);
parts.push_back("=");
parts.push_back(app_name_);
}
if (!app_version_.empty()) {
parts.push_back(",");
parts.push_back(AppVersionToken);
parts.push_back("=");
parts.push_back(app_version_);
}
return absl::StrJoin(parts, "");
}
absl::optional<uint64_t> WorkloadMetadataObject::hash() const {
return Envoy::HashUtil::xxHash64(absl::StrCat(instance_name_, "/", namespace_name_));
}
namespace {
// Returns a string view stored in a flatbuffers string.
absl::string_view toAbslStringView(const flatbuffers::String* str) {
return str ? absl::string_view(str->c_str(), str->size()) : absl::string_view();
}
std::string_view toStdStringView(absl::string_view view) {
return std::string_view(view.data(), view.size());
}
} // namespace
std::string convertWorkloadMetadataToFlatNode(const WorkloadMetadataObject& obj) {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::Offset<flatbuffers::String> name, cluster, namespace_, workload_name, owner;
std::vector<flatbuffers::Offset<Wasm::Common::KeyVal>> labels;
name = fbb.CreateString(toStdStringView(obj.instance_name_));
namespace_ = fbb.CreateString(toStdStringView(obj.namespace_name_));
cluster = fbb.CreateString(toStdStringView(obj.cluster_name_));
workload_name = fbb.CreateString(toStdStringView(obj.workload_name_));
switch (obj.workload_type_) {
case WorkloadType::Deployment:
owner = fbb.CreateString(absl::StrCat(OwnerPrefix, obj.namespace_name_, "/", DeploymentSuffix,
"s/", obj.workload_name_));
break;
case WorkloadType::Job:
owner = fbb.CreateString(
absl::StrCat(OwnerPrefix, obj.namespace_name_, "/", JobSuffix, "s/", obj.workload_name_));
break;
case WorkloadType::CronJob:
owner = fbb.CreateString(absl::StrCat(OwnerPrefix, obj.namespace_name_, "/", CronJobSuffix,
"s/", obj.workload_name_));
break;
case WorkloadType::Pod:
owner = fbb.CreateString(
absl::StrCat(OwnerPrefix, obj.namespace_name_, "/", PodSuffix, "s/", obj.workload_name_));
break;
}
labels.push_back(
Wasm::Common::CreateKeyVal(fbb, fbb.CreateString("service.istio.io/canonical-name"),
fbb.CreateString(toStdStringView(obj.canonical_name_))));
labels.push_back(
Wasm::Common::CreateKeyVal(fbb, fbb.CreateString("service.istio.io/canonical-revision"),
fbb.CreateString(toStdStringView(obj.canonical_revision_))));
labels.push_back(Wasm::Common::CreateKeyVal(fbb, fbb.CreateString("app"),
fbb.CreateString(toStdStringView(obj.app_name_))));
labels.push_back(Wasm::Common::CreateKeyVal(fbb, fbb.CreateString("version"),
fbb.CreateString(toStdStringView(obj.app_version_))));
auto labels_offset = fbb.CreateVectorOfSortedTables(&labels);
Wasm::Common::FlatNodeBuilder node(fbb);
node.add_name(name);
node.add_cluster_id(cluster);
node.add_namespace_(namespace_);
node.add_workload_name(workload_name);
node.add_owner(owner);
node.add_labels(labels_offset);
auto data = node.Finish();
fbb.Finish(data);
auto fb = fbb.Release();
return std::string(reinterpret_cast<const char*>(fb.data()), fb.size());
}
WorkloadMetadataObject convertFlatNodeToWorkloadMetadata(const Wasm::Common::FlatNode& node) {
const absl::string_view instance = toAbslStringView(node.name());
const absl::string_view cluster = toAbslStringView(node.cluster_id());
const absl::string_view workload = toAbslStringView(node.workload_name());
const absl::string_view namespace_name = toAbslStringView(node.namespace_());
const auto* labels = node.labels();
absl::string_view canonical_name;
absl::string_view canonical_revision;
absl::string_view app_name;
absl::string_view app_version;
if (labels) {
const auto* name_iter = labels->LookupByKey("service.istio.io/canonical-name");
const auto* name = name_iter ? name_iter->value() : nullptr;
canonical_name = toAbslStringView(name);
const auto* revision_iter = labels->LookupByKey("service.istio.io/canonical-revision");
const auto* revision = revision_iter ? revision_iter->value() : nullptr;
canonical_revision = toAbslStringView(revision);
const auto* app_iter = labels->LookupByKey("app");
const auto* app = app_iter ? app_iter->value() : nullptr;
app_name = toAbslStringView(app);
const auto* version_iter = labels->LookupByKey("version");
const auto* version = version_iter ? version_iter->value() : nullptr;
app_version = toAbslStringView(version);
}
WorkloadType workload_type = WorkloadType::Pod;
// Strip "s/workload_name" and check for workload type.
absl::string_view owner = toAbslStringView(node.owner());
if (owner.size() > workload.size() + 2) {
owner.remove_suffix(workload.size() + 2);
size_t last = owner.rfind('/');
if (last != absl::string_view::npos) {
const auto it = ALL_WORKLOAD_TOKENS.find(owner.substr(last + 1));
if (it != ALL_WORKLOAD_TOKENS.end()) {
switch (it->second) {
case WorkloadType::Deployment:
workload_type = WorkloadType::Deployment;
break;
case WorkloadType::CronJob:
workload_type = WorkloadType::CronJob;
break;
case WorkloadType::Job:
workload_type = WorkloadType::Job;
break;
case WorkloadType::Pod:
workload_type = WorkloadType::Pod;
break;
default:
break;
}
}
}
}
return WorkloadMetadataObject(instance, cluster, namespace_name, workload, canonical_name,
canonical_revision, app_name, app_version, workload_type);
}
absl::optional<WorkloadMetadataObject>
convertEndpointMetadata(const std::string& endpoint_encoding) {
std::vector<absl::string_view> parts = absl::StrSplit(endpoint_encoding, ';');
if (parts.size() < 5) {
return {};
}
// TODO: we cannot determine workload type from the encoding.
return absl::make_optional<WorkloadMetadataObject>("", parts[4], parts[1], parts[0], parts[2],
parts[3], "", "", WorkloadType::Pod);
return std::make_unique<WorkloadMetadataObject>(instance, cluster, namespace_name, workload,
canonical_name, canonical_revision, app_name,
app_version, workload_type, "");
}
} // namespace Common

View File

@ -14,17 +14,34 @@
#pragma once
#include "absl/strings/str_split.h"
#include "absl/types/optional.h"
#include "envoy/common/hashable.h"
#include "envoy/ssl/connection.h"
#include "envoy/stream_info/filter_state.h"
#include "extensions/common/node_info_generated.h"
#include "source/common/protobuf/protobuf.h"
#include "absl/types/optional.h"
#include "google/protobuf/struct.pb.h"
namespace Istio {
namespace Common {
// Filter state key to store the peer metadata under.
constexpr absl::string_view DownstreamPeer = "downstream_peer";
constexpr absl::string_view UpstreamPeer = "upstream_peer";
// Special filter state key to indicate the filter is done looking for peer metadata.
// This is used by network metadata exchange on failure.
constexpr absl::string_view NoPeer = "peer_not_found";
// Special labels used in the peer metadata.
constexpr absl::string_view CanonicalNameLabel = "service.istio.io/canonical-name";
constexpr absl::string_view CanonicalRevisionLabel = "service.istio.io/canonical-revision";
constexpr absl::string_view AppNameLabel = "app";
constexpr absl::string_view AppVersionLabel = "version";
enum class WorkloadType {
Unknown,
Pod,
Deployment,
Job,
@ -32,6 +49,7 @@ enum class WorkloadType {
};
constexpr absl::string_view OwnerPrefix = "kubernetes://apis/apps/v1/namespaces/";
constexpr absl::string_view PodSuffix = "pod";
constexpr absl::string_view DeploymentSuffix = "deployment";
constexpr absl::string_view JobSuffix = "job";
@ -42,48 +60,56 @@ enum class BaggageToken {
ClusterName,
ServiceName,
ServiceVersion,
PodName,
DeploymentName,
JobName,
CronJobName,
AppName,
AppVersion,
WorkloadName,
WorkloadType,
InstanceName,
};
constexpr absl::string_view NamespaceNameToken = "k8s.namespace.name";
constexpr absl::string_view ClusterNameToken = "k8s.cluster.name";
constexpr absl::string_view ServiceNameToken = "service.name";
constexpr absl::string_view ServiceVersionToken = "service.version";
constexpr absl::string_view PodNameToken = "k8s.pod.name";
constexpr absl::string_view DeploymentNameToken = "k8s.deployment.name";
constexpr absl::string_view JobNameToken = "k8s.job.name";
constexpr absl::string_view CronJobNameToken = "k8s.cronjob.name";
constexpr absl::string_view AppNameToken = "app.name";
constexpr absl::string_view AppVersionToken = "app.version";
constexpr absl::string_view NamespaceNameToken = "namespace";
constexpr absl::string_view ClusterNameToken = "cluster";
constexpr absl::string_view ServiceNameToken = "service";
constexpr absl::string_view ServiceVersionToken = "revision";
constexpr absl::string_view AppNameToken = "app";
constexpr absl::string_view AppVersionToken = "version";
constexpr absl::string_view WorkloadNameToken = "workload";
constexpr absl::string_view WorkloadTypeToken = "type";
constexpr absl::string_view InstanceNameToken = "name";
constexpr absl::string_view LabelsToken = "labels";
constexpr absl::string_view IdentityToken = "identity";
constexpr absl::string_view kSourceMetadataObjectKey = "ambient.source.workloadMetadata";
constexpr absl::string_view kSourceMetadataBaggageKey = "ambient.source.workloadMetadataBaggage";
constexpr absl::string_view kDestinationMetadataObjectKey = "ambient.destination.workloadMetadata";
constexpr absl::string_view InstanceMetadataField = "NAME";
constexpr absl::string_view NamespaceMetadataField = "NAMESPACE";
constexpr absl::string_view ClusterMetadataField = "CLUSTER_ID";
constexpr absl::string_view OwnerMetadataField = "OWNER";
constexpr absl::string_view WorkloadMetadataField = "WORKLOAD_NAME";
constexpr absl::string_view LabelsMetadataField = "LABELS";
struct WorkloadMetadataObject : public Envoy::StreamInfo::FilterState::Object,
public Envoy::Hashable {
class WorkloadMetadataObject : public Envoy::StreamInfo::FilterState::Object,
public Envoy::Hashable {
public:
explicit WorkloadMetadataObject(absl::string_view instance_name, absl::string_view cluster_name,
absl::string_view namespace_name, absl::string_view workload_name,
absl::string_view canonical_name,
absl::string_view canonical_revision, absl::string_view app_name,
absl::string_view app_version, const WorkloadType workload_type)
absl::string_view app_version, WorkloadType workload_type,
absl::string_view identity)
: instance_name_(instance_name), cluster_name_(cluster_name), namespace_name_(namespace_name),
workload_name_(workload_name), canonical_name_(canonical_name),
canonical_revision_(canonical_revision), app_name_(app_name), app_version_(app_version),
workload_type_(workload_type) {}
static WorkloadMetadataObject fromBaggage(absl::string_view baggage_header_value);
std::string baggage() const;
workload_type_(workload_type), identity_(identity) {}
absl::optional<uint64_t> hash() const override;
absl::optional<std::string> serializeAsString() const override { return baggage(); }
Envoy::ProtobufTypes::MessagePtr serializeAsProto() const override;
std::vector<std::pair<absl::string_view, absl::string_view>> serializeAsPairs() const;
absl::optional<std::string> serializeAsString() const override;
absl::optional<std::string> owner() const;
bool hasFieldSupport() const override { return true; }
using Envoy::StreamInfo::FilterState::Object::FieldType;
FieldType getField(absl::string_view) const override;
void setLabels(std::vector<std::pair<std::string, std::string>> labels) { labels_ = labels; }
std::vector<std::pair<std::string, std::string>> getLabels() const { return labels_; }
const std::string instance_name_;
const std::string cluster_name_;
@ -94,13 +120,26 @@ struct WorkloadMetadataObject : public Envoy::StreamInfo::FilterState::Object,
const std::string app_name_;
const std::string app_version_;
const WorkloadType workload_type_;
const std::string identity_;
std::vector<std::pair<std::string, std::string>> labels_;
};
// Convert metadata object to flatbuffer.
std::string convertWorkloadMetadataToFlatNode(const WorkloadMetadataObject& obj);
// Parse string workload type.
WorkloadType fromSuffix(absl::string_view suffix);
// Convert flatbuffer to metadata object.
WorkloadMetadataObject convertFlatNodeToWorkloadMetadata(const Wasm::Common::FlatNode& node);
// Parse owner field from kubernetes to detect the workload type.
WorkloadType parseOwner(absl::string_view owner, absl::string_view workload);
// Convert a metadata object to a struct.
google::protobuf::Struct convertWorkloadMetadataToStruct(const WorkloadMetadataObject& obj);
// Convert struct to a metadata object.
std::unique_ptr<WorkloadMetadataObject>
convertStructToWorkloadMetadata(const google::protobuf::Struct& metadata);
std::unique_ptr<WorkloadMetadataObject>
convertStructToWorkloadMetadata(const google::protobuf::Struct& metadata,
const absl::flat_hash_set<std::string>& additional_labels);
// Convert endpoint metadata string to a metadata object.
// Telemetry metadata is compressed into a semicolon separated string:
@ -110,5 +149,10 @@ WorkloadMetadataObject convertFlatNodeToWorkloadMetadata(const Wasm::Common::Fla
absl::optional<WorkloadMetadataObject>
convertEndpointMetadata(const std::string& endpoint_encoding);
std::string serializeToStringDeterministic(const google::protobuf::Struct& metadata);
// Convert from baggage encoding.
std::unique_ptr<WorkloadMetadataObject> convertBaggageToWorkloadMetadata(absl::string_view data);
} // namespace Common
} // namespace Istio

View File

@ -14,154 +14,156 @@
#include "extensions/common/metadata_object.h"
#include "envoy/registry/registry.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace Istio {
namespace Common {
using Envoy::Protobuf::util::MessageDifferencer;
using ::testing::NiceMock;
TEST(WorkloadMetadataObjectTest, Hash) {
WorkloadMetadataObject obj1("foo-pod-12345", "my-cluster", "default", "foo", "foo", "latest",
"foo-app", "v1", WorkloadType::Deployment);
WorkloadMetadataObject obj2("foo-pod-12345", "my-cluster", "default", "bar", "baz", "first",
"foo-app", "v1", WorkloadType::Job);
EXPECT_EQ(obj1.hash().value(), obj2.hash().value());
}
TEST(WorkloadMetadataObjectTest, Baggage) {
WorkloadMetadataObject deploy("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
"v1alpha3", "foo-app", "v1", WorkloadType::Deployment);
"v1alpha3", "", "", WorkloadType::Deployment, "");
WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
"v1alpha3", "foo-app", "v1", WorkloadType::Pod);
"v1alpha3", "", "", WorkloadType::Pod, "");
WorkloadMetadataObject cronjob("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
"v1alpha3", "foo-app", "v1", WorkloadType::CronJob);
"v1alpha3", "foo-app", "v1", WorkloadType::CronJob, "");
WorkloadMetadataObject job("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
"v1alpha3", "foo-app", "v1", WorkloadType::Job);
"v1alpha3", "", "", WorkloadType::Job, "");
EXPECT_EQ(deploy.baggage(), absl::StrCat("k8s.deployment.name=foo,k8s.cluster.name=my-cluster,",
"k8s.namespace.name=default,",
"service.name=foo-service,service.version=v1alpha3,",
"app.name=foo-app,app.version=v1"));
EXPECT_EQ(deploy.serializeAsString(),
absl::StrCat("type=deployment,workload=foo,name=pod-foo-1234,cluster=my-cluster,",
"namespace=default,service=foo-service,revision=v1alpha3"));
EXPECT_EQ(pod.baggage(), absl::StrCat("k8s.pod.name=foo,k8s.cluster.name=my-cluster,",
"k8s.namespace.name=default,",
"service.name=foo-service,service.version=v1alpha3,",
"app.name=foo-app,app.version=v1"));
EXPECT_EQ(pod.serializeAsString(),
absl::StrCat("type=pod,workload=foo,name=pod-foo-1234,cluster=my-cluster,",
"namespace=default,service=foo-service,revision=v1alpha3"));
EXPECT_EQ(cronjob.baggage(), absl::StrCat("k8s.cronjob.name=foo,k8s.cluster.name=my-cluster,",
"k8s.namespace.name=default,"
"service.name=foo-service,service.version=v1alpha3,",
"app.name=foo-app,app.version=v1"));
EXPECT_EQ(cronjob.serializeAsString(),
absl::StrCat("type=cronjob,workload=foo,name=pod-foo-1234,cluster=my-cluster,",
"namespace=default,service=foo-service,revision=v1alpha3,",
"app=foo-app,version=v1"));
EXPECT_EQ(job.baggage(), absl::StrCat("k8s.job.name=foo,k8s.cluster.name=my-cluster,",
"k8s.namespace.name=default,",
"service.name=foo-service,service.version=v1alpha3,",
"app.name=foo-app,app.version=v1"));
EXPECT_EQ(job.serializeAsString(),
absl::StrCat("type=job,workload=foo,name=pod-foo-1234,cluster=my-cluster,",
"namespace=default,service=foo-service,revision=v1alpha3"));
}
void checkFlatNodeConversion(const WorkloadMetadataObject& obj) {
auto buffer = convertWorkloadMetadataToFlatNode(obj);
const auto& node = *flatbuffers::GetRoot<Wasm::Common::FlatNode>(buffer.data());
auto obj2 = convertFlatNodeToWorkloadMetadata(node);
EXPECT_EQ(obj2.baggage(), obj.baggage());
void checkStructConversion(const Envoy::StreamInfo::FilterState::Object& data) {
const auto& obj = dynamic_cast<const WorkloadMetadataObject&>(data);
auto pb = convertWorkloadMetadataToStruct(obj);
auto obj2 = convertStructToWorkloadMetadata(pb);
EXPECT_EQ(obj2->serializeAsString(), obj.serializeAsString());
MessageDifferencer::Equals(*(obj2->serializeAsProto()), *(obj.serializeAsProto()));
EXPECT_EQ(obj2->hash(), obj.hash());
}
TEST(WorkloadMetadataObjectTest, FromBaggage) {
TEST(WorkloadMetadataObjectTest, ConversionWithLabels) {
WorkloadMetadataObject deploy("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
"v1alpha3", "", "", WorkloadType::Deployment, "");
deploy.setLabels({{"label1", "value1"}, {"label2", "value2"}});
auto pb = convertWorkloadMetadataToStruct(deploy);
auto obj1 = convertStructToWorkloadMetadata(pb, {"label1", "label2"});
EXPECT_EQ(obj1->getLabels().size(), 2);
auto obj2 = convertStructToWorkloadMetadata(pb, {"label1"});
EXPECT_EQ(obj2->getLabels().size(), 1);
absl::flat_hash_set<std::string> empty;
auto obj3 = convertStructToWorkloadMetadata(pb, empty);
EXPECT_EQ(obj3->getLabels().size(), 0);
}
TEST(WorkloadMetadataObjectTest, Conversion) {
{
auto obj = WorkloadMetadataObject::fromBaggage(
absl::StrCat("k8s.deployment.name=foo,k8s.cluster.name=my-cluster,k8s."
"namespace.name=default,",
"service.name=foo-service,", "service.version=v1alpha3"));
EXPECT_EQ(obj.canonical_name_, "foo-service");
EXPECT_EQ(obj.canonical_revision_, "v1alpha3");
EXPECT_EQ(obj.workload_type_, WorkloadType::Deployment);
EXPECT_EQ(obj.workload_name_, "foo");
EXPECT_EQ(obj.namespace_name_, "default");
EXPECT_EQ(obj.cluster_name_, "my-cluster");
checkFlatNodeConversion(obj);
const auto r = convertBaggageToWorkloadMetadata(
"type=deployment,workload=foo,cluster=my-cluster,"
"namespace=default,service=foo-service,revision=v1alpha3,app=foo-app,version=latest");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("service")), "foo-service");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("revision")), "v1alpha3");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("type")), DeploymentSuffix);
EXPECT_EQ(absl::get<absl::string_view>(r->getField("workload")), "foo");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("name")), "");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "default");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("cluster")), "my-cluster");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("app")), "foo-app");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("version")), "latest");
checkStructConversion(*r);
}
{
auto obj = WorkloadMetadataObject::fromBaggage(
absl::StrCat("k8s.pod.name=foo-pod-435,k8s.cluster.name=my-cluster,k8s."
"namespace.name=test,"
"service.name=foo-service,service.version=v1beta2"));
EXPECT_EQ(obj.canonical_name_, "foo-service");
EXPECT_EQ(obj.canonical_revision_, "v1beta2");
EXPECT_EQ(obj.workload_type_, WorkloadType::Pod);
EXPECT_EQ(obj.workload_name_, "foo-pod-435");
EXPECT_EQ(obj.instance_name_, "foo-pod-435");
EXPECT_EQ(obj.namespace_name_, "test");
EXPECT_EQ(obj.cluster_name_, "my-cluster");
checkFlatNodeConversion(obj);
const auto r =
convertBaggageToWorkloadMetadata("type=pod,name=foo-pod-435,cluster=my-cluster,namespace="
"test,service=foo-service,revision=v1beta2");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("service")), "foo-service");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("revision")), "v1beta2");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("type")), PodSuffix);
EXPECT_EQ(absl::get<absl::string_view>(r->getField("workload")), "");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("name")), "foo-pod-435");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "test");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("cluster")), "my-cluster");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("app")), "");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("version")), "");
checkStructConversion(*r);
}
{
auto obj = WorkloadMetadataObject::fromBaggage(
absl::StrCat("k8s.job.name=foo-job-435,k8s.cluster.name=my-cluster,k8s."
"namespace.name=test,",
"service.name=foo-service,", "service.version=v1beta4"));
EXPECT_EQ(obj.canonical_name_, "foo-service");
EXPECT_EQ(obj.canonical_revision_, "v1beta4");
EXPECT_EQ(obj.workload_type_, WorkloadType::Job);
EXPECT_EQ(obj.workload_name_, "foo-job-435");
EXPECT_EQ(obj.instance_name_, "foo-job-435");
EXPECT_EQ(obj.namespace_name_, "test");
EXPECT_EQ(obj.cluster_name_, "my-cluster");
checkFlatNodeConversion(obj);
const auto r =
convertBaggageToWorkloadMetadata("type=job,name=foo-job-435,cluster=my-cluster,namespace="
"test,service=foo-service,revision=v1beta4");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("service")), "foo-service");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("revision")), "v1beta4");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("type")), JobSuffix);
EXPECT_EQ(absl::get<absl::string_view>(r->getField("workload")), "");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("name")), "foo-job-435");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "test");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("cluster")), "my-cluster");
checkStructConversion(*r);
}
{
auto obj = WorkloadMetadataObject::fromBaggage(
absl::StrCat("k8s.cronjob.name=foo-cronjob,k8s.cluster.name=my-cluster,"
"k8s.namespace.name=test,",
"service.name=foo-service,", "service.version=v1beta4"));
EXPECT_EQ(obj.canonical_name_, "foo-service");
EXPECT_EQ(obj.canonical_revision_, "v1beta4");
EXPECT_EQ(obj.workload_type_, WorkloadType::CronJob);
EXPECT_EQ(obj.workload_name_, "foo-cronjob");
EXPECT_EQ(obj.namespace_name_, "test");
EXPECT_EQ(obj.cluster_name_, "my-cluster");
EXPECT_EQ(obj.app_name_, "");
EXPECT_EQ(obj.app_version_, "");
checkFlatNodeConversion(obj);
const auto r =
convertBaggageToWorkloadMetadata("type=cronjob,workload=foo-cronjob,cluster=my-cluster,"
"namespace=test,service=foo-service,revision=v1beta4");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("service")), "foo-service");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("revision")), "v1beta4");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("type")), CronJobSuffix);
EXPECT_EQ(absl::get<absl::string_view>(r->getField("workload")), "foo-cronjob");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("name")), "");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "test");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("cluster")), "my-cluster");
checkStructConversion(*r);
}
{
auto obj = WorkloadMetadataObject::fromBaggage(absl::StrCat(
"k8s.deployment.name=foo,k8s.namespace.name=default,", "service.name=foo-service,",
"service.version=v1alpha3,app.name=foo-app,app.version=v1"));
const auto r = convertBaggageToWorkloadMetadata(
"type=deployment,workload=foo,namespace=default,service=foo-service,revision=v1alpha3");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("service")), "foo-service");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("revision")), "v1alpha3");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("type")), DeploymentSuffix);
EXPECT_EQ(absl::get<absl::string_view>(r->getField("workload")), "foo");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "default");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("cluster")), "");
checkStructConversion(*r);
}
EXPECT_EQ(obj.canonical_name_, "foo-service");
EXPECT_EQ(obj.canonical_revision_, "v1alpha3");
EXPECT_EQ(obj.workload_type_, WorkloadType::Deployment);
EXPECT_EQ(obj.workload_name_, "foo");
EXPECT_EQ(obj.namespace_name_, "default");
EXPECT_EQ(obj.cluster_name_, "");
EXPECT_EQ(obj.app_name_, "foo-app");
EXPECT_EQ(obj.app_version_, "v1");
checkFlatNodeConversion(obj);
{
const auto r = convertBaggageToWorkloadMetadata("namespace=default");
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "default");
checkStructConversion(*r);
}
}
TEST(WorkloadMetadataObjectTest, ConvertFromFlatNode) {
flatbuffers::FlatBufferBuilder fbb;
Wasm::Common::FlatNodeBuilder builder(fbb);
auto data = builder.Finish();
fbb.Finish(data);
auto buffer = fbb.Release();
const auto& node = *flatbuffers::GetRoot<Wasm::Common::FlatNode>(buffer.data());
auto obj = convertFlatNodeToWorkloadMetadata(node);
EXPECT_EQ(obj.baggage(), "k8s.pod.name=");
TEST(WorkloadMetadataObjectTest, ConvertFromEmpty) {
google::protobuf::Struct node;
auto obj = convertStructToWorkloadMetadata(node);
EXPECT_EQ(obj->serializeAsString(), "");
checkStructConversion(*obj);
}
TEST(WorkloadMetadataObjectTest, ConvertFromEndpointMetadata) {
@ -171,8 +173,8 @@ TEST(WorkloadMetadataObjectTest, ConvertFromEndpointMetadata) {
EXPECT_EQ(absl::nullopt, convertEndpointMetadata("a;b;c;d"));
auto obj = convertEndpointMetadata("foo-pod;default;foo-service;v1;my-cluster");
ASSERT_TRUE(obj.has_value());
EXPECT_EQ(obj->baggage(), "k8s.pod.name=foo-pod,k8s.cluster.name=my-cluster,k8s.namespace."
"name=default,service.name=foo-service,service.version=v1");
EXPECT_EQ(obj->serializeAsString(), "workload=foo-pod,cluster=my-cluster,"
"namespace=default,service=foo-service,revision=v1");
}
} // namespace Common

View File

@ -1,50 +0,0 @@
/* Copyright 2020 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Wasm.Common;
table KeyVal {
key:string (key);
value:string;
}
// NodeInfo represents the information extracted from proxy node metadata.
table FlatNode {
// Name of the node. e.g. in k8s, name is the pod name.
name:string;
// Namespace that the node runs in.
namespace:string;
// K8s or vm workload attributes.
labels:[KeyVal];
owner:string;
workload_name:string;
// Platform metadata uses prefixed keys
// GCP uses gcp_* keys
platform_metadata:[KeyVal];
// Version identifier for the proxy.
istio_version:string;
// Unique identifier for the mesh. Taken from global mesh id parameter (or
// the configured trust domain when not specified).
mesh_id:string;
// List of short names for application containers that are using this proxy.
// This is only used for kubernetes, and is populated by the sidecar injector.
app_containers:[string];
// Identifier for the cluster to which this workload belongs (for k8s workloads).
cluster_id:string;
// instance ip addresses
instance_ips:[string];
}
root_type FlatNode;

View File

@ -1,191 +0,0 @@
/* Copyright 2020 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/common/proto_util.h"
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "extensions/common/util.h"
// WASM_PROLOG
#ifndef NULL_PLUGIN
#include "proxy_wasm_intrinsics.h"
#else // NULL_PLUGIN
#include "include/proxy-wasm/null_plugin.h"
#endif // NULL_PLUGIN
// END WASM_PROLOG
namespace Wasm {
namespace Common {
flatbuffers::DetachedBuffer
extractNodeFlatBufferFromStruct(const google::protobuf::Struct& metadata) {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::Offset<flatbuffers::String> name, namespace_, owner, workload_name, istio_version,
mesh_id, cluster_id;
std::vector<flatbuffers::Offset<KeyVal>> labels, platform_metadata;
std::vector<flatbuffers::Offset<flatbuffers::String>> app_containers;
std::vector<flatbuffers::Offset<flatbuffers::String>> ip_addrs;
for (const auto& it : metadata.fields()) {
if (it.first == "NAME") {
name = fbb.CreateString(it.second.string_value());
} else if (it.first == "NAMESPACE") {
namespace_ = fbb.CreateString(it.second.string_value());
} else if (it.first == "OWNER") {
owner = fbb.CreateString(it.second.string_value());
} else if (it.first == "WORKLOAD_NAME") {
workload_name = fbb.CreateString(it.second.string_value());
} else if (it.first == "ISTIO_VERSION") {
istio_version = fbb.CreateString(it.second.string_value());
} else if (it.first == "MESH_ID") {
mesh_id = fbb.CreateString(it.second.string_value());
} else if (it.first == "CLUSTER_ID") {
cluster_id = fbb.CreateString(it.second.string_value());
} else if (it.first == "LABELS") {
for (const auto& labels_it : it.second.struct_value().fields()) {
labels.push_back(CreateKeyVal(fbb, fbb.CreateString(labels_it.first),
fbb.CreateString(labels_it.second.string_value())));
}
} else if (it.first == "PLATFORM_METADATA") {
for (const auto& platform_it : it.second.struct_value().fields()) {
platform_metadata.push_back(
CreateKeyVal(fbb, fbb.CreateString(platform_it.first),
fbb.CreateString(platform_it.second.string_value())));
}
} else if (it.first == "APP_CONTAINERS") {
std::vector<absl::string_view> containers = absl::StrSplit(it.second.string_value(), ',');
for (const auto& container : containers) {
app_containers.push_back(fbb.CreateString(toStdStringView(container)));
}
} else if (it.first == "INSTANCE_IPS") {
std::vector<absl::string_view> ip_addresses = absl::StrSplit(it.second.string_value(), ',');
for (const auto& ip : ip_addresses) {
ip_addrs.push_back(fbb.CreateString(toStdStringView(ip)));
}
}
}
// finish pre-order construction
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyVal>>> labels_offset,
platform_metadata_offset;
if (labels.size() > 0) {
labels_offset = fbb.CreateVectorOfSortedTables(&labels);
}
if (platform_metadata.size() > 0) {
platform_metadata_offset = fbb.CreateVectorOfSortedTables(&platform_metadata);
}
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>>
app_containers_offset;
if (app_containers.size() > 0) {
app_containers_offset = fbb.CreateVector(app_containers);
}
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>>
ip_addrs_offset;
if (ip_addrs.size() > 0) {
ip_addrs_offset = fbb.CreateVector(ip_addrs);
}
FlatNodeBuilder node(fbb);
node.add_name(name);
node.add_namespace_(namespace_);
node.add_owner(owner);
node.add_workload_name(workload_name);
node.add_istio_version(istio_version);
node.add_mesh_id(mesh_id);
node.add_cluster_id(cluster_id);
node.add_labels(labels_offset);
node.add_platform_metadata(platform_metadata_offset);
if (app_containers.size() > 0) {
node.add_app_containers(app_containers_offset);
}
if (ip_addrs.size() > 0) {
node.add_instance_ips(ip_addrs_offset);
}
auto data = node.Finish();
fbb.Finish(data);
return fbb.Release();
}
void extractStructFromNodeFlatBuffer(const FlatNode& node, google::protobuf::Struct* metadata) {
if (node.name()) {
(*metadata->mutable_fields())["NAME"].set_string_value(node.name()->str());
}
if (node.namespace_()) {
(*metadata->mutable_fields())["NAMESPACE"].set_string_value(node.namespace_()->str());
}
if (node.owner()) {
(*metadata->mutable_fields())["OWNER"].set_string_value(node.owner()->str());
}
if (node.workload_name()) {
(*metadata->mutable_fields())["WORKLOAD_NAME"].set_string_value(node.workload_name()->str());
}
if (node.istio_version()) {
(*metadata->mutable_fields())["ISTIO_VERSION"].set_string_value(node.istio_version()->str());
}
if (node.mesh_id()) {
(*metadata->mutable_fields())["MESH_ID"].set_string_value(node.mesh_id()->str());
}
if (node.cluster_id()) {
(*metadata->mutable_fields())["CLUSTER_ID"].set_string_value(node.cluster_id()->str());
}
if (node.labels()) {
auto* map = (*metadata->mutable_fields())["LABELS"].mutable_struct_value();
for (const auto keyval : *node.labels()) {
(*map->mutable_fields())[flatbuffers::GetString(keyval->key())].set_string_value(
flatbuffers::GetString(keyval->value()));
}
}
if (node.platform_metadata()) {
auto* map = (*metadata->mutable_fields())["PLATFORM_METADATA"].mutable_struct_value();
for (const auto keyval : *node.platform_metadata()) {
(*map->mutable_fields())[flatbuffers::GetString(keyval->key())].set_string_value(
flatbuffers::GetString(keyval->value()));
}
}
if (node.app_containers()) {
std::vector<std::string> containers;
for (const auto container : *node.app_containers()) {
containers.push_back(flatbuffers::GetString(container));
}
(*metadata->mutable_fields())["APP_CONTAINERS"].set_string_value(
absl::StrJoin(containers, ","));
}
if (node.instance_ips()) {
std::vector<std::string> ip_addrs;
for (const auto ip : *node.instance_ips()) {
ip_addrs.push_back(flatbuffers::GetString(ip));
}
(*metadata->mutable_fields())["INSTANCE_IPS"].set_string_value(absl::StrJoin(ip_addrs, ","));
}
}
bool serializeToStringDeterministic(const google::protobuf::Message& metadata,
std::string* metadata_bytes) {
google::protobuf::io::StringOutputStream md(metadata_bytes);
google::protobuf::io::CodedOutputStream mcs(&md);
mcs.SetSerializationDeterministic(true);
if (!metadata.SerializeToCodedStream(&mcs)) {
return false;
}
return true;
}
} // namespace Common
} // namespace Wasm

View File

@ -1,40 +0,0 @@
/* Copyright 2020 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "extensions/common/node_info_generated.h"
#include "flatbuffers/flatbuffers.h"
#include "google/protobuf/struct.pb.h"
/**
* Utilities that require protobuf import.
*/
namespace Wasm {
namespace Common {
// Extract node info into a flatbuffer from a struct.
flatbuffers::DetachedBuffer
extractNodeFlatBufferFromStruct(const google::protobuf::Struct& metadata);
// Extract struct from a flatbuffer. This is an inverse of the above function.
void extractStructFromNodeFlatBuffer(const FlatNode& node, google::protobuf::Struct* metadata);
// Serialize deterministically a protobuf to a string.
bool serializeToStringDeterministic(const google::protobuf::Message& metadata,
std::string* metadata_bytes);
} // namespace Common
} // namespace Wasm

View File

@ -1,220 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "benchmark/benchmark.h"
#include "extensions/common/metadata_object.h"
#include "extensions/common/node_info_generated.h"
#include "extensions/common/proto_util.h"
#include "extensions/common/util.h"
#include "google/protobuf/util/json_util.h"
#include "source/common/common/base64.h"
#include "source/common/stream_info/filter_state_impl.h"
#include "source/extensions/filters/common/expr/cel_state.h"
#include "test/test_common/status_utility.h"
// WASM_PROLOG
#ifdef NULL_PLUGIN
namespace Wasm {
#endif // NULL_PLUGIN
// END WASM_PROLOG
namespace Common {
using namespace google::protobuf::util;
constexpr std::string_view node_metadata_json = R"###(
{
"NAME":"test_pod",
"NAMESPACE":"test_namespace",
"LABELS": {
"app": "productpage",
"version": "v1",
"pod-template-hash": "84975bc778"
},
"OWNER":"test_owner",
"WORKLOAD_NAME":"test_workload",
"PLATFORM_METADATA":{
"gcp_project":"test_project",
"gcp_cluster_location":"test_location",
"gcp_cluster_name":"test_cluster"
},
"ISTIO_VERSION":"istio-1.4",
"MESH_ID":"test-mesh"
}
)###";
constexpr std::string_view metadata_id_key = "envoy.wasm.metadata_exchange.downstream_id";
constexpr std::string_view metadata_key = "envoy.wasm.metadata_exchange.downstream";
constexpr std::string_view node_id = "test_pod.test_namespace";
static void setData(Envoy::StreamInfo::FilterStateImpl& filter_state, std::string_view key,
std::string_view value) {
Envoy::Extensions::Filters::Common::Expr::CelStatePrototype prototype;
auto state_ptr = std::make_unique<Envoy::Extensions::Filters::Common::Expr::CelState>(prototype);
state_ptr->setValue(toAbslStringView(value));
filter_state.setData(toAbslStringView(key), std::move(state_ptr),
Envoy::StreamInfo::FilterState::StateType::Mutable);
}
static const std::string& getData(Envoy::StreamInfo::FilterStateImpl& filter_state,
std::string_view key) {
return filter_state
.getDataReadOnly<Envoy::Extensions::Filters::Common::Expr::CelState>(toAbslStringView(key))
->value();
}
static void BM_ReadFlatBuffer(benchmark::State& state) {
google::protobuf::Struct metadata_struct;
JsonParseOptions json_parse_options;
ASSERT_OK(
JsonStringToMessage(std::string(node_metadata_json), &metadata_struct, json_parse_options));
auto out = extractNodeFlatBufferFromStruct(metadata_struct);
Envoy::StreamInfo::FilterStateImpl filter_state{
Envoy::StreamInfo::FilterState::LifeSpan::TopSpan};
setData(filter_state, metadata_key,
std::string_view(reinterpret_cast<const char*>(out.data()), out.size()));
size_t size = 0;
for (auto _ : state) {
auto buf = getData(filter_state, metadata_key);
auto peer = flatbuffers::GetRoot<FlatNode>(buf.data());
size += peer->workload_name()->size() + peer->namespace_()->size() +
peer->labels()->LookupByKey("app")->value()->size() +
peer->labels()->LookupByKey("version")->value()->size();
benchmark::DoNotOptimize(size);
}
}
BENCHMARK(BM_ReadFlatBuffer);
static void BM_WriteRawBytes(benchmark::State& state) {
google::protobuf::Struct metadata_struct;
JsonParseOptions json_parse_options;
ASSERT_OK(
JsonStringToMessage(std::string(node_metadata_json), &metadata_struct, json_parse_options));
auto bytes = metadata_struct.SerializeAsString();
Envoy::StreamInfo::FilterStateImpl filter_state{
Envoy::StreamInfo::FilterState::LifeSpan::TopSpan};
for (auto _ : state) {
setData(filter_state, metadata_id_key, node_id);
setData(filter_state, metadata_key, bytes);
}
}
BENCHMARK(BM_WriteRawBytes);
static void BM_WriteFlatBufferWithCache(benchmark::State& state) {
google::protobuf::Struct metadata_struct;
JsonParseOptions json_parse_options;
ASSERT_OK(
JsonStringToMessage(std::string(node_metadata_json), &metadata_struct, json_parse_options));
auto bytes = metadata_struct.SerializeAsString();
Envoy::StreamInfo::FilterStateImpl filter_state{
Envoy::StreamInfo::FilterState::LifeSpan::TopSpan};
std::unordered_map<std::string, std::string> cache;
for (auto _ : state) {
// lookup cache by key
auto nodeinfo_it = cache.find(std::string(node_id));
std::string node_info;
if (nodeinfo_it == cache.end()) {
google::protobuf::Struct test_struct;
test_struct.ParseFromArray(bytes.data(), bytes.size());
benchmark::DoNotOptimize(test_struct);
auto out = extractNodeFlatBufferFromStruct(test_struct);
node_info =
cache.emplace(node_id, std::string(reinterpret_cast<const char*>(out.data()), out.size()))
.first->second;
} else {
node_info = nodeinfo_it->second;
}
setData(filter_state, metadata_id_key, node_id);
setData(filter_state, metadata_key, node_info);
}
}
BENCHMARK(BM_WriteFlatBufferWithCache);
constexpr std::string_view node_flatbuffer_json = R"###(
{
"NAME":"test_pod",
"NAMESPACE":"default",
"CLUSTER_ID": "client-cluster",
"LABELS": {
"app": "productpage",
"version": "v1",
"service.istio.io/canonical-name": "productpage-v1",
"service.istio.io/canonical-revision": "version-1"
},
"OWNER": "kubernetes://apis/apps/v1/namespaces/default/deployments/productpage-v1",
"WORKLOAD_NAME":"productpage-v1"
}
)###";
// Measure decoding performance of x-envoy-peer-metadata.
static void BM_DecodeFlatBuffer(benchmark::State& state) {
// Construct a header from sample value.
google::protobuf::Struct metadata_struct;
JsonParseOptions json_parse_options;
ASSERT_OK(
JsonStringToMessage(std::string(node_flatbuffer_json), &metadata_struct, json_parse_options));
std::string metadata_bytes;
::Wasm::Common::serializeToStringDeterministic(metadata_struct, &metadata_bytes);
const std::string header_value =
Envoy::Base64::encode(metadata_bytes.data(), metadata_bytes.size());
size_t size = 0;
for (auto _ : state) {
auto bytes = Envoy::Base64::decodeWithoutPadding(header_value);
google::protobuf::Struct metadata;
metadata.ParseFromString(bytes);
auto fb = ::Wasm::Common::extractNodeFlatBufferFromStruct(metadata);
size += fb.size();
benchmark::DoNotOptimize(size);
}
}
BENCHMARK(BM_DecodeFlatBuffer);
// Measure decoding performance of baggage.
static void BM_DecodeBaggage(benchmark::State& state) {
// Construct a header from sample value.
google::protobuf::Struct metadata_struct;
JsonParseOptions json_parse_options;
ASSERT_OK(
JsonStringToMessage(std::string(node_flatbuffer_json), &metadata_struct, json_parse_options));
auto fb = ::Wasm::Common::extractNodeFlatBufferFromStruct(metadata_struct);
const auto& node = *flatbuffers::GetRoot<Wasm::Common::FlatNode>(fb.data());
const std::string baggage = Istio::Common::convertFlatNodeToWorkloadMetadata(node).baggage();
size_t size = 0;
for (auto _ : state) {
auto obj = Istio::Common::WorkloadMetadataObject::fromBaggage(baggage);
size += obj.namespace_name_.size();
benchmark::DoNotOptimize(size);
}
}
BENCHMARK(BM_DecodeBaggage);
} // namespace Common
// WASM_EPILOG
#ifdef NULL_PLUGIN
} // namespace Wasm
#endif

View File

@ -1,157 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/common/proto_util.h"
#include "extensions/common/node_info_generated.h"
#include "google/protobuf/struct.pb.h"
#include "google/protobuf/text_format.h"
#include "google/protobuf/util/json_util.h"
#include "gtest/gtest.h"
// WASM_PROLOG
#ifdef NULL_PLUGIN
namespace Wasm {
#endif // NULL_PLUGIN
// END WASM_PROLOG
namespace Common {
using namespace google::protobuf;
using namespace google::protobuf::util;
constexpr std::string_view node_metadata_json = R"###(
{
"NAME":"test_pod",
"NAMESPACE":"test_namespace",
"OWNER":"test_owner",
"WORKLOAD_NAME":"test_workload",
"ISTIO_VERSION":"1.8",
"MESH_ID":"istio-mesh",
"CLUSTER_ID":"test-cluster",
"LABELS":{
"app":"test",
"version":"v1"
},
"PLATFORM_METADATA":{
"gcp_cluster_location":"test_location",
"gcp_cluster_name":"test_cluster",
"gcp_project":"test_project"
},
"APP_CONTAINERS": "hello,test",
"INSTANCE_IPS": "10.10.10.1,10.10.10.2,10.10.10.3"
}
)###";
constexpr std::string_view node_metadata_json_with_missing_lists = R"###(
{
"NAME":"test_pod",
"NAMESPACE":"test_namespace",
"OWNER":"test_owner",
"WORKLOAD_NAME":"test_workload",
"ISTIO_VERSION":"1.8",
"MESH_ID":"istio-mesh",
"CLUSTER_ID":"test-cluster",
"LABELS":{
"app":"test",
"version":"v1"
},
"PLATFORM_METADATA":{
"gcp_cluster_location":"test_location",
"gcp_cluster_name":"test_cluster",
"gcp_project":"test_project"
},
}
)###";
// Test all possible metadata field.
TEST(ProtoUtilTest, extractNodeMetadata) {
google::protobuf::Struct metadata_struct;
JsonParseOptions json_parse_options;
EXPECT_TRUE(
JsonStringToMessage(std::string(node_metadata_json), &metadata_struct, json_parse_options)
.ok());
auto out = extractNodeFlatBufferFromStruct(metadata_struct);
auto peer = flatbuffers::GetRoot<FlatNode>(out.data());
EXPECT_EQ(peer->name()->string_view(), "test_pod");
EXPECT_EQ(peer->namespace_()->string_view(), "test_namespace");
EXPECT_EQ(peer->owner()->string_view(), "test_owner");
EXPECT_EQ(peer->workload_name()->string_view(), "test_workload");
EXPECT_EQ(peer->platform_metadata()->Get(2)->key()->string_view(), "gcp_project");
EXPECT_EQ(peer->platform_metadata()->Get(2)->value()->string_view(), "test_project");
EXPECT_EQ(peer->app_containers()->size(), 2);
EXPECT_EQ(peer->instance_ips()->size(), 3);
EXPECT_EQ(peer->cluster_id()->string_view(), "test-cluster");
}
// Test all possible metadata field.
TEST(ProtoUtilTest, extractNodeMetadataWithMissingLists) {
google::protobuf::Struct metadata_struct;
JsonParseOptions json_parse_options;
EXPECT_TRUE(JsonStringToMessage(std::string(node_metadata_json_with_missing_lists),
&metadata_struct, json_parse_options)
.ok());
auto out = extractNodeFlatBufferFromStruct(metadata_struct);
auto peer = flatbuffers::GetRoot<FlatNode>(out.data());
EXPECT_EQ(peer->name()->string_view(), "test_pod");
EXPECT_EQ(peer->namespace_()->string_view(), "test_namespace");
EXPECT_EQ(peer->owner()->string_view(), "test_owner");
EXPECT_EQ(peer->workload_name()->string_view(), "test_workload");
EXPECT_EQ(peer->platform_metadata()->Get(2)->key()->string_view(), "gcp_project");
EXPECT_EQ(peer->platform_metadata()->Get(2)->value()->string_view(), "test_project");
EXPECT_EQ(peer->app_containers(), nullptr);
EXPECT_EQ(peer->instance_ips(), nullptr);
EXPECT_EQ(peer->cluster_id()->string_view(), "test-cluster");
}
// Test roundtripping
TEST(ProtoUtilTest, Rountrip) {
google::protobuf::Struct metadata_struct;
JsonParseOptions json_parse_options;
EXPECT_TRUE(
JsonStringToMessage(std::string(node_metadata_json), &metadata_struct, json_parse_options)
.ok());
auto out = extractNodeFlatBufferFromStruct(metadata_struct);
auto peer = flatbuffers::GetRoot<FlatNode>(out.data());
google::protobuf::Struct output_struct;
extractStructFromNodeFlatBuffer(*peer, &output_struct);
// Validate serialized bytes
std::string input_bytes;
EXPECT_TRUE(serializeToStringDeterministic(metadata_struct, &input_bytes));
std::string output_bytes;
EXPECT_TRUE(serializeToStringDeterministic(output_struct, &output_bytes));
EXPECT_EQ(input_bytes, output_bytes)
<< metadata_struct.DebugString() << output_struct.DebugString();
}
// Test roundtrip for an empty struct (for corner cases)
TEST(ProtoUtilTest, RountripEmpty) {
google::protobuf::Struct metadata_struct;
auto out = extractNodeFlatBufferFromStruct(metadata_struct);
auto peer = flatbuffers::GetRoot<FlatNode>(out.data());
google::protobuf::Struct output_struct;
extractStructFromNodeFlatBuffer(*peer, &output_struct);
EXPECT_EQ(0, output_struct.fields().size());
}
} // namespace Common
// WASM_EPILOG
#ifdef NULL_PLUGIN
} // namespace Wasm
#endif

View File

@ -1,225 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/common/util.h"
#include "absl/strings/str_cat.h"
namespace Wasm {
namespace Common {
namespace {
// This replicates the flag lists in envoyproxy/envoy, because the property
// access API does not support returning response flags as a short string since
// it is not owned by any object and always generated on demand:
// https://github.com/envoyproxy/envoy/blob/v1.18.3/source/common/stream_info/utility.h#L21
constexpr static absl::string_view DOWNSTREAM_CONNECTION_TERMINATION = "DC";
constexpr static absl::string_view FAILED_LOCAL_HEALTH_CHECK = "LH";
constexpr static absl::string_view NO_HEALTHY_UPSTREAM = "UH";
constexpr static absl::string_view UPSTREAM_REQUEST_TIMEOUT = "UT";
constexpr static absl::string_view LOCAL_RESET = "LR";
constexpr static absl::string_view UPSTREAM_REMOTE_RESET = "UR";
constexpr static absl::string_view UPSTREAM_CONNECTION_FAILURE = "UF";
constexpr static absl::string_view UPSTREAM_CONNECTION_TERMINATION = "UC";
constexpr static absl::string_view UPSTREAM_OVERFLOW = "UO";
constexpr static absl::string_view UPSTREAM_RETRY_LIMIT_EXCEEDED = "URX";
constexpr static absl::string_view NO_ROUTE_FOUND = "NR";
constexpr static absl::string_view DELAY_INJECTED = "DI";
constexpr static absl::string_view FAULT_INJECTED = "FI";
constexpr static absl::string_view RATE_LIMITED = "RL";
constexpr static absl::string_view UNAUTHORIZED_EXTERNAL_SERVICE = "UAEX";
constexpr static absl::string_view RATELIMIT_SERVICE_ERROR = "RLSE";
constexpr static absl::string_view STREAM_IDLE_TIMEOUT = "SI";
constexpr static absl::string_view INVALID_ENVOY_REQUEST_HEADERS = "IH";
constexpr static absl::string_view DOWNSTREAM_PROTOCOL_ERROR = "DPE";
constexpr static absl::string_view UPSTREAM_MAX_STREAM_DURATION_REACHED = "UMSDR";
constexpr static absl::string_view RESPONSE_FROM_CACHE_FILTER = "RFCF";
constexpr static absl::string_view NO_FILTER_CONFIG_FOUND = "NFCF";
constexpr static absl::string_view DURATION_TIMEOUT = "DT";
constexpr static absl::string_view UPSTREAM_PROTOCOL_ERROR = "UPE";
constexpr static absl::string_view NO_CLUSTER_FOUND = "NC";
constexpr static absl::string_view OVERLOAD_MANAGER = "OM";
constexpr static absl::string_view DNS_RESOLUTION_FAILURE = "DF";
constexpr static absl::string_view DROP_OVERLOAD = "DO";
enum ResponseFlag {
FailedLocalHealthCheck = 0x1,
NoHealthyUpstream = 0x2,
UpstreamRequestTimeout = 0x4,
LocalReset = 0x8,
UpstreamRemoteReset = 0x10,
UpstreamConnectionFailure = 0x20,
UpstreamConnectionTermination = 0x40,
UpstreamOverflow = 0x80,
NoRouteFound = 0x100,
DelayInjected = 0x200,
FaultInjected = 0x400,
RateLimited = 0x800,
UnauthorizedExternalService = 0x1000,
RateLimitServiceError = 0x2000,
DownstreamConnectionTermination = 0x4000,
UpstreamRetryLimitExceeded = 0x8000,
StreamIdleTimeout = 0x10000,
InvalidEnvoyRequestHeaders = 0x20000,
DownstreamProtocolError = 0x40000,
UpstreamMaxStreamDurationReached = 0x80000,
ResponseFromCacheFilter = 0x100000,
NoFilterConfigFound = 0x200000,
DurationTimeout = 0x400000,
UpstreamProtocolError = 0x800000,
NoClusterFound = 0x1000000,
OverloadManager = 0x2000000,
DnsResolutionFailed = 0x4000000,
DropOverLoad = 0x8000000,
LastFlag = DropOverLoad,
};
void appendString(std::string& result, const absl::string_view& append) {
if (result.empty()) {
result = std::string(append);
} else {
absl::StrAppend(&result, ",", append);
}
}
} // namespace
const std::string parseResponseFlag(uint64_t response_flag) {
std::string result;
if (response_flag & FailedLocalHealthCheck) {
appendString(result, FAILED_LOCAL_HEALTH_CHECK);
}
if (response_flag & NoHealthyUpstream) {
appendString(result, NO_HEALTHY_UPSTREAM);
}
if (response_flag & UpstreamRequestTimeout) {
appendString(result, UPSTREAM_REQUEST_TIMEOUT);
}
if (response_flag & LocalReset) {
appendString(result, LOCAL_RESET);
}
if (response_flag & UpstreamRemoteReset) {
appendString(result, UPSTREAM_REMOTE_RESET);
}
if (response_flag & UpstreamConnectionFailure) {
appendString(result, UPSTREAM_CONNECTION_FAILURE);
}
if (response_flag & UpstreamConnectionTermination) {
appendString(result, UPSTREAM_CONNECTION_TERMINATION);
}
if (response_flag & UpstreamOverflow) {
appendString(result, UPSTREAM_OVERFLOW);
}
if (response_flag & NoRouteFound) {
appendString(result, NO_ROUTE_FOUND);
}
if (response_flag & DelayInjected) {
appendString(result, DELAY_INJECTED);
}
if (response_flag & FaultInjected) {
appendString(result, FAULT_INJECTED);
}
if (response_flag & RateLimited) {
appendString(result, RATE_LIMITED);
}
if (response_flag & UnauthorizedExternalService) {
appendString(result, UNAUTHORIZED_EXTERNAL_SERVICE);
}
if (response_flag & RateLimitServiceError) {
appendString(result, RATELIMIT_SERVICE_ERROR);
}
if (response_flag & DownstreamConnectionTermination) {
appendString(result, DOWNSTREAM_CONNECTION_TERMINATION);
}
if (response_flag & UpstreamRetryLimitExceeded) {
appendString(result, UPSTREAM_RETRY_LIMIT_EXCEEDED);
}
if (response_flag & StreamIdleTimeout) {
appendString(result, STREAM_IDLE_TIMEOUT);
}
if (response_flag & InvalidEnvoyRequestHeaders) {
appendString(result, INVALID_ENVOY_REQUEST_HEADERS);
}
if (response_flag & DownstreamProtocolError) {
appendString(result, DOWNSTREAM_PROTOCOL_ERROR);
}
if (response_flag & UpstreamMaxStreamDurationReached) {
appendString(result, UPSTREAM_MAX_STREAM_DURATION_REACHED);
}
if (response_flag & ResponseFromCacheFilter) {
appendString(result, RESPONSE_FROM_CACHE_FILTER);
}
if (response_flag & NoFilterConfigFound) {
appendString(result, NO_FILTER_CONFIG_FOUND);
}
if (response_flag & DurationTimeout) {
appendString(result, DURATION_TIMEOUT);
}
if (response_flag & UpstreamProtocolError) {
appendString(result, UPSTREAM_PROTOCOL_ERROR);
}
if (response_flag & NoClusterFound) {
appendString(result, NO_CLUSTER_FOUND);
}
if (response_flag & OverloadManager) {
appendString(result, OVERLOAD_MANAGER);
}
if (response_flag & DnsResolutionFailed) {
appendString(result, DNS_RESOLUTION_FAILURE);
}
if (response_flag & DropOverLoad) {
appendString(result, DROP_OVERLOAD);
}
if (response_flag >= (LastFlag << 1)) {
// Response flag integer overflows. Append the integer to avoid information
// loss.
appendString(result, std::to_string(response_flag));
}
return result.empty() ? ::Wasm::Common::NONE : result;
}
} // namespace Common
} // namespace Wasm

View File

@ -1,44 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
#include "absl/strings/string_view.h"
namespace Wasm {
namespace Common {
// None response flag.
const char NONE[] = "-";
// Parses an integer response flag into a readable short string.
const std::string parseResponseFlag(uint64_t response_flag);
// Used for converting sanctioned uses of std string_view (e.g. extensions) to
// absl::string_view for internal use.
inline absl::string_view toAbslStringView(std::string_view view) {
return absl::string_view(view.data(), view.size());
}
// Used for converting internal absl::string_view to sanctioned uses of std
// string_view (e.g. extensions).
inline std::string_view toStdStringView(absl::string_view view) {
return std::string_view(view.data(), view.size());
}
} // namespace Common
} // namespace Wasm

View File

@ -1,54 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/common/util.h"
#include "gtest/gtest.h"
namespace Wasm {
namespace Common {
namespace {
TEST(WasmCommonUtilsTest, ParseResponseFlag) {
std::vector<std::pair<uint64_t, std::string>> expected = {
std::make_pair(0x1, "LH"), std::make_pair(0x2, "UH"), std::make_pair(0x4, "UT"),
std::make_pair(0x8, "LR"), std::make_pair(0x10, "UR"), std::make_pair(0x20, "UF"),
std::make_pair(0x40, "UC"), std::make_pair(0x80, "UO"), std::make_pair(0x100, "NR"),
std::make_pair(0x200, "DI"), std::make_pair(0x400, "FI"), std::make_pair(0x800, "RL"),
std::make_pair(0x1000, "UAEX"), std::make_pair(0x2000, "RLSE"), std::make_pair(0x4000, "DC"),
std::make_pair(0x8000, "URX"), std::make_pair(0x10000, "SI"), std::make_pair(0x20000, "IH"),
std::make_pair(0x40000, "DPE"),
};
for (const auto& test_case : expected) {
EXPECT_EQ(test_case.second, parseResponseFlag(test_case.first));
}
// No flag is set.
{ EXPECT_EQ("-", parseResponseFlag(0x0)); }
// Test combinations.
// These are not real use cases, but are used to cover multiple response flags
// case.
{ EXPECT_EQ("UT,DI,FI", parseResponseFlag(0x604)); }
{ EXPECT_EQ("DPE,DO", parseResponseFlag(0x8040000)); }
// Test overflow.
{ EXPECT_EQ("DPE,DO,402915328", parseResponseFlag(0x18040000)); }
}
} // namespace
} // namespace Common
} // namespace Wasm

View File

@ -1,49 +0,0 @@
# Copyright 2019 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_library",
)
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
envoy_cc_library(
name = "stackdriver_plugin",
srcs = [
"stackdriver.cc",
"stackdriver_plugin_factory.cc",
],
hdrs = [
"stackdriver.h",
],
repository = "@envoy",
deps = [
"//extensions/common:context",
"//extensions/common:proto_util",
"//extensions/stackdriver/common:constants",
"//extensions/stackdriver/config/v1alpha1:stackdriver_plugin_config_cc_proto",
"//extensions/stackdriver/log:exporter",
"//extensions/stackdriver/log:logger",
"//extensions/stackdriver/metric",
"@io_opencensus_cpp//opencensus/exporters/stats/stackdriver:stackdriver_exporter",
"@proxy_wasm_cpp_host//:null_lib",
"@proxy_wasm_cpp_sdk//contrib:contrib_lib",
],
)

View File

@ -1,38 +0,0 @@
As part of the ongoing Telemetry V2 effort to move Mixer like processing to the proxy as Envoy filters, we are releasing experimental support for Stackdriver HTTP telemetry.
It is a replacement for the current Mixer Stackdriver adapter, which supports exporting [GCP Istio standard metric](https://cloud.google.com/monitoring/api/metrics_istio), server access log, and traces from the proxy.
## How to enable
### Metrics and Access Logs
Metrics and server side access log will be enabled by default by installing the Stackdriver filter.
1. Disable `Stackdriver adapter` or `istio-telemetry`
To avoid duplicated telemetry reporting, you should disable `Stackdriver adapter` if you already set it up with Mixer v1. To disable Stackdriver adapter, remove Stackdriver Mixer rules, handlers, and instances, e.g. run `kubectl delete -n istio-system rule your-stackdriver-rule && kubectl delete -n istio-system handler your-stackdriver-handlers && kubectl delete -n istio-system instance your-stackdriver-instance`
If you want to disable istio-telemetry as whole:
* If your cluster is installed using `istioctl`, run `istioctl manifest apply --set values.mixer.telemetry.enabled=false,values.mixer.policy.enabled=false`. If your cluster is installed via helm, run `helm template install/kubernetes/helm/istio --name istio --namespace istio-system --set mixer.telemetry.enabled=false --set mixer.policy.enabled=false`.
* Alternatively, you can comment out mixerCheckServer and mixerReportServer in your mesh configuration.
2. Enable metadata exchange filter
`kubectl -n istio-system apply -f https://raw.githubusercontent.com/istio/proxy/release-1.4/extensions/stats/testdata/istio/metadata-exchange_filter.yaml`
3. Enable Stackdriver filter
`kubectl -n istio-system apply -f https://raw.githubusercontent.com/istio/proxy/release-1.4/extensions/stackdriver/testdata/stackdriver_filter.yaml`
4. Visit Stackdriver Monitoring metric explorer and search for [standard Istio metrics](https://cloud.google.com/monitoring/api/metrics_istio). Visit Stackdriver Logging Viewer and search `server-accesslog-stackdriver` for access log entries.
### Trace
Opencensus tracer is by default shipped with 1.4.0 Istio proxy, which supports exporting traces to Stackdriver as other tracers liker Jeager and Zipkin. To enable it, set global tracer as Stackdriver: `helm template --set global.proxy.tracer="stackdriver" install/kubernetes/helm/istio --name istio --namespace istio-system | kubectl apply -f -`. The default sampling rate is 1%. To raise it, you could set it via traceSampling helm option: `--set pilot.traceSampling=100`
## Limitations in 1.4.0
1. No TCP telemetry.
2. Access log misses some labels, which will be added in the following 1.4.x releases.
## Details
1. The preview version uses the WASM sandbox API, but *does not* run inside a WASM VM. It is natively compiled in Envoy using `NullVM`.
2. In later release we will enable running filters in the V8 WASM VM.
3. At present The filters are configured using the Istio Envoy Filter API.

View File

@ -1,80 +0,0 @@
# Copyright 2019 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_library",
"envoy_cc_test",
)
package(default_visibility = ["//extensions/stackdriver:__subpackages__"])
licenses(["notice"])
envoy_cc_library(
name = "constants",
hdrs = [
"constants.h",
],
repository = "@envoy",
)
envoy_cc_library(
name = "utils",
srcs = [
"utils.cc",
],
hdrs = [
"utils.h",
],
external_deps = ["grpc"],
repository = "@envoy",
deps = [
":constants",
"//extensions/common:context",
"@com_google_googleapis//google/monitoring/v3:monitoring_cc_proto",
"@envoy_api//envoy/config/core/v3:pkg_cc_proto",
],
)
envoy_cc_test(
name = "utils_test",
size = "small",
srcs = ["utils_test.cc"],
repository = "@envoy",
deps = [
":constants",
":utils",
"@com_google_protobuf//:protobuf",
"@envoy//test/test_common:status_utility_lib",
"@envoy//test/test_common:wasm_lib",
],
)
envoy_cc_library(
name = "metrics",
srcs = [
"metrics.cc",
],
hdrs = [
"metrics.h",
],
repository = "@envoy",
deps = [
"@proxy_wasm_cpp_host//:null_lib",
],
)

View File

@ -1,154 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string>
#include <string_view>
namespace Extensions {
namespace Stackdriver {
namespace Common {
// Measure names of metrics.
constexpr char kServerRequestCountMeasure[] = "server/request_count_measure";
constexpr char kServerRequestBytesMeasure[] = "server/request_bytes_measure";
constexpr char kServerResponseBytesMeasure[] = "server/response_bytes_measure";
constexpr char kServerResponseLatenciesMeasure[] = "server/response_latencies_measure";
constexpr char kClientRequestCountMeasure[] = "client/request_count_measure";
constexpr char kClientRequestBytesMeasure[] = "client/request_bytes_measure";
constexpr char kClientResponseBytesMeasure[] = "client/response_bytes_measure";
constexpr char kClientRoundtripLatenciesMeasure[] = "client/roundtrip_latencies_measure";
constexpr char kServerConnectionsOpenCountMeasure[] = "server/connection_open_count_measure";
constexpr char kServerConnectionsCloseCountMeasure[] = "server/connection_close_count_measure";
constexpr char kServerReceivedBytesCountMeasure[] = "server/received_bytes_count_measure";
constexpr char kServerSentBytesCountMeasure[] = "server/sent_bytes_count_measure";
constexpr char kClientConnectionsOpenCountMeasure[] = "client/connection_open_count_measure";
constexpr char kClientConnectionsCloseCountMeasure[] = "client/connection_close_count_measure";
constexpr char kClientReceivedBytesCountMeasure[] = "client/received_bytes_count_measure";
constexpr char kClientSentBytesCountMeasure[] = "client/sent_bytes_count_measure";
// View names of metrics.
constexpr char kServerRequestCountView[] = "server/request_count";
constexpr char kServerRequestBytesView[] = "server/request_bytes";
constexpr char kServerResponseBytesView[] = "server/response_bytes";
constexpr char kServerResponseLatenciesView[] = "server/response_latencies";
constexpr char kClientRequestCountView[] = "client/request_count";
constexpr char kClientRequestBytesView[] = "client/request_bytes";
constexpr char kClientResponseBytesView[] = "client/response_bytes";
constexpr char kClientRoundtripLatenciesView[] = "client/roundtrip_latencies";
constexpr char kServerConnectionsOpenCountView[] = "server/connection_open_count";
constexpr char kServerConnectionsCloseCountView[] = "server/connection_close_count";
constexpr char kServerReceivedBytesCountView[] = "server/received_bytes_count";
constexpr char kServerSentBytesCountView[] = "server/sent_bytes_count";
constexpr char kClientConnectionsOpenCountView[] = "client/connection_open_count";
constexpr char kClientConnectionsCloseCountView[] = "client/connection_close_count";
constexpr char kClientReceivedBytesCountView[] = "client/received_bytes_count";
constexpr char kClientSentBytesCountView[] = "client/sent_bytes_count";
constexpr std::string_view kDefinedLabels[] = {
"request_protocol",
"service_authentication_policy",
"mesh_uid",
"destination_service_name",
"destination_service_namespace",
"destination_port",
"source_principal",
"source_workload_name",
"source_workload_namespace",
"source_owner",
"destination_principal",
"destination_workload_name",
"destination_workload_namespace",
"destination_owner",
"source_canonical_service_name",
"destination_canonical_service_name",
"source_canonical_service_namespace",
"destination_canonical_service_namespace",
"source_canonical_revision",
"destination_canonical_revision",
};
constexpr std::string_view kHttpDefinedLabels[] = {
"request_operation",
"response_code",
"api_version",
"api_name",
};
// Prefix for Istio metrics.
constexpr char kIstioMetricPrefix[] = "istio.io/service/";
// Monitored resource
constexpr char kPodMonitoredResource[] = "k8s_pod";
constexpr char kContainerMonitoredResource[] = "k8s_container";
constexpr char kGCEInstanceMonitoredResource[] = "gce_instance";
constexpr char kGenericNode[] = "generic_node";
constexpr char kProjectIDLabel[] = "project_id";
constexpr char kLocationLabel[] = "location";
constexpr char kClusterNameLabel[] = "cluster_name";
constexpr char kNamespaceNameLabel[] = "namespace_name";
constexpr char kPodNameLabel[] = "pod_name";
constexpr char kContainerNameLabel[] = "container_name";
constexpr char kGCEInstanceIDLabel[] = "instance_id";
constexpr char kZoneLabel[] = "zone";
constexpr char kNamespaceLabel[] = "namespace"; // used for generic_node
constexpr char kNodeIDLabel[] = "node_id"; // used for generic_node
// GCP node metadata key
constexpr char kGCPLocationKey[] = "gcp_location";
constexpr char kGCPClusterNameKey[] = "gcp_gke_cluster_name";
constexpr char kGCPProjectKey[] = "gcp_project";
constexpr std::string_view kGCPProjectNumberKey = "gcp_project_number";
constexpr char kGCPGCEInstanceIDKey[] = "gcp_gce_instance_id";
constexpr std::string_view kGCECreatedByKey = "gcp_gce_instance_created_by";
// Misc
constexpr char kIstioProxyContainerName[] = "istio-proxy";
constexpr double kNanosecondsPerMillisecond = 1000000.0;
// Stackdriver root context id.
constexpr char kOutboundRootContextId[] = "stackdriver_outbound";
constexpr char kInboundRootContextId[] = "stackdriver_inbound";
// Stackdriver service endpoint node metadata key.
constexpr char kSecureStackdriverEndpointKey[] = "SECURE_STACKDRIVER_ENDPOINT";
constexpr char kInsecureStackdriverEndpointKey[] = "INSECURE_STACKDRIVER_ENDPOINT";
constexpr char kMonitoringEndpointKey[] = "STACKDRIVER_MONITORING_ENDPOINT";
constexpr char kMonitoringExportIntervalKey[] = "STACKDRIVER_MONITORING_EXPORT_INTERVAL_SECS";
constexpr char kLoggingExportIntervalKey[] = "STACKDRIVER_LOGGING_EXPORT_INTERVAL_SECS";
constexpr char kTcpLogEntryTimeoutKey[] = "STACKDRIVER_TCP_LOG_ENTRY_TIMEOUT_SECS";
constexpr char kProxyTickerIntervalKey[] = "STACKDRIVER_PROXY_TICKER_INTERVAL_SECS";
constexpr char kTokenFile[] = "STACKDRIVER_TOKEN_FILE";
constexpr char kCACertFile[] = "STACKDRIVER_ROOT_CA_FILE";
// Port of security token exchange server (STS).
constexpr char kSTSPortKey[] = "STS_PORT";
// STS credentials
constexpr char kSTSSubjectTokenPath[] = "/var/run/secrets/tokens/istio-token";
constexpr char kSTSSubjectTokenType[] = "urn:ietf:params:oauth:token-type:jwt";
constexpr char kSTSScope[] = "https://www.googleapis.com/auth/cloud-platform";
// Stackdriver services
constexpr char kMonitoringService[] = "monitoring.googleapis.com";
constexpr char kLoggingService[] = "logging.googleapis.com";
constexpr char kMeshTelemetryService[] = "meshtelemetry.googleapis.com";
const std::string kUnknownLabel = "unknown";
} // namespace Common
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,52 +0,0 @@
/* Copyright 2020 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/stackdriver/common/metrics.h"
#ifdef NULL_PLUGIN
namespace proxy_wasm {
namespace null_plugin {
#endif
namespace Extensions {
namespace Stackdriver {
namespace Common {
uint32_t newExportCallMetric(const std::string& type, bool success) {
// NOTE: export_call cannot be a static global object, because in Nullvm,
// global metric is shared by base VM and thread local VM, but at host side,
// metrics are attached to a specific VM/root context. Since (1) metric object
// keeps an internal map which records all fully resolved metrics and avoid
// define metric ABI call when the same metric are seen (2) base VM always
// initiliazing before thread local VM, sharing a global metric object between
// base VM and thread local VM would cause host side thread local VM root
// context missing metric definition. This is not going to be a problem with
// real Wasm VM due to memory isolation.
Metric export_call(MetricType::Counter, "envoy_export_call",
{MetricTag{"wasm_filter", MetricTag::TagType::String},
MetricTag{"type", MetricTag::TagType::String},
MetricTag{"success", MetricTag::TagType::Bool}});
return export_call.resolve("stackdriver_filter", type, success);
}
} // namespace Common
} // namespace Stackdriver
} // namespace Extensions
#ifdef NULL_PLUGIN
} // namespace null_plugin
} // namespace proxy_wasm
#endif

View File

@ -1,44 +0,0 @@
/* Copyright 2020 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#ifndef NULL_PLUGIN
#include "api/wasm/cpp/proxy_wasm_intrinsics.h"
#else
#include "include/proxy-wasm/null_plugin.h"
namespace proxy_wasm {
namespace null_plugin {
#endif
namespace Extensions {
namespace Stackdriver {
namespace Common {
// newExportCallMetric create a fully resolved metric based on the given type
// and a boolean which indicates whether the call succeeds or not. Current type
// could only be logging.
uint32_t newExportCallMetric(const std::string& type, bool success);
} // namespace Common
} // namespace Stackdriver
} // namespace Extensions
#ifdef NULL_PLUGIN
} // namespace null_plugin
} // namespace proxy_wasm
#endif

View File

@ -1,261 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/stackdriver/common/utils.h"
#include "absl/strings/str_join.h"
#include "extensions/common/util.h"
#include "extensions/stackdriver/common/constants.h"
#include "grpcpp/grpcpp.h"
namespace Extensions {
namespace Stackdriver {
namespace Common {
namespace {
const std::string
getContainerName(const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>* containers) {
if (containers && containers->size() == 1) {
return flatbuffers::GetString(containers->Get(0));
}
return kIstioProxyContainerName;
}
std::string
getNodeID(const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>* ip_addrs) {
if (!ip_addrs || ip_addrs->size() == 0) {
return "istio-proxy";
}
std::vector<std::string> ips;
ips.reserve(ip_addrs->size());
for (auto it = ip_addrs->begin(); it != ip_addrs->end(); ++it) {
ips.push_back(flatbuffers::GetString(*it));
}
return absl::StrJoin(ips, ",");
}
} // namespace
using google::api::MonitoredResource;
void buildEnvoyGrpcService(const StackdriverStubOption& stub_option, GrpcService* grpc_service) {
if (!stub_option.insecure_endpoint.empty()) {
// Do not set up credential if insecure endpoint is provided. This is only
// for testing.
grpc_service->mutable_google_grpc()->set_target_uri(stub_option.insecure_endpoint);
return;
}
grpc_service->mutable_google_grpc()->set_target_uri(stub_option.secure_endpoint.empty()
? stub_option.default_endpoint
: stub_option.secure_endpoint);
if (stub_option.sts_port.empty()) {
// Security token exchange is not enabled. Use default Google credential.
grpc_service->mutable_google_grpc()->mutable_channel_credentials()->mutable_google_default();
return;
}
setSTSCallCredentialOptions(
grpc_service->mutable_google_grpc()->add_call_credentials()->mutable_sts_service(),
stub_option.sts_port,
stub_option.test_token_path.empty() ? kSTSSubjectTokenPath : stub_option.test_token_path);
auto initial_metadata = grpc_service->add_initial_metadata();
// When using p4sa/sts, google backend needs `x-goog-user-project` in initial
// metadata to differentiate which project the call should be accounted for.
initial_metadata->set_key("x-goog-user-project");
initial_metadata->set_value(stub_option.project_id);
auto* ssl_creds =
grpc_service->mutable_google_grpc()->mutable_channel_credentials()->mutable_ssl_credentials();
if (!stub_option.test_root_pem_path.empty()) {
ssl_creds->mutable_root_certs()->set_filename(stub_option.test_root_pem_path);
}
}
bool isRawGCEInstance(const ::Wasm::Common::FlatNode& node) {
auto platform_metadata = node.platform_metadata();
if (!platform_metadata) {
return false;
}
auto instance_id = platform_metadata->LookupByKey(kGCPGCEInstanceIDKey);
auto cluster_name = platform_metadata->LookupByKey(kGCPClusterNameKey);
return instance_id && !cluster_name;
}
std::string getGCEInstanceUID(const ::Wasm::Common::FlatNode& node) {
auto platform_metadata = node.platform_metadata();
if (!platform_metadata) {
return "";
}
auto project = platform_metadata->LookupByKey(kGCPProjectKey);
auto location = platform_metadata->LookupByKey(kGCPLocationKey);
auto instance_id = platform_metadata->LookupByKey(kGCPGCEInstanceIDKey);
auto name = node.name() ? node.name()->string_view() : std::string_view();
if (name.size() == 0 && instance_id) {
name = instance_id->value()->string_view();
}
if (name.size() > 0 && project && location) {
return absl::StrCat("//compute.googleapis.com/projects/",
::Wasm::Common::toAbslStringView(project->value()->string_view()),
"/zones/",
::Wasm::Common::toAbslStringView(location->value()->string_view()),
"/instances/", ::Wasm::Common::toAbslStringView(name));
}
return "";
}
std::string getOwner(const ::Wasm::Common::FlatNode& node) {
// do not override supplied owner
if (node.owner()) {
return flatbuffers::GetString(node.owner());
}
// only attempt for GCE Instances at this point. Support for other
// platforms will have to be added later. We also don't try to discover
// owners for GKE workload instances, as those should be handled by the
// sidecar injector.
if (isRawGCEInstance(node)) {
auto platform_metadata = node.platform_metadata();
if (!platform_metadata) {
return "";
}
auto created_by = platform_metadata->LookupByKey(kGCECreatedByKey.data());
if (created_by) {
return absl::StrCat("//compute.googleapis.com/",
::Wasm::Common::toAbslStringView(created_by->value()->string_view()));
}
return getGCEInstanceUID(node);
}
return "";
}
void getMonitoredResource(const std::string& monitored_resource_type,
const ::Wasm::Common::FlatNode& local_node_info,
MonitoredResource* monitored_resource) {
if (!monitored_resource) {
return;
}
monitored_resource->set_type(monitored_resource_type);
auto platform_metadata = local_node_info.platform_metadata();
if (platform_metadata) {
auto project_key = platform_metadata->LookupByKey(kGCPProjectKey);
if (project_key) {
(*monitored_resource->mutable_labels())[kProjectIDLabel] =
flatbuffers::GetString(project_key->value());
}
}
if (monitored_resource_type == kGenericNode) {
// need location, namespace, node_id
if (platform_metadata) {
auto location_label = platform_metadata->LookupByKey(kGCPLocationKey);
if (location_label) {
(*monitored_resource->mutable_labels())[kLocationLabel] =
flatbuffers::GetString(location_label->value());
}
(*monitored_resource->mutable_labels())[kNamespaceLabel] =
flatbuffers::GetString(local_node_info.namespace_());
auto node_id = getNodeID(local_node_info.instance_ips());
(*monitored_resource->mutable_labels())[kNodeIDLabel] = node_id;
}
return;
}
if (monitored_resource_type == kGCEInstanceMonitoredResource) {
// gce_instance
if (platform_metadata) {
auto instance_id_label = platform_metadata->LookupByKey(kGCPGCEInstanceIDKey);
if (instance_id_label) {
(*monitored_resource->mutable_labels())[kGCEInstanceIDLabel] =
flatbuffers::GetString(instance_id_label->value());
}
auto zone_label = platform_metadata->LookupByKey(kGCPLocationKey);
if (zone_label) {
(*monitored_resource->mutable_labels())[kZoneLabel] =
flatbuffers::GetString(zone_label->value());
}
}
} else {
// k8s_pod or k8s_container
if (platform_metadata) {
auto location_label = platform_metadata->LookupByKey(kGCPLocationKey);
if (location_label) {
(*monitored_resource->mutable_labels())[kLocationLabel] =
flatbuffers::GetString(location_label->value());
}
auto cluster_name = platform_metadata->LookupByKey(kGCPClusterNameKey);
if (cluster_name) {
(*monitored_resource->mutable_labels())[kClusterNameLabel] =
flatbuffers::GetString(cluster_name->value());
}
}
(*monitored_resource->mutable_labels())[kNamespaceNameLabel] =
flatbuffers::GetString(local_node_info.namespace_());
(*monitored_resource->mutable_labels())[kPodNameLabel] =
flatbuffers::GetString(local_node_info.name());
if (monitored_resource_type == kContainerMonitoredResource) {
// Fill in container_name of k8s_container monitored resource.
auto container = getContainerName(local_node_info.app_containers());
(*monitored_resource->mutable_labels())[kContainerNameLabel] = container;
}
}
}
void setSTSCallCredentialOptions(
::envoy::config::core::v3::GrpcService_GoogleGrpc_CallCredentials_StsService* sts_service,
const std::string& sts_port, const std::string& token_path) {
if (!sts_service) {
return;
}
sts_service->set_token_exchange_service_uri("http://localhost:" + sts_port + "/token");
sts_service->set_subject_token_path(token_path);
sts_service->set_subject_token_type(kSTSSubjectTokenType);
sts_service->set_scope(kSTSScope);
}
void setSTSCallCredentialOptions(::grpc::experimental::StsCredentialsOptions* sts_options,
const std::string& sts_port, const std::string& token_path) {
if (!sts_options) {
return;
}
sts_options->token_exchange_service_uri = "http://localhost:" + sts_port + "/token";
sts_options->subject_token_path = token_path;
sts_options->subject_token_type = kSTSSubjectTokenType;
sts_options->scope = kSTSScope;
}
const std::string& unknownIfEmpty(const std::string& val) {
if (val.empty()) {
return kUnknownLabel;
}
return val;
}
} // namespace Common
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,87 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "absl/strings/str_cat.h"
#include "extensions/common/context.h"
#include "google/api/monitored_resource.pb.h"
#include "grpcpp/grpcpp.h"
#ifndef NULL_PLUGIN
#include "api/wasm/cpp/proxy_wasm_intrinsics.h"
#else
#include "envoy/config/core/v3/grpc_service.pb.h"
using GrpcService = ::envoy::config::core::v3::GrpcService;
#endif
namespace Extensions {
namespace Stackdriver {
namespace Common {
// StackdriverStubOption includes all the configuration to construct stackdriver
// gRPC stubs.
struct StackdriverStubOption {
std::string sts_port;
std::string default_endpoint;
std::string test_token_path;
std::string test_root_pem_path;
std::string secure_endpoint;
std::string insecure_endpoint;
std::string monitoring_endpoint;
std::string project_id;
bool enable_log_compression;
};
// Build Envoy GrpcService proto based on the given stub option.
void buildEnvoyGrpcService(const StackdriverStubOption& option, GrpcService* grpc_service);
// Determines if the proxy is running directly on GCE instance (VM).
// If the proxy is running on GKE-managed VM, this will return false.
// The determination is made based on available `platform_metadata`
// for the node.
bool isRawGCEInstance(const ::Wasm::Common::FlatNode& node);
// Returns the unique identifier for a Raw GCE Instance. If the node
// is not a GCE Instance, the empty string will be returned.
std::string getGCEInstanceUID(const ::Wasm::Common::FlatNode& node);
// Returns "owner" information for a node. If that information
// has been directly set, that value is returned. If not, and the owner
// can be entirely derived from platform metadata, this will derive the
// owner. Currently, this is only supported for GCE Instances. For
// anything else, this will return the empty string.
std::string getOwner(const ::Wasm::Common::FlatNode& node);
// Gets monitored resource proto based on the type and node metadata info.
// Only two types of monitored resource could be returned: k8s_container or
// k8s_pod.
void getMonitoredResource(const std::string& monitored_resource_type,
const ::Wasm::Common::FlatNode& local_node_info,
google::api::MonitoredResource* monitored_resource);
// Set secure exchange service gRPC call credential.
void setSTSCallCredentialOptions(
::envoy::config::core::v3::GrpcService_GoogleGrpc_CallCredentials_StsService* sts_service,
const std::string& sts_port, const std::string& token_path);
void setSTSCallCredentialOptions(::grpc::experimental::StsCredentialsOptions* sts_options,
const std::string& sts_port, const std::string& token_path);
// Return unknown if the given value is empty string.
const std::string& unknownIfEmpty(const std::string& val);
} // namespace Common
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,122 +0,0 @@
/* Copyright 2020 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/stackdriver/common/utils.h"
#include "extensions/stackdriver/common/constants.h"
#include "gmock/gmock.h"
#include "google/protobuf/util/json_util.h"
#include "google/protobuf/util/message_differencer.h"
#include "test/test_common/status_utility.h"
#include "gtest/gtest.h"
namespace Extensions {
namespace Stackdriver {
namespace Common {
using google::protobuf::util::MessageDifferencer;
TEST(UtilsTest, TestEnvoyGrpcInsecure) {
GrpcService expected_envoy_grpc_service;
std::string envoy_google_grpc_json = R"({
"google_grpc": {
"target_uri": "test"
}
})";
google::protobuf::util::JsonParseOptions options;
ASSERT_OK(JsonStringToMessage(envoy_google_grpc_json, &expected_envoy_grpc_service, options));
StackdriverStubOption opt;
opt.insecure_endpoint = "test";
GrpcService envoy_grpc_service;
buildEnvoyGrpcService(opt, &envoy_grpc_service);
std::string diff;
MessageDifferencer differ;
differ.ReportDifferencesToString(&diff);
if (!differ.Compare(expected_envoy_grpc_service, envoy_grpc_service)) {
FAIL() << "unexpected envoy grpc service " << diff << "\n";
}
}
TEST(UtilsTest, TestEnvoyGrpcSTS) {
GrpcService expected_envoy_grpc_service;
std::string envoy_google_grpc_json = R"({
"google_grpc": {
"target_uri": "secure",
"channel_credentials": {
"ssl_credentials": {}
},
"call_credentials": {
"sts_service": {
"token_exchange_service_uri": "http://localhost:1234/token",
"subject_token_path": "/var/run/secrets/tokens/istio-token",
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
"scope": "https://www.googleapis.com/auth/cloud-platform"
}
}
},
"initial_metadata": {
"key": "x-goog-user-project",
"value": "project"
}
})";
google::protobuf::util::JsonParseOptions options;
ASSERT_OK(JsonStringToMessage(envoy_google_grpc_json, &expected_envoy_grpc_service, options));
StackdriverStubOption opt;
opt.secure_endpoint = "secure";
opt.sts_port = "1234";
opt.project_id = "project";
GrpcService envoy_grpc_service;
buildEnvoyGrpcService(opt, &envoy_grpc_service);
std::string diff;
MessageDifferencer differ;
differ.ReportDifferencesToString(&diff);
if (!differ.Compare(expected_envoy_grpc_service, envoy_grpc_service)) {
FAIL() << "unexpected envoy grpc service " << diff << "\n";
}
}
TEST(UtilsTest, TestEnvoyGrpcDefaultCredential) {
GrpcService expected_envoy_grpc_service;
std::string envoy_google_grpc_json = R"({
"google_grpc": {
"target_uri": "secure",
"channel_credentials": {
"google_default": {}
}
}
})";
google::protobuf::util::JsonParseOptions options;
ASSERT_OK(JsonStringToMessage(envoy_google_grpc_json, &expected_envoy_grpc_service, options));
StackdriverStubOption opt;
opt.secure_endpoint = "secure";
GrpcService envoy_grpc_service;
buildEnvoyGrpcService(opt, &envoy_grpc_service);
std::string diff;
MessageDifferencer differ;
differ.ReportDifferencesToString(&diff);
if (!differ.Compare(expected_envoy_grpc_service, envoy_grpc_service)) {
FAIL() << "unexpected envoy grpc service " << diff << "\n";
}
}
} // namespace Common
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,34 +0,0 @@
# Copyright 2019 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
cc_proto_library(
name = "stackdriver_plugin_config_cc_proto",
deps = ["stackdriver_plugin_config_proto"],
)
proto_library(
name = "stackdriver_plugin_config_proto",
srcs = ["stackdriver_plugin_config.proto"],
deps = [
"@com_google_protobuf//:duration_proto",
"@com_google_protobuf//:wrappers_proto",
],
)

View File

@ -1,365 +0,0 @@
---
title: Stackdriver Config
description: Configuration for Stackdriver filter.
location: https://istio.io/docs/reference/config/proxy_extensions/stackdriver.html
layout: protoc-gen-docs
generator: protoc-gen-docs
weight: 20
number_of_entries: 4
---
<h2 id="CustomConfig">CustomConfig</h2>
<section>
<p>Custom instance configuration overrides.
Provides a way to customize logs.</p>
<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="CustomConfig-dimensions">
<td><code>dimensions</code></td>
<td><code>map&lt;string,&nbsp;string&gt;</code></td>
<td>
<p>(Optional) Collection of tag names and tag expressions to include in the
instance. Conflicts are resolved by the tag name by overriding previously
supplied values.</p>
</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>
<h2 id="PluginConfig">PluginConfig</h2>
<section>
<p>next id: 17</p>
<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="PluginConfig-max_log_batch_size_in_bytes">
<td><code>max_log_batch_size_in_bytes</code></td>
<td><code>int32</code></td>
<td>
<p>Optional. Allows configuration of the size of the LogWrite request. The
size is in bytes, so that it allows for better performance. Default is 4MB.
The size of one log entry within LogWrite request is approx 1Kb.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-log_report_duration">
<td><code>log_report_duration</code></td>
<td><code><a href="https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#duration">Duration</a></code></td>
<td>
<p>Optional. Allows configuration of the time between calls out to the
stackdriver logging service to report buffered LogWrite request.
Customers can choose to report more aggressively by keeping shorter report
interval if needed. Default is 10s.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-enable_audit_log">
<td><code>enable_audit_log</code></td>
<td><code>bool</code></td>
<td>
<p>Optional. Controls whether to export audit log.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-destination_service_name">
<td><code>destination_service_name</code></td>
<td><code>string</code></td>
<td>
<p>Optional. FQDN of destination service that the request routed to, e.g.
productpage.default.svc.cluster.local. If not provided, request host header
will be used instead</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-max_peer_cache_size">
<td><code>max_peer_cache_size</code></td>
<td><code>int32</code></td>
<td>
<p>maximum size of the peer metadata cache.
A long lived proxy that connects with many transient peers can build up a
large cache. To turn off the cache, set this field to a negative value.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-disable_host_header_fallback">
<td><code>disable_host_header_fallback</code></td>
<td><code>bool</code></td>
<td>
<p>Optional: Disable using host header as a fallback if destination service is
not available from the controlplane. Disable the fallback if the host
header originates outsides the mesh, like at ingress.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-max_edges_batch_size">
<td><code>max_edges_batch_size</code></td>
<td><code>int32</code></td>
<td>
<p>Optional. Allows configuration of the number of traffic assertions to batch
into a single request. Default is 100. Max is 1000.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-enable_log_compression">
<td><code>enable_log_compression</code></td>
<td><code><a href="https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#boolvalue">BoolValue</a></code></td>
<td>
<p>Optional. Allows enabling log compression for stackdriver access logs.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-access_logging">
<td><code>access_logging</code></td>
<td><code><a href="#PluginConfig-AccessLogging">AccessLogging</a></code></td>
<td>
<p>Optional. Controls what type of logs to export.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-access_logging_filter_expression">
<td><code>access_logging_filter_expression</code></td>
<td><code>string</code></td>
<td>
<p>CEL expression for filtering access logging. If the expression evaluates
to true, an access log entry will be generated. Otherwise, no access log
entry will be generated.
NOTE: Audit logs ignore configured filters.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-custom_log_config">
<td><code>custom_log_config</code></td>
<td><code><a href="#CustomConfig">CustomConfig</a></code></td>
<td>
<p>(Optional) Collection of tag names and tag expressions to include in the
logs. Conflicts are resolved by the tag name by overriding previously
supplied values. Does not apply to audit logs.
See
<a href="https://istio.io/latest/docs/tasks/observability/metrics/customize-metrics/#use-expressions-for-values">https://istio.io/latest/docs/tasks/observability/metrics/customize-metrics/#use-expressions-for-values</a>
for more details about the expression language.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-metric_expiry_duration">
<td><code>metric_expiry_duration</code></td>
<td><code><a href="https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#duration">Duration</a></code></td>
<td>
<p>Optional. Controls the metric expiry duration. If a metric time series is
not updated for the given duration, it will be purged from time series
cache as well as metric reporting. If this is not set or set to 0, time
series will never be expired. This option is useful to avoid unbounded
metric label explodes proxy memory.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-metrics_overrides">
<td><code>metrics_overrides</code></td>
<td><code>map&lt;string,&nbsp;<a href="#MetricsOverride">MetricsOverride</a>&gt;</code></td>
<td>
<p>Optional. Allows altering metrics behavior.
Metric names for specifying overloads drop the <code>istio.io/service</code> prefix.
Examples: <code>server/request_count</code>, <code>client/roundtrip_latencies</code></p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-disable_server_access_logging" class="deprecated ">
<td><code>disable_server_access_logging</code></td>
<td><code>bool</code></td>
<td>
<p>Optional. Controls whether to export server access log.
This is deprecated in favor of AccessLogging enum.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-enable_mesh_edges_reporting" class="deprecated ">
<td><code>enable_mesh_edges_reporting</code></td>
<td><code>bool</code></td>
<td>
<p>Optional. Controls whether or not to export mesh edges to a mesh edges
service. This is disabled by default.
Deprecated &ndash; Mesh edge reporting is no longer supported and this setting
is no-op.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-mesh_edges_reporting_duration" class="deprecated ">
<td><code>mesh_edges_reporting_duration</code></td>
<td><code><a href="https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#duration">Duration</a></code></td>
<td>
<p>Optional. Allows configuration of the time between calls out to the mesh
edges service to report <em>NEW</em> edges. The minimum configurable duration is
<code>10s</code>. NOTE: This option ONLY configures the intermediate reporting of
novel edges. Once every <code>10m</code>, all edges observed in that 10m window are
reported and the local cache is cleared.
The default duration is <code>1m</code>. Any value greater than <code>10m</code> will result in
reporting every <code>10m</code>.
Deprecated &ndash; Mesh edge reporting is no longer supported and this setting
is no-op.</p>
</td>
<td>
No
</td>
</tr>
<tr id="PluginConfig-disable_http_size_metrics" class="deprecated ">
<td><code>disable_http_size_metrics</code></td>
<td><code>bool</code></td>
<td>
<p>Optional. Allows disabling of reporting of the request and response size
metrics for HTTP traffic. Defaults to false (request and response size
metrics are enabled).
Deprecated &ndash; use <code>metrics_overrides</code> instead.
if <code>metrics_overrides</code> is used, this value will be ignored.</p>
</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>
<h2 id="MetricsOverride">MetricsOverride</h2>
<section>
<p>Provides behavior modifications for Cloud Monitoring metrics.</p>
<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="MetricsOverride-drop">
<td><code>drop</code></td>
<td><code>bool</code></td>
<td>
<p>Optional. If true, no data for the associated metric will be collected or
exported.</p>
</td>
<td>
No
</td>
</tr>
<tr id="MetricsOverride-tag_overrides">
<td><code>tag_overrides</code></td>
<td><code>map&lt;string,&nbsp;string&gt;</code></td>
<td>
<p>Optional. Maps tag names to value expressions that will be used at
reporting time. If the tag name does not match a well-known tag for the
istio Cloud Monitoring metrics, the configuration will have no effect.</p>
</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>
<h2 id="PluginConfig-AccessLogging">PluginConfig.AccessLogging</h2>
<section>
<p>Types of Access logs to export. Does not affect audit logging.</p>
<table class="enum-values">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr id="PluginConfig-AccessLogging-NONE">
<td><code>NONE</code></td>
<td>
<p>No Logs.</p>
</td>
</tr>
<tr id="PluginConfig-AccessLogging-FULL">
<td><code>FULL</code></td>
<td>
<p>All logs including both success and error logs.</p>
</td>
</tr>
<tr id="PluginConfig-AccessLogging-ERRORS_ONLY">
<td><code>ERRORS_ONLY</code></td>
<td>
<p>All error logs. This is currently only available for outbound/client side
logs. A request is classified as error when <code>status&gt;=400 or response_flag != &quot;-&quot;</code></p>
</td>
</tr>
</tbody>
</table>
</section>

View File

@ -1,162 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
syntax = "proto3";
// clang-format off
// $title: Stackdriver Config
// $description: Configuration for Stackdriver filter.
// $location: https://istio.io/docs/reference/config/proxy_extensions/stackdriver.html
// $weight: 20
// clang-format on
package stackdriver.config.v1alpha1;
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
// Custom instance configuration overrides.
// Provides a way to customize logs.
message CustomConfig {
// (Optional) Collection of tag names and tag expressions to include in the
// instance. Conflicts are resolved by the tag name by overriding previously
// supplied values.
map<string, string> dimensions = 1;
// (Optional) A list of tags to remove.
// Not implemented yet.
// $hide_from_docs
repeated string tags_to_remove = 2;
}
// next id: 17
message PluginConfig {
// Types of Access logs to export. Does not affect audit logging.
enum AccessLogging {
// No Logs.
NONE = 0;
// All logs including both success and error logs.
FULL = 1;
// All error logs. This is currently only available for outbound/client side
// logs. A request is classified as error when `status>=400 or
// response_flag != "-"`
ERRORS_ONLY = 2;
};
// Optional. Controls whether to export server access log.
// This is deprecated in favor of AccessLogging enum.
bool disable_server_access_logging = 1 [deprecated = true];
// Optional. Allows configuration of the size of the LogWrite request. The
// size is in bytes, so that it allows for better performance. Default is 4MB.
// The size of one log entry within LogWrite request is approx 1Kb.
int32 max_log_batch_size_in_bytes = 12;
// Optional. Allows configuration of the time between calls out to the
// stackdriver logging service to report buffered LogWrite request.
// Customers can choose to report more aggressively by keeping shorter report
// interval if needed. Default is 10s.
google.protobuf.Duration log_report_duration = 13;
// Optional. Controls whether to export audit log.
bool enable_audit_log = 11;
// Optional. FQDN of destination service that the request routed to, e.g.
// productpage.default.svc.cluster.local. If not provided, request host header
// will be used instead
string destination_service_name = 2;
// Optional. Controls whether or not to export mesh edges to a mesh edges
// service. This is disabled by default.
// Deprecated -- Mesh edge reporting is no longer supported and this setting
// is no-op.
bool enable_mesh_edges_reporting = 3 [deprecated = true];
// Optional. Allows configuration of the time between calls out to the mesh
// edges service to report *NEW* edges. The minimum configurable duration is
// `10s`. NOTE: This option ONLY configures the intermediate reporting of
// novel edges. Once every `10m`, all edges observed in that 10m window are
// reported and the local cache is cleared.
// The default duration is `1m`. Any value greater than `10m` will result in
// reporting every `10m`.
// Deprecated -- Mesh edge reporting is no longer supported and this setting
// is no-op.
google.protobuf.Duration mesh_edges_reporting_duration = 4 [deprecated = true];
// maximum size of the peer metadata cache.
// A long lived proxy that connects with many transient peers can build up a
// large cache. To turn off the cache, set this field to a negative value.
int32 max_peer_cache_size = 5;
// Optional: Disable using host header as a fallback if destination service is
// not available from the controlplane. Disable the fallback if the host
// header originates outsides the mesh, like at ingress.
bool disable_host_header_fallback = 6;
// Optional. Allows configuration of the number of traffic assertions to batch
// into a single request. Default is 100. Max is 1000.
int32 max_edges_batch_size = 7;
// Optional. Allows disabling of reporting of the request and response size
// metrics for HTTP traffic. Defaults to false (request and response size
// metrics are enabled).
// Deprecated -- use `metrics_overrides` instead.
// if `metrics_overrides` is used, this value will be ignored.
bool disable_http_size_metrics = 8 [deprecated = true];
// Optional. Allows enabling log compression for stackdriver access logs.
google.protobuf.BoolValue enable_log_compression = 9;
// Optional. Controls what type of logs to export.
AccessLogging access_logging = 10;
// CEL expression for filtering access logging. If the expression evaluates
// to true, an access log entry will be generated. Otherwise, no access log
// entry will be generated.
// NOTE: Audit logs ignore configured filters.
string access_logging_filter_expression = 17;
// (Optional) Collection of tag names and tag expressions to include in the
// logs. Conflicts are resolved by the tag name by overriding previously
// supplied values. Does not apply to audit logs.
// See
// https://istio.io/latest/docs/tasks/observability/metrics/customize-metrics/#use-expressions-for-values
// for more details about the expression language.
CustomConfig custom_log_config = 14;
// Optional. Controls the metric expiry duration. If a metric time series is
// not updated for the given duration, it will be purged from time series
// cache as well as metric reporting. If this is not set or set to 0, time
// series will never be expired. This option is useful to avoid unbounded
// metric label explodes proxy memory.
google.protobuf.Duration metric_expiry_duration = 15;
// Optional. Allows altering metrics behavior.
// Metric names for specifying overloads drop the `istio.io/service` prefix.
// Examples: `server/request_count`, `client/roundtrip_latencies`
map<string, MetricsOverride> metrics_overrides = 16;
}
// Provides behavior modifications for Cloud Monitoring metrics.
message MetricsOverride {
// Optional. If true, no data for the associated metric will be collected or
// exported.
bool drop = 1;
// Optional. Maps tag names to value expressions that will be used at
// reporting time. If the tag name does not match a well-known tag for the
// istio Cloud Monitoring metrics, the configuration will have no effect.
map<string, string> tag_overrides = 2;
}

View File

@ -1,82 +0,0 @@
# Copyright 2019 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_library",
"envoy_cc_test",
)
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
envoy_cc_library(
name = "logger",
srcs = [
"logger.cc",
],
hdrs = [
"logger.h",
],
repository = "@envoy",
deps = [
":exporter",
"//extensions/common:context",
"//extensions/common:util",
"//extensions/stackdriver/common:constants",
"//extensions/stackdriver/common:utils",
"@com_google_absl//absl/strings",
"@com_google_googleapis//google/logging/v2:logging_cc_proto",
"@com_googlesource_code_re2//:re2",
"@proxy_wasm_cpp_host//:null_lib",
],
)
envoy_cc_library(
name = "exporter",
srcs = [
"exporter.cc",
],
hdrs = [
"exporter.h",
],
copts = ["-DPROXY_WASM_PROTOBUF=1"],
repository = "@envoy",
deps = [
"//extensions/stackdriver/common:metrics",
"//extensions/stackdriver/common:utils",
"@com_google_googleapis//google/logging/v2:logging_cc_proto",
"@proxy_wasm_cpp_host//:null_lib",
],
)
envoy_cc_test(
name = "logger_test",
size = "small",
srcs = ["logger_test.cc"],
repository = "@envoy",
deps = [
":logger",
"//extensions/stackdriver/common:constants",
"//extensions/stackdriver/common:utils",
"@com_google_googleapis//google/logging/v2:logging_cc_proto",
"@com_google_protobuf//:protobuf",
"@envoy//test/test_common:status_utility_lib",
"@envoy//test/test_common:wasm_lib",
],
)

View File

@ -1,109 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/stackdriver/log/exporter.h"
#include "extensions/stackdriver/common/constants.h"
#include "extensions/stackdriver/common/metrics.h"
#ifdef NULL_PLUGIN
#include "envoy/config/core/v3/grpc_service.pb.h"
namespace proxy_wasm {
namespace null_plugin {
using envoy::config::core::v3::GrpcService;
#endif
constexpr char kGoogleLoggingService[] = "google.logging.v2.LoggingServiceV2";
constexpr char kGoogleWriteLogEntriesMethod[] = "WriteLogEntries";
constexpr int kDefaultTimeoutMillisecond = 10000;
namespace Extensions {
namespace Stackdriver {
namespace Log {
ExporterImpl::ExporterImpl(
RootContext* root_context,
const ::Extensions::Stackdriver::Common::StackdriverStubOption& stub_option) {
context_ = root_context;
auto success_counter = Common::newExportCallMetric("logging", true);
auto failure_counter = Common::newExportCallMetric("logging", false);
success_callback_ = [this, success_counter](size_t) {
incrementMetric(success_counter, 1);
LOG_DEBUG("successfully sent Stackdriver logging request");
in_flight_export_call_ -= 1;
if (in_flight_export_call_ < 0) {
LOG_WARN("in flight report call should not be negative");
}
if (in_flight_export_call_ <= 0 && is_on_done_) {
proxy_done();
}
};
failure_callback_ = [this, failure_counter](GrpcStatus status) {
// TODO(bianpengyuan): add retry.
incrementMetric(failure_counter, 1);
LOG_WARN("Stackdriver logging api call error: " + std::to_string(static_cast<int>(status)) +
getStatus().second->toString());
in_flight_export_call_ -= 1;
if (in_flight_export_call_ < 0) {
LOG_WARN("in flight report call should not be negative");
}
if (in_flight_export_call_ <= 0 && is_on_done_) {
proxy_done();
}
};
// Construct grpc_service for the Stackdriver gRPC call.
GrpcService grpc_service;
grpc_service.mutable_google_grpc()->set_stat_prefix("stackdriver_logging");
if (stub_option.enable_log_compression) {
(*grpc_service.mutable_google_grpc()
->mutable_channel_args()
->mutable_args())[GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM]
.set_int_value(GRPC_COMPRESS_GZIP);
}
buildEnvoyGrpcService(stub_option, &grpc_service);
grpc_service.SerializeToString(&grpc_service_string_);
}
void ExporterImpl::exportLogs(
const std::vector<std::unique_ptr<const google::logging::v2::WriteLogEntriesRequest>>& requests,
bool is_on_done) {
is_on_done_ = is_on_done;
HeaderStringPairs initial_metadata;
for (const auto& req : requests) {
auto result = context_->grpcSimpleCall(
grpc_service_string_, kGoogleLoggingService, kGoogleWriteLogEntriesMethod, initial_metadata,
*req, kDefaultTimeoutMillisecond, success_callback_, failure_callback_);
if (result != WasmResult::Ok) {
LOG_WARN("failed to make stackdriver logging export call");
break;
}
in_flight_export_call_ += 1;
}
}
} // namespace Log
} // namespace Stackdriver
} // namespace Extensions
#ifdef NULL_PLUGIN
} // namespace null_plugin
} // namespace proxy_wasm
#endif

View File

@ -1,90 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
#include "extensions/stackdriver/common/utils.h"
#include "google/logging/v2/logging.pb.h"
#ifndef NULL_PLUGIN
#include "api/wasm/cpp/proxy_wasm_intrinsics.h"
#else
#include "include/proxy-wasm/null_plugin.h"
namespace proxy_wasm {
namespace null_plugin {
#endif
namespace Extensions {
namespace Stackdriver {
namespace Log {
// Log exporter interface.
class Exporter {
public:
virtual ~Exporter() {}
virtual void
exportLogs(const std::vector<std::unique_ptr<const google::logging::v2::WriteLogEntriesRequest>>&,
bool is_on_done) = 0;
};
// Exporter writes Stackdriver access log to the backend. It uses WebAssembly
// gRPC API.
class ExporterImpl : public Exporter {
public:
// root_context is the wasm runtime context that this instance runs with.
// logging_service_endpoint is an optional param which should be used for test
// only.
ExporterImpl(RootContext* root_context,
const ::Extensions::Stackdriver::Common::StackdriverStubOption& stub_option);
// exportLogs exports the given log request to Stackdriver.
void exportLogs(
const std::vector<std::unique_ptr<const google::logging::v2::WriteLogEntriesRequest>>& req,
bool is_on_done) override;
private:
// Wasm context that outbound calls are attached to.
RootContext* context_ = nullptr;
// Serialized string of Stackdriver logging service
std::string grpc_service_string_;
// Indicates if the current exporting is triggered by root context onDone. If
// this is true, gRPC callback needs to call proxy_done to indicate that async
// call finishes.
bool is_on_done_ = false;
// Callbacks for gRPC calls.
std::function<void(size_t)> success_callback_;
std::function<void(GrpcStatus)> failure_callback_;
// Record in flight export calls. When ondone is triggered, export call needs
// to be zero before calling proxy_done.
int in_flight_export_call_ = 0;
};
} // namespace Log
} // namespace Stackdriver
} // namespace Extensions
#ifdef NULL_PLUGIN
} // namespace null_plugin
} // namespace proxy_wasm
#endif

View File

@ -1,472 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/stackdriver/log/logger.h"
#include "absl/strings/match.h"
#include "extensions/common/util.h"
#include "extensions/stackdriver/common/constants.h"
#include "google/logging/v2/log_entry.pb.h"
#include "google/protobuf/util/time_util.h"
#include "re2/re2.h"
#ifndef NULL_PLUGIN
#include "api/wasm/cpp/proxy_wasm_intrinsics.h"
#else
#include "include/proxy-wasm/null_plugin.h"
#endif
namespace Extensions {
namespace Stackdriver {
namespace Log {
namespace {
// Matches Rbac Access denied string.
// It is of the format:
// "rbac_access_denied_matched_policy[ns[NAMESPACE]-policy[POLICY]-rule[POLICY_INDEX]]"
const RE2
rbac_denied_match("rbac_access_denied_matched_policy\\[ns\\[(.*)\\]-policy\\[(.*)\\]-rule\\[("
".*)\\]\\]");
constexpr char rbac_denied_match_prefix[] = "rbac_access_denied_matched_policy";
constexpr char kRbacAccessDenied[] = "AuthzDenied";
void setSourceCanonicalService(const ::Wasm::Common::FlatNode& peer_node_info,
google::protobuf::Map<std::string, std::string>* label_map) {
const auto peer_labels = peer_node_info.labels();
if (peer_labels) {
auto ics_iter = peer_labels->LookupByKey(Wasm::Common::kCanonicalServiceLabelName.data());
if (ics_iter) {
(*label_map)["source_canonical_service"] = flatbuffers::GetString(ics_iter->value());
}
}
}
void setDestinationCanonicalService(const ::Wasm::Common::FlatNode& peer_node_info,
google::protobuf::Map<std::string, std::string>* label_map) {
const auto peer_labels = peer_node_info.labels();
if (peer_labels) {
auto ics_iter = peer_labels->LookupByKey(Wasm::Common::kCanonicalServiceLabelName.data());
if (ics_iter) {
(*label_map)["destination_canonical_service"] = flatbuffers::GetString(ics_iter->value());
}
}
}
// Set monitored resources derived from local node info.
void setMonitoredResource(const ::Wasm::Common::FlatNode& local_node_info,
const std::string& resource_type,
google::logging::v2::WriteLogEntriesRequest* log_entries_request) {
google::api::MonitoredResource monitored_resource;
Common::getMonitoredResource(resource_type, local_node_info, &monitored_resource);
log_entries_request->mutable_resource()->CopyFrom(monitored_resource);
}
// Helper methods to fill destination Labels. Which labels are filled depends on
// if the entry is audit or not.
void fillDestinationLabels(const ::Wasm::Common::FlatNode& destination_node_info,
google::protobuf::Map<std::string, std::string>* label_map, bool audit) {
(*label_map)["destination_workload"] =
flatbuffers::GetString(destination_node_info.workload_name());
(*label_map)["destination_namespace"] =
flatbuffers::GetString(destination_node_info.namespace_());
// Don't set if audit request
if (!audit) {
(*label_map)["destination_name"] = flatbuffers::GetString(destination_node_info.name());
}
// Add destination app and version label if exist.
const auto local_labels = destination_node_info.labels();
if (local_labels) {
auto version_iter = local_labels->LookupByKey("version");
if (version_iter && !audit) {
(*label_map)["destination_version"] = flatbuffers::GetString(version_iter->value());
}
// App label is used to correlate workload and its logs in UI.
auto app_iter = local_labels->LookupByKey("app");
if (app_iter) {
(*label_map)["destination_app"] = flatbuffers::GetString(app_iter->value());
}
if (label_map->find("destination_canonical_service") == label_map->end()) {
setDestinationCanonicalService(destination_node_info, label_map);
}
auto rev_iter =
local_labels->LookupByKey(Wasm::Common::kCanonicalServiceRevisionLabelName.data());
if (rev_iter) {
(*label_map)["destination_canonical_revision"] = flatbuffers::GetString(rev_iter->value());
}
}
}
// Helper methods to fill source Labels. The labels filled depends on whether
// the log entry is audit or not.
void fillSourceLabels(const ::Wasm::Common::FlatNode& source_node_info,
google::protobuf::Map<std::string, std::string>* label_map, bool audit) {
if (!audit) {
(*label_map)["source_name"] = flatbuffers::GetString(source_node_info.name());
}
(*label_map)["source_workload"] = flatbuffers::GetString(source_node_info.workload_name());
(*label_map)["source_namespace"] = flatbuffers::GetString(source_node_info.namespace_());
// Add destination app and version label if exist.
const auto local_labels = source_node_info.labels();
if (local_labels) {
auto version_iter = local_labels->LookupByKey("version");
if (version_iter && !audit) {
(*label_map)["source_version"] = flatbuffers::GetString(version_iter->value());
}
// App label is used to correlate workload and its logs in UI.
auto app_iter = local_labels->LookupByKey("app");
if (app_iter) {
(*label_map)["source_app"] = flatbuffers::GetString(app_iter->value());
}
if (label_map->find("source_canonical_service") == label_map->end()) {
setSourceCanonicalService(source_node_info, label_map);
}
auto rev_iter =
local_labels->LookupByKey(Wasm::Common::kCanonicalServiceRevisionLabelName.data());
if (rev_iter) {
(*label_map)["source_canonical_revision"] = flatbuffers::GetString(rev_iter->value());
}
}
}
void fillExtraLabels(const std::unordered_map<std::string, std::string>& extra_labels,
google::protobuf::Map<std::string, std::string>* label_map) {
for (const auto& extra_label : extra_labels) {
(*label_map)[extra_label.first] = extra_label.second;
}
}
bool fillAuthInfo(const std::string& response_details,
google::protobuf::Map<std::string, std::string>* label_map) {
std::string policy_name, policy_namespace, policy_rule_index;
if (absl::StartsWith(response_details, rbac_denied_match_prefix)) {
(*label_map)["response_details"] = kRbacAccessDenied;
if (RE2::PartialMatch(response_details, rbac_denied_match, &policy_namespace, &policy_name,
&policy_rule_index)) {
(*label_map)["policy_name"] = absl::StrCat(policy_namespace, ".", policy_name);
(*label_map)["policy_rule"] = policy_rule_index;
}
return true;
}
return false;
}
} // namespace
using google::protobuf::util::TimeUtil;
// Name of the server access log.
constexpr char kServerAccessLogName[] = "server-accesslog-stackdriver";
// Name of the client access log.
constexpr char kClientAccessLogName[] = "client-accesslog-stackdriver";
// Name of the server audit access log.
constexpr char kServerAuditLogName[] = "server-istio-audit-log";
// Name of the client audit access log.
constexpr char kClientAuditLogName[] = "client-istio-audit-log";
void Logger::initializeLogEntryRequest(
const flatbuffers::Vector<flatbuffers::Offset<Wasm::Common::KeyVal>>* platform_metadata,
const ::Wasm::Common::FlatNode& local_node_info,
const std::unordered_map<std::string, std::string>& extra_labels, bool outbound, bool audit) {
LogEntryType log_entry_type = GetLogEntryType(outbound, audit);
log_entries_request_map_[log_entry_type]->request =
std::make_unique<google::logging::v2::WriteLogEntriesRequest>();
log_entries_request_map_[log_entry_type]->size = 0;
auto log_entries_request = log_entries_request_map_[log_entry_type]->request.get();
const std::string& log_name = audit ? (outbound ? kClientAuditLogName : kServerAuditLogName)
: (outbound ? kClientAccessLogName : kServerAccessLogName);
log_entries_request->set_log_name("projects/" + project_id_ + "/logs/" + log_name);
std::string resource_type =
outbound ? Common::kPodMonitoredResource : Common::kContainerMonitoredResource;
const auto cluster_iter =
platform_metadata ? platform_metadata->LookupByKey(Common::kGCPClusterNameKey) : nullptr;
if (!cluster_iter) {
// if there is no cluster name, then this is not a kubernetes resource
const auto instance_iter =
platform_metadata ? platform_metadata->LookupByKey(Common::kGCPGCEInstanceIDKey) : nullptr;
const auto creator_iter = platform_metadata
? platform_metadata->LookupByKey(Common::kGCECreatedByKey.data())
: nullptr;
if (!instance_iter && !creator_iter) {
resource_type = Common::kGCEInstanceMonitoredResource;
} else {
resource_type = Common::kGenericNode;
}
}
setMonitoredResource(local_node_info, resource_type, log_entries_request);
auto label_map = log_entries_request->mutable_labels();
if (!audit) {
(*label_map)["mesh_uid"] = flatbuffers::GetString(local_node_info.mesh_id());
}
// Set common labels shared by all client entries or server entries
outbound ? fillSourceLabels(local_node_info, label_map, audit)
: fillDestinationLabels(local_node_info, label_map, audit);
if (!audit) {
fillExtraLabels(extra_labels, label_map);
}
}
Logger::Logger(const ::Wasm::Common::FlatNode& local_node_info, std::unique_ptr<Exporter> exporter,
const std::unordered_map<std::string, std::string>& extra_labels,
int log_request_size_limit) {
const auto platform_metadata = local_node_info.platform_metadata();
const auto project_iter =
platform_metadata ? platform_metadata->LookupByKey(Common::kGCPProjectKey) : nullptr;
if (project_iter) {
project_id_ = flatbuffers::GetString(project_iter->value());
}
// Initalize the current WriteLogEntriesRequest for client/server
log_entries_request_map_[LogEntryType::Client] = std::make_unique<Logger::WriteLogEntryRequest>();
initializeLogEntryRequest(platform_metadata, local_node_info, extra_labels, true /*outbound */,
false /* audit */);
log_entries_request_map_[Logger::LogEntryType::Server] =
std::make_unique<Logger::WriteLogEntryRequest>();
initializeLogEntryRequest(platform_metadata, local_node_info, extra_labels, false /* outbound */,
false /* audit */);
log_entries_request_map_[LogEntryType::ClientAudit] =
std::make_unique<Logger::WriteLogEntryRequest>();
initializeLogEntryRequest(platform_metadata, local_node_info, extra_labels, true /*outbound */,
true /* audit */);
log_entries_request_map_[Logger::LogEntryType::ServerAudit] =
std::make_unique<Logger::WriteLogEntryRequest>();
initializeLogEntryRequest(platform_metadata, local_node_info, extra_labels, false /* outbound */,
true /* audit */);
log_request_size_limit_ = log_request_size_limit;
exporter_ = std::move(exporter);
}
void Logger::addTcpLogEntry(const ::Wasm::Common::RequestInfo& request_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const std::unordered_map<std::string, std::string>& extra_labels,
long int log_time, bool outbound, bool audit) {
// create a new log entry
auto* log_entries =
log_entries_request_map_[GetLogEntryType(outbound, audit)]->request->mutable_entries();
auto* new_entry = log_entries->Add();
*new_entry->mutable_timestamp() =
google::protobuf::util::TimeUtil::NanosecondsToTimestamp(log_time);
addTCPLabelsToLogEntry(request_info, peer_node_info, new_entry, outbound, audit);
fillAndFlushLogEntry(request_info, peer_node_info, extra_labels, new_entry, outbound, audit);
}
void Logger::addLogEntry(const ::Wasm::Common::RequestInfo& request_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const std::unordered_map<std::string, std::string>& extra_labels,
bool outbound, bool audit) {
// create a new log entry
auto* log_entries =
log_entries_request_map_[GetLogEntryType(outbound, audit)]->request->mutable_entries();
auto* new_entry = log_entries->Add();
*new_entry->mutable_timestamp() =
google::protobuf::util::TimeUtil::NanosecondsToTimestamp(request_info.start_time);
fillHTTPRequestInLogEntry(request_info, new_entry);
fillAndFlushLogEntry(request_info, peer_node_info, extra_labels, new_entry, outbound, audit);
}
void Logger::fillAndFlushLogEntry(const ::Wasm::Common::RequestInfo& request_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const std::unordered_map<std::string, std::string>& extra_labels,
google::logging::v2::LogEntry* new_entry, bool outbound,
bool audit) {
// match logic from stackdriver.cc that determines if error-only logging.
if (request_info.response_code >= 400 || request_info.response_flag != ::Wasm::Common::NONE) {
new_entry->set_severity(::google::logging::type::ERROR);
} else {
new_entry->set_severity(::google::logging::type::INFO);
}
auto label_map = new_entry->mutable_labels();
if (outbound) {
fillDestinationLabels(peer_node_info, label_map, audit);
} else {
fillSourceLabels(peer_node_info, label_map, audit);
}
(*label_map)["destination_service_host"] = request_info.destination_service_host;
(*label_map)["destination_service_name"] = request_info.destination_service_name;
(*label_map)["destination_principal"] = request_info.destination_principal;
(*label_map)["source_principal"] = request_info.source_principal;
if (!audit) {
(*label_map)["response_flag"] = request_info.response_flag;
(*label_map)["service_authentication_policy"] =
std::string(::Wasm::Common::AuthenticationPolicyString(request_info.service_auth_policy));
(*label_map)["protocol"] = ::Wasm::Common::ProtocolString(request_info.request_protocol);
(*label_map)["log_sampled"] = request_info.log_sampled ? "true" : "false";
(*label_map)["connection_id"] = std::to_string(request_info.connection_id);
if (!request_info.route_name.empty()) {
(*label_map)["route_name"] = request_info.route_name;
}
if (!request_info.upstream_host.empty()) {
(*label_map)["upstream_host"] = request_info.upstream_host;
}
(*label_map)["upstream_cluster"] = request_info.upstream_cluster;
if (!request_info.requested_server_name.empty()) {
(*label_map)["requested_server_name"] = request_info.requested_server_name;
}
if (!request_info.x_envoy_original_path.empty()) {
(*label_map)["x-envoy-original-path"] = request_info.x_envoy_original_path;
}
if (!request_info.x_envoy_original_dst_host.empty()) {
(*label_map)["x-envoy-original-dst-host"] = request_info.x_envoy_original_dst_host;
}
if (!request_info.upstream_transport_failure_reason.empty()) {
(*label_map)["upstream_transport_failure_reason"] =
request_info.upstream_transport_failure_reason;
}
if (!request_info.response_details.empty()) {
if (!fillAuthInfo(request_info.response_details, label_map)) {
(*label_map)["response_details"] = request_info.response_details;
}
}
}
// Insert trace headers, if exist.
if (request_info.b3_trace_sampled) {
new_entry->set_trace("projects/" + project_id_ + "/traces/" + request_info.b3_trace_id);
new_entry->set_span_id(request_info.b3_span_id);
new_entry->set_trace_sampled(request_info.b3_trace_sampled);
}
// This is done just before flushing, so that any customized label entry can
// override existing ones.
if (!audit) {
fillExtraLabels(extra_labels, new_entry->mutable_labels());
}
LogEntryType log_entry_type = GetLogEntryType(outbound, audit);
// Accumulate estimated size of the request. If the current request exceeds
// the size limit, flush the request out.
log_entries_request_map_[log_entry_type]->size += new_entry->ByteSizeLong();
if (log_entries_request_map_[log_entry_type]->size > log_request_size_limit_) {
flush(log_entry_type);
}
}
void Logger::flush(LogEntryType log_entry_type) {
auto request = log_entries_request_map_[log_entry_type]->request.get();
std::unique_ptr<google::logging::v2::WriteLogEntriesRequest> cur =
std::make_unique<google::logging::v2::WriteLogEntriesRequest>();
cur->set_log_name(request->log_name());
cur->mutable_resource()->CopyFrom(request->resource());
*cur->mutable_labels() = request->labels();
// Swap the new request with the old one and export it.
log_entries_request_map_[log_entry_type]->request.swap(cur);
request_queue_.emplace_back(std::move(cur));
// Reset size counter.
log_entries_request_map_[log_entry_type]->size = 0;
}
bool Logger::flush() {
bool flushed = false;
// This flush is triggered by timer, thus iterate through the map to see if
// any log entry is non empty.
for (auto const& log_entry : log_entries_request_map_) {
if (log_entry.second->size != 0) {
flush(log_entry.first);
flushed = true;
}
}
return flushed;
}
bool Logger::exportLogEntry(bool is_on_done) {
if (!flush() && request_queue_.empty()) {
// No log entry needs to export.
return false;
}
exporter_->exportLogs(request_queue_, is_on_done);
request_queue_.clear();
return true;
}
void Logger::addTCPLabelsToLogEntry(const ::Wasm::Common::RequestInfo& request_info,
const ::Wasm::Common::FlatNode& peer_node_info,
google::logging::v2::LogEntry* log_entry, bool outbound,
bool audit) {
const auto& entries_request = log_entries_request_map_[GetLogEntryType(outbound, audit)]->request;
auto label_map = log_entry->mutable_labels();
std::string source, destination;
if (outbound) {
setDestinationCanonicalService(peer_node_info, label_map);
auto source_cs_iter = entries_request->labels().find("source_canonical_service");
auto destination_cs_iter = label_map->find("destination_canonical_service");
source = source_cs_iter != entries_request->labels().end()
? source_cs_iter->second
: entries_request->labels().at("source_workload");
destination = destination_cs_iter != label_map->end() ? destination_cs_iter->second
: request_info.destination_service_name;
} else {
setSourceCanonicalService(peer_node_info, label_map);
auto source_cs_iter = label_map->find("source_canonical_service");
auto destination_cs_iter = entries_request->labels().find("destination_canonical_service");
source = source_cs_iter != label_map->end()
? source_cs_iter->second
: flatbuffers::GetString(peer_node_info.workload_name());
destination = destination_cs_iter != entries_request->labels().end()
? destination_cs_iter->second
: request_info.destination_service_name;
}
log_entry->set_text_payload(absl::StrCat(source, " --> ", destination));
(*label_map)["source_ip"] = request_info.source_address;
(*label_map)["destination_ip"] = request_info.destination_address;
(*label_map)["source_port"] = std::to_string(request_info.source_port);
(*label_map)["destination_port"] = std::to_string(request_info.destination_port);
(*label_map)["total_sent_bytes"] = std::to_string(request_info.tcp_total_sent_bytes);
(*label_map)["total_received_bytes"] = std::to_string(request_info.tcp_total_received_bytes);
(*label_map)["connection_state"] =
std::string(::Wasm::Common::TCPConnectionStateString(request_info.tcp_connection_state));
}
void Logger::fillHTTPRequestInLogEntry(const ::Wasm::Common::RequestInfo& request_info,
google::logging::v2::LogEntry* log_entry) {
auto http_request = log_entry->mutable_http_request();
http_request->set_request_method(request_info.request_operation);
http_request->set_request_url(request_info.url_scheme + "://" + request_info.url_host +
request_info.path);
http_request->set_request_size(request_info.request_size);
http_request->set_status(request_info.response_code);
http_request->set_response_size(request_info.response_size);
http_request->set_user_agent(request_info.user_agent);
http_request->set_remote_ip(request_info.source_address);
http_request->set_server_ip(request_info.destination_address);
http_request->set_protocol(::Wasm::Common::ProtocolString(request_info.request_protocol).data());
*http_request->mutable_latency() =
google::protobuf::util::TimeUtil::NanosecondsToDuration(request_info.duration);
http_request->set_referer(request_info.referer);
auto label_map = log_entry->mutable_labels();
(*label_map)["request_id"] = request_info.request_id;
}
} // namespace Log
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,164 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
#include <vector>
#include "extensions/common/context.h"
#include "extensions/stackdriver/log/exporter.h"
#include "google/logging/v2/logging.pb.h"
namespace Extensions {
namespace Stackdriver {
namespace Log {
#ifdef NULL_PLUGIN
using proxy_wasm::null_plugin::Extensions::Stackdriver::Log::Exporter;
#endif
// Logger records access logs and exports them to Stackdriver.
class Logger {
public:
// Logger initiate a Stackdriver access logger, which batches log entries and
// exports to Stackdriver backend with the given exporter.
// log_request_size_limit is the size limit of a logging request:
// https://cloud.google.com/logging/quotas.
Logger(const ::Wasm::Common::FlatNode& local_node_info, std::unique_ptr<Exporter> exporter,
const std::unordered_map<std::string, std::string>& extra_labels,
int log_request_size_limit = 4000000 /* 4 Mb */);
// Type of log entry.
enum LogEntryType { Client, ClientAudit, Server, ServerAudit };
// Add a new log entry based on the given request information and peer node
// information. The type of entry that is added depends on outbound and audit
// arguments.
//
// Audit labels:
// - destination_canonical_revision
// - destination_canonical_service
// - destination_service_name
// - destination_namespace
// - destination_principal
// - destination_service_host
// - destination_app
// - destination_workload
// - request_id
// - source_app
// - source_canonical_revision
// - source_canonical_service
// - source_namespace
// - source_workload
// - source_principal
//
void addLogEntry(const ::Wasm::Common::RequestInfo& request_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const std::unordered_map<std::string, std::string>& extra_labels, bool outbound,
bool audit);
// Add a new tcp log entry based on the given request information and peer
// node information. The type of entry that is added depends on outbound and
// audit arguments.
void addTcpLogEntry(const ::Wasm::Common::RequestInfo& request_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const std::unordered_map<std::string, std::string>& extra_labels,
long int log_time, bool outbound, bool audit);
// Export and clean the buffered WriteLogEntriesRequests. Returns true if
// async call is made to export log entry, otherwise returns false if nothing
// exported.
bool exportLogEntry(bool is_on_done);
private:
// Stores log entry request and it's size.
struct WriteLogEntryRequest {
// Request that the new log entry should be written into.
std::unique_ptr<google::logging::v2::WriteLogEntriesRequest> request;
// Estimated size of the current WriteLogEntriesRequest.
int size;
};
// Flush rotates the current WriteLogEntriesRequest. This will be triggered
// either by a timer or by request size limit. Returns false if there is no
// log entry to be exported.
bool flush();
void flush(LogEntryType log_entry_type);
// Add TCP Specific labels to LogEntry. Which labels are set depends on if
// the entry is an audit entry or not
void addTCPLabelsToLogEntry(const ::Wasm::Common::RequestInfo& request_info,
const ::Wasm::Common::FlatNode& peer_node_info,
google::logging::v2::LogEntry* log_entry, bool outbound, bool audit);
// Fill Http_Request entry in LogEntry.
void fillHTTPRequestInLogEntry(const ::Wasm::Common::RequestInfo& request_info,
google::logging::v2::LogEntry* log_entry);
// Generic method to fill the log entry. The WriteLogEntriesRequest
// containing the log entry is flushed if the request exceeds the configured
// maximum size. Which request should be flushed is determined by the outbound
// and audit arguments.
void fillAndFlushLogEntry(const ::Wasm::Common::RequestInfo& request_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const std::unordered_map<std::string, std::string>& extra_labels,
google::logging::v2::LogEntry* new_entry, bool outbound, bool audit);
// Helper method to initialize log entry request. The type of log entry is
// determined by the oubound and audit arguments.
void initializeLogEntryRequest(
const flatbuffers::Vector<flatbuffers::Offset<Wasm::Common::KeyVal>>* platform_metadata,
const ::Wasm::Common::FlatNode& local_node_info,
const std::unordered_map<std::string, std::string>& extra_labels, bool outbound, bool audit);
// Helper method to get Log Entry Type.
Logger::LogEntryType GetLogEntryType(bool outbound, bool audit) const {
if (outbound) {
if (audit) {
return Logger::LogEntryType::ClientAudit;
}
return Logger::LogEntryType::Client;
}
if (audit) {
return Logger::LogEntryType::ServerAudit;
}
return Logger::LogEntryType::Server;
}
// Buffer for WriteLogEntriesRequests that are to be exported.
std::vector<std::unique_ptr<const google::logging::v2::WriteLogEntriesRequest>> request_queue_;
// Stores client/server requests that the new log entry should be written
// into.
std::unordered_map<Logger::LogEntryType, std::unique_ptr<Logger::WriteLogEntryRequest>>
log_entries_request_map_;
// Size limit of a WriteLogEntriesRequest. If current WriteLogEntriesRequest
// exceeds this size limit, flush() will be triggered.
int log_request_size_limit_;
// Exporter calls Stackdriver services to export access logs.
std::unique_ptr<Exporter> exporter_;
// GCP project that this proxy runs with.
std::string project_id_;
};
} // namespace Log
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,457 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/stackdriver/log/logger.h"
#include <memory>
#include "extensions/stackdriver/common/constants.h"
#include "extensions/stackdriver/common/utils.h"
#include "gmock/gmock.h"
#include "google/logging/v2/log_entry.pb.h"
#include "google/protobuf/util/json_util.h"
#include "google/protobuf/util/message_differencer.h"
#include "google/protobuf/util/time_util.h"
#include "test/test_common/status_utility.h"
#include "gtest/gtest.h"
namespace Extensions {
namespace Stackdriver {
namespace Log {
using google::protobuf::util::MessageDifferencer;
using google::protobuf::util::TimeUtil;
namespace {
class MockExporter : public Exporter {
public:
MOCK_METHOD2(
exportLogs,
void(const std::vector<std::unique_ptr<const google::logging::v2::WriteLogEntriesRequest>>&,
bool));
};
const ::Wasm::Common::FlatNode& nodeInfo(flatbuffers::FlatBufferBuilder& fbb) {
auto name = fbb.CreateString("test_pod");
auto namespace_ = fbb.CreateString("test_namespace");
auto workload_name = fbb.CreateString("test_workload");
auto mesh_id = fbb.CreateString("mesh");
std::vector<flatbuffers::Offset<::Wasm::Common::KeyVal>> platform_metadata = {
::Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(Common::kGCPProjectKey),
fbb.CreateString("test_project")),
::Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(Common::kGCPClusterNameKey),
fbb.CreateString("test_cluster")),
::Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(Common::kGCPLocationKey),
fbb.CreateString("test_location"))};
auto platform_metadata_offset = fbb.CreateVectorOfSortedTables(&platform_metadata);
::Wasm::Common::FlatNodeBuilder node(fbb);
node.add_name(name);
node.add_namespace_(namespace_);
node.add_workload_name(workload_name);
node.add_mesh_id(mesh_id);
node.add_platform_metadata(platform_metadata_offset);
auto data = node.Finish();
fbb.Finish(data);
return *flatbuffers::GetRoot<::Wasm::Common::FlatNode>(fbb.GetBufferPointer());
}
const ::Wasm::Common::FlatNode& peerNodeInfo(flatbuffers::FlatBufferBuilder& fbb) {
auto name = fbb.CreateString("test_peer_pod");
auto namespace_ = fbb.CreateString("test_peer_namespace");
auto workload_name = fbb.CreateString("test_peer_workload");
std::vector<flatbuffers::Offset<::Wasm::Common::KeyVal>> platform_metadata = {
::Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(Common::kGCPProjectKey),
fbb.CreateString("test_project")),
::Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(Common::kGCPClusterNameKey),
fbb.CreateString("test_cluster")),
::Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(Common::kGCPLocationKey),
fbb.CreateString("test_location"))};
auto platform_metadata_offset = fbb.CreateVectorOfSortedTables(&platform_metadata);
::Wasm::Common::FlatNodeBuilder node(fbb);
node.add_name(name);
node.add_namespace_(namespace_);
node.add_workload_name(workload_name);
node.add_platform_metadata(platform_metadata_offset);
auto data = node.Finish();
fbb.Finish(data);
return *flatbuffers::GetRoot<::Wasm::Common::FlatNode>(fbb.GetBufferPointer());
}
::Wasm::Common::RequestInfo requestInfo(int response_code = 200) {
::Wasm::Common::RequestInfo request_info;
request_info.start_time = 0;
request_info.response_code = response_code;
request_info.request_operation = "GET";
request_info.destination_service_host = "httpbin.org";
request_info.destination_service_name = "httpbin";
request_info.response_flag = "-";
request_info.request_protocol = ::Wasm::Common::Protocol::HTTP;
request_info.destination_principal = "destination_principal";
request_info.source_principal = "source_principal";
request_info.service_auth_policy = ::Wasm::Common::ServiceAuthenticationPolicy::MutualTLS;
request_info.duration = 10000000000; // 10s in nanoseconds
request_info.url_scheme = "http";
request_info.url_host = "httpbin.org";
request_info.url_path = "/headers";
request_info.path = "/headers?retry=true";
request_info.request_id = "123";
request_info.b3_trace_id = "123abc";
request_info.b3_span_id = "abc123";
request_info.b3_trace_sampled = true;
request_info.user_agent = "chrome";
request_info.referer = "www.google.com";
request_info.source_address = "1.1.1.1";
request_info.destination_address = "2.2.2.2";
request_info.connection_id = 0;
request_info.route_name = "redirect";
request_info.upstream_cluster = "server-inbound-cluster";
request_info.upstream_host = "1.1.1.1:1000";
request_info.requested_server_name = "server.com";
request_info.x_envoy_original_dst_host = "tmp.com";
request_info.x_envoy_original_path = "/tmp";
return request_info;
}
std::string write_audit_request_json = R"({
"logName":"projects/test_project/logs/server-istio-audit-log",
"resource":{
"type":"k8s_container",
"labels":{
"cluster_name":"test_cluster",
"pod_name":"test_pod",
"location":"test_location",
"namespace_name":"test_namespace",
"project_id":"test_project",
"container_name":"istio-proxy"
}
},
"labels":{
"destination_workload":"test_workload",
"destination_namespace":"test_namespace"
},
"entries":[
{
"httpRequest":{
"requestMethod":"GET",
"requestUrl":"http://httpbin.org/headers?retry=true",
"userAgent":"chrome",
"remoteIp":"1.1.1.1",
"referer":"www.google.com",
"serverIp":"2.2.2.2",
"latency":"10s",
"protocol":"http",
"status":"200"
},
"timestamp":"1970-01-01T00:00:00Z",
"severity":"INFO",
"labels":{
"destination_principal":"destination_principal",
"destination_service_host":"httpbin.org",
"destination_service_name":"httpbin",
"request_id":"123",
"source_namespace":"test_peer_namespace",
"source_principal":"source_principal",
"source_workload":"test_peer_workload",
},
"trace":"projects/test_project/traces/123abc",
"spanId":"abc123",
"traceSampled":true
}
]
})";
std::string write_log_request_json = R"({
"logName":"projects/test_project/logs/server-accesslog-stackdriver",
"resource":{
"type":"k8s_container",
"labels":{
"cluster_name":"test_cluster",
"pod_name":"test_pod",
"location":"test_location",
"namespace_name":"test_namespace",
"project_id":"test_project",
"container_name":"istio-proxy"
}
},
"labels":{
"destination_workload":"test_workload",
"mesh_uid":"mesh",
"destination_namespace":"test_namespace",
"destination_name":"test_pod"
},
"entries":[
{
"httpRequest":{
"requestMethod":"GET",
"requestUrl":"http://httpbin.org/headers?retry=true",
"userAgent":"chrome",
"remoteIp":"1.1.1.1",
"referer":"www.google.com",
"serverIp":"2.2.2.2",
"latency":"10s",
"protocol":"http",
"status":"200"
},
"timestamp":"1970-01-01T00:00:00Z",
"severity":"INFO",
"labels":{
"source_name":"test_peer_pod",
"destination_principal":"destination_principal",
"destination_service_host":"httpbin.org",
"destination_service_name":"httpbin",
"request_id":"123",
"source_namespace":"test_peer_namespace",
"source_principal":"source_principal",
"service_authentication_policy":"MUTUAL_TLS",
"source_workload":"test_peer_workload",
"response_flag":"-",
"protocol":"http",
"log_sampled":"false",
"connection_id":"0",
"upstream_cluster": "server-inbound-cluster",
"route_name": "redirect",
"requested_server_name": "server.com",
"x-envoy-original-dst-host": "tmp.com",
"x-envoy-original-path": "/tmp",
"upstream_host": "1.1.1.1:1000"
},
"trace":"projects/test_project/traces/123abc",
"spanId":"abc123",
"traceSampled":true
}
]
})";
std::string write_error_log_request_json = R"({
"logName":"projects/test_project/logs/server-accesslog-stackdriver",
"resource":{
"type":"k8s_container",
"labels":{
"cluster_name":"test_cluster",
"pod_name":"test_pod",
"location":"test_location",
"namespace_name":"test_namespace",
"project_id":"test_project",
"container_name":"istio-proxy"
}
},
"labels":{
"destination_workload":"test_workload",
"mesh_uid":"mesh",
"destination_namespace":"test_namespace",
"destination_name":"test_pod"
},
"entries":[
{
"httpRequest":{
"requestMethod":"GET",
"requestUrl":"http://httpbin.org/headers?retry=true",
"userAgent":"chrome",
"remoteIp":"1.1.1.1",
"referer":"www.google.com",
"serverIp":"2.2.2.2",
"latency":"10s",
"protocol":"http",
"status":"404",
},
"timestamp":"1970-01-01T00:00:00Z",
"severity":"ERROR",
"labels":{
"source_name":"test_peer_pod",
"destination_principal":"destination_principal",
"destination_service_host":"httpbin.org",
"destination_service_name":"httpbin",
"request_id":"123",
"source_namespace":"test_peer_namespace",
"source_principal":"source_principal",
"service_authentication_policy":"MUTUAL_TLS",
"source_workload":"test_peer_workload",
"response_flag":"-",
"protocol":"http",
"log_sampled":"false",
"connection_id":"0",
"upstream_cluster": "server-inbound-cluster",
"route_name": "redirect",
"requested_server_name": "server.com",
"x-envoy-original-dst-host": "tmp.com",
"x-envoy-original-path": "/tmp",
"upstream_host": "1.1.1.1:1000"
},
"trace":"projects/test_project/traces/123abc",
"spanId":"abc123",
"traceSampled":true
}
]
})";
google::logging::v2::WriteLogEntriesRequest
expectedRequest(int log_entry_count, bool for_audit = false, bool use_error_log = false) {
google::logging::v2::WriteLogEntriesRequest req;
google::protobuf::util::JsonParseOptions options;
std::string non_audit_log = use_error_log ? write_error_log_request_json : write_log_request_json;
const auto status =
JsonStringToMessage((for_audit ? write_audit_request_json : non_audit_log), &req, options);
EXPECT_OK(status);
for (int i = 1; i < log_entry_count; i++) {
auto* new_entry = req.mutable_entries()->Add();
new_entry->CopyFrom(req.entries()[0]);
}
return req;
}
} // namespace
TEST(LoggerTest, TestWriteLogEntry) {
auto exporter = std::make_unique<::testing::NiceMock<MockExporter>>();
auto exporter_ptr = exporter.get();
flatbuffers::FlatBufferBuilder local, peer;
std::unordered_map<std::string, std::string> extra_labels;
auto logger = std::make_unique<Logger>(nodeInfo(local), std::move(exporter), extra_labels);
logger->addLogEntry(requestInfo(), peerNodeInfo(peer), extra_labels, false, false);
EXPECT_CALL(*exporter_ptr, exportLogs(::testing::_, ::testing::_))
.WillOnce(::testing::Invoke(
[](const std::vector<std::unique_ptr<const google::logging::v2::WriteLogEntriesRequest>>&
requests,
bool) {
for (const auto& req : requests) {
std::string diff;
MessageDifferencer differ;
differ.ReportDifferencesToString(&diff);
if (!differ.Compare(expectedRequest(1), *req)) {
FAIL() << "unexpected log entry " << diff << "\n";
}
}
}));
logger->exportLogEntry(/* is_on_done = */ false);
}
TEST(LoggerTest, TestWriteErrorLogEntry) {
auto exporter = std::make_unique<::testing::NiceMock<MockExporter>>();
auto exporter_ptr = exporter.get();
flatbuffers::FlatBufferBuilder local, peer;
std::unordered_map<std::string, std::string> extra_labels;
auto logger = std::make_unique<Logger>(nodeInfo(local), std::move(exporter), extra_labels);
logger->addLogEntry(requestInfo(404), peerNodeInfo(peer), extra_labels, false, false);
EXPECT_CALL(*exporter_ptr, exportLogs(::testing::_, ::testing::_))
.WillOnce(::testing::Invoke(
[](const std::vector<std::unique_ptr<const google::logging::v2::WriteLogEntriesRequest>>&
requests,
bool) {
for (const auto& req : requests) {
std::string diff;
MessageDifferencer differ;
differ.ReportDifferencesToString(&diff);
if (!differ.Compare(expectedRequest(1, false /* audit log */, true /* error log */),
*req)) {
FAIL() << "unexpected log entry " << diff << "\n";
}
}
}));
logger->exportLogEntry(/* is_on_done = */ false);
}
TEST(LoggerTest, TestWriteLogEntryRotation) {
auto exporter = std::make_unique<::testing::NiceMock<MockExporter>>();
auto exporter_ptr = exporter.get();
flatbuffers::FlatBufferBuilder local, peer;
std::unordered_map<std::string, std::string> extra_labels;
auto logger = std::make_unique<Logger>(nodeInfo(local), std::move(exporter), extra_labels, 1200);
for (int i = 0; i < 10; i++) {
logger->addLogEntry(requestInfo(), peerNodeInfo(peer), extra_labels, false, false);
}
EXPECT_CALL(*exporter_ptr, exportLogs(::testing::_, ::testing::_))
.WillOnce(::testing::Invoke(
[](const std::vector<std::unique_ptr<const google::logging::v2::WriteLogEntriesRequest>>&
requests,
bool) {
EXPECT_EQ(requests.size(), 5);
for (const auto& req : requests) {
std::string diff;
MessageDifferencer differ;
differ.ReportDifferencesToString(&diff);
if (!differ.Compare(expectedRequest(2), *req)) {
FAIL() << "unexpected log entry " << diff << "\n";
}
}
}));
logger->exportLogEntry(/* is_on_done = */ false);
}
TEST(LoggerTest, TestWriteAuditEntry) {
auto exporter = std::make_unique<::testing::NiceMock<MockExporter>>();
auto exporter_ptr = exporter.get();
flatbuffers::FlatBufferBuilder local, peer;
std::unordered_map<std::string, std::string> extra_labels;
auto logger = std::make_unique<Logger>(nodeInfo(local), std::move(exporter), extra_labels);
logger->addLogEntry(requestInfo(), peerNodeInfo(peer), extra_labels, false, true);
EXPECT_CALL(*exporter_ptr, exportLogs(::testing::_, ::testing::_))
.WillOnce(::testing::Invoke(
[](const std::vector<std::unique_ptr<const google::logging::v2::WriteLogEntriesRequest>>&
requests,
bool) {
for (const auto& req : requests) {
std::string diff;
MessageDifferencer differ;
differ.ReportDifferencesToString(&diff);
if (!differ.Compare(expectedRequest(1, true), *req)) {
FAIL() << "unexpected audit entry " << diff << "\n";
}
}
}));
logger->exportLogEntry(/* is_on_done = */ false);
}
TEST(LoggerTest, TestWriteAuditAndLogEntry) {
auto exporter = std::make_unique<::testing::NiceMock<MockExporter>>();
auto exporter_ptr = exporter.get();
flatbuffers::FlatBufferBuilder local, peer;
std::unordered_map<std::string, std::string> extra_labels;
auto logger = std::make_unique<Logger>(nodeInfo(local), std::move(exporter), extra_labels);
for (int i = 0; i < 5; i++) {
logger->addLogEntry(requestInfo(), peerNodeInfo(peer), extra_labels, false, false);
logger->addLogEntry(requestInfo(), peerNodeInfo(peer), extra_labels, false, true);
}
EXPECT_CALL(*exporter_ptr, exportLogs(::testing::_, ::testing::_))
.WillOnce(::testing::Invoke(
[](const std::vector<std::unique_ptr<const google::logging::v2::WriteLogEntriesRequest>>&
requests,
bool) {
bool foundAudit = false;
bool foundLog = false;
std::string diff;
EXPECT_EQ(requests.size(), 2);
for (const auto& req : requests) {
MessageDifferencer differ;
differ.ReportDifferencesToString(&diff);
if (differ.Compare(expectedRequest(5, true), *req)) {
foundAudit = true;
}
if (differ.Compare(expectedRequest(5, false), *req)) {
foundLog = true;
}
}
if (!(foundAudit && foundLog)) {
FAIL() << "unexpected entries, last difference: " << diff << "\n";
}
}));
logger->exportLogEntry(/* is_on_done = */ false);
}
} // namespace Log
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,60 +0,0 @@
# Copyright 2019 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_library",
"envoy_cc_test",
)
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
envoy_cc_library(
name = "metric",
srcs = [
"record.cc",
"registry.cc",
],
hdrs = [
"record.h",
"registry.h",
],
repository = "@envoy",
deps = [
"//extensions/common:context",
"//extensions/stackdriver/common:constants",
"//extensions/stackdriver/common:utils",
"//extensions/stackdriver/config/v1alpha1:stackdriver_plugin_config_cc_proto",
"@io_opencensus_cpp//opencensus/exporters/stats/stackdriver:stackdriver_exporter",
"@io_opencensus_cpp//opencensus/stats",
],
)
envoy_cc_test(
name = "registry_test",
size = "small",
srcs = ["registry_test.cc"],
repository = "@envoy",
deps = [
":metric",
"//extensions/stackdriver/common:constants",
"@com_google_protobuf//:protobuf",
"@envoy//test/test_common:wasm_lib",
],
)

View File

@ -1,478 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/stackdriver/metric/record.h"
#include "extensions/stackdriver/common/constants.h"
#include "extensions/stackdriver/metric/registry.h"
#include "google/protobuf/util/time_util.h"
using google::protobuf::util::TimeUtil;
namespace Extensions {
namespace Stackdriver {
namespace Metric {
namespace {
using Common::unknownIfEmpty;
std::string getLocalCanonicalName(const ::Wasm::Common::FlatNode& local_node_info) {
const auto local_labels = local_node_info.labels();
const auto local_name_iter =
local_labels ? local_labels->LookupByKey(Wasm::Common::kCanonicalServiceLabelName.data())
: nullptr;
const auto local_canonical_name =
local_name_iter ? local_name_iter->value() : local_node_info.workload_name();
return flatbuffers::GetString(local_canonical_name);
}
std::string getLocalCanonicalRev(const ::Wasm::Common::FlatNode& local_node_info) {
const auto local_labels = local_node_info.labels();
const auto local_rev_iter =
local_labels
? local_labels->LookupByKey(Wasm::Common::kCanonicalServiceRevisionLabelName.data())
: nullptr;
const auto local_canonical_rev = local_rev_iter ? local_rev_iter->value() : nullptr;
return local_canonical_rev ? local_canonical_rev->str() : ::Wasm::Common::kLatest.data();
}
std::string getPeerCanonicalName(const ::Wasm::Common::FlatNode& peer_node_info) {
const auto peer_labels = peer_node_info.labels();
const auto peer_name_iter =
peer_labels ? peer_labels->LookupByKey(Wasm::Common::kCanonicalServiceLabelName.data())
: nullptr;
const auto peer_canonical_name =
peer_name_iter ? peer_name_iter->value() : peer_node_info.workload_name();
return flatbuffers::GetString(peer_canonical_name);
}
std::string getPeerCanonicalRev(const ::Wasm::Common::FlatNode& peer_node_info) {
const auto peer_labels = peer_node_info.labels();
const auto peer_rev_iter =
peer_labels
? peer_labels->LookupByKey(Wasm::Common::kCanonicalServiceRevisionLabelName.data())
: nullptr;
const auto peer_canonical_rev = peer_rev_iter ? peer_rev_iter->value() : nullptr;
return peer_canonical_rev ? peer_canonical_rev->str() : ::Wasm::Common::kLatest.data();
}
TagKeyValueList getOutboundTagMap(const ::Wasm::Common::FlatNode& local_node_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const ::Wasm::Common::RequestInfo& request_info) {
TagKeyValueList outboundMap = {
{meshUIDKey(), unknownIfEmpty(flatbuffers::GetString(local_node_info.mesh_id()))},
{requestProtocolKey(),
unknownIfEmpty(std::string(::Wasm::Common::ProtocolString(request_info.request_protocol)))},
{serviceAuthenticationPolicyKey(),
unknownIfEmpty(std::string(
::Wasm::Common::AuthenticationPolicyString(request_info.service_auth_policy)))},
{destinationServiceNameKey(), unknownIfEmpty(request_info.destination_service_name)},
{destinationServiceNamespaceKey(),
unknownIfEmpty(flatbuffers::GetString(peer_node_info.namespace_()))},
{destinationPortKey(), unknownIfEmpty(std::to_string(request_info.destination_port))},
{sourcePrincipalKey(), unknownIfEmpty(request_info.source_principal)},
{sourceWorkloadNameKey(),
unknownIfEmpty(flatbuffers::GetString(local_node_info.workload_name()))},
{sourceWorkloadNamespaceKey(),
unknownIfEmpty(flatbuffers::GetString(local_node_info.namespace_()))},
{sourceOwnerKey(), unknownIfEmpty(Common::getOwner(local_node_info))},
{destinationPrincipalKey(), unknownIfEmpty(request_info.destination_principal)},
{destinationWorkloadNameKey(),
unknownIfEmpty(flatbuffers::GetString(peer_node_info.workload_name()))},
{destinationWorkloadNamespaceKey(),
unknownIfEmpty(flatbuffers::GetString(peer_node_info.namespace_()))},
{destinationOwnerKey(), unknownIfEmpty(Common::getOwner(peer_node_info))},
{destinationCanonicalServiceNameKey(), unknownIfEmpty(getPeerCanonicalName(peer_node_info))},
{destinationCanonicalServiceNamespaceKey(),
unknownIfEmpty(flatbuffers::GetString(peer_node_info.namespace_()))},
{destinationCanonicalRevisionKey(), unknownIfEmpty(getPeerCanonicalRev(peer_node_info))},
{sourceCanonicalServiceNameKey(), unknownIfEmpty(getLocalCanonicalName(local_node_info))},
{sourceCanonicalServiceNamespaceKey(),
unknownIfEmpty(flatbuffers::GetString(local_node_info.namespace_()))},
{sourceCanonicalRevisionKey(), unknownIfEmpty(getLocalCanonicalRev(local_node_info))},
{proxyVersionKey(), unknownIfEmpty(flatbuffers::GetString(local_node_info.istio_version()))}};
return outboundMap;
}
TagKeyValueList getInboundTagMap(const ::Wasm::Common::FlatNode& local_node_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const ::Wasm::Common::RequestInfo& request_info) {
TagKeyValueList inboundMap = {
{meshUIDKey(), unknownIfEmpty(flatbuffers::GetString(local_node_info.mesh_id()))},
{requestProtocolKey(),
unknownIfEmpty(std::string(::Wasm::Common::ProtocolString(request_info.request_protocol)))},
{serviceAuthenticationPolicyKey(),
unknownIfEmpty(std::string(
::Wasm::Common::AuthenticationPolicyString(request_info.service_auth_policy)))},
{destinationServiceNameKey(), unknownIfEmpty(request_info.destination_service_name)},
{destinationServiceNamespaceKey(),
unknownIfEmpty(flatbuffers::GetString(local_node_info.namespace_()))},
{destinationPortKey(), unknownIfEmpty(std::to_string(request_info.destination_port))},
{sourcePrincipalKey(), unknownIfEmpty(request_info.source_principal)},
{sourceWorkloadNameKey(),
unknownIfEmpty(flatbuffers::GetString(peer_node_info.workload_name()))},
{sourceWorkloadNamespaceKey(),
unknownIfEmpty(flatbuffers::GetString(peer_node_info.namespace_()))},
{sourceOwnerKey(), unknownIfEmpty(Common::getOwner(peer_node_info))},
{destinationPrincipalKey(), unknownIfEmpty(request_info.destination_principal)},
{destinationWorkloadNameKey(),
unknownIfEmpty(flatbuffers::GetString(local_node_info.workload_name()))},
{destinationWorkloadNamespaceKey(),
unknownIfEmpty(flatbuffers::GetString(local_node_info.namespace_()))},
{destinationOwnerKey(), unknownIfEmpty(Common::getOwner(local_node_info))},
{destinationCanonicalServiceNameKey(),
unknownIfEmpty(getLocalCanonicalName(local_node_info))},
{destinationCanonicalServiceNamespaceKey(),
unknownIfEmpty(flatbuffers::GetString(local_node_info.namespace_()))},
{destinationCanonicalRevisionKey(), unknownIfEmpty(getLocalCanonicalRev(local_node_info))},
{sourceCanonicalServiceNameKey(), unknownIfEmpty(getPeerCanonicalName(peer_node_info))},
{sourceCanonicalServiceNamespaceKey(),
unknownIfEmpty(flatbuffers::GetString(peer_node_info.namespace_()))},
{sourceCanonicalRevisionKey(), unknownIfEmpty(getPeerCanonicalRev(peer_node_info))},
{proxyVersionKey(), unknownIfEmpty(flatbuffers::GetString(local_node_info.istio_version()))}};
return inboundMap;
}
// See:
// https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
uint32_t httpCodeFromGrpc(uint32_t grpc_status) {
switch (grpc_status) {
case 0: // OK
return 200;
case 1: // CANCELLED
return 499;
case 2: // UNKNOWN
return 500;
case 3: // INVALID_ARGUMENT
return 400;
case 4: // DEADLINE_EXCEEDED
return 504;
case 5: // NOT_FOUND
return 404;
case 6: // ALREADY_EXISTS
return 409;
case 7: // PERMISSION_DENIED
return 403;
case 8: // RESOURCE_EXHAUSTED
return 429;
case 9: // FAILED_PRECONDITION
return 400;
case 10: // ABORTED
return 409;
case 11: // OUT_OF_RANGE
return 400;
case 12: // UNIMPLEMENTED
return 501;
case 13: // INTERNAL
return 500;
case 14: // UNAVAILABLE
return 503;
case 15: // DATA_LOSS
return 500;
case 16: // UNAUTHENTICATED
return 401;
default:
return 500;
}
}
void addHttpSpecificTags(const ::Wasm::Common::RequestInfo& request_info,
TagKeyValueList& tag_map) {
const auto& operation = request_info.request_protocol == ::Wasm::Common::Protocol::GRPC
? request_info.url_path
: request_info.request_operation;
tag_map.emplace_back(Metric::requestOperationKey(), operation);
const auto& response_code = request_info.request_protocol == ::Wasm::Common::Protocol::GRPC
? httpCodeFromGrpc(request_info.grpc_status)
: request_info.response_code;
tag_map.emplace_back(Metric::responseCodeKey(), std::to_string(response_code));
}
TagKeyValueList getMetricTagMap(const TagKeyValueList& input_map,
const TagKeyValueList& tag_overrides) {
if (tag_overrides.empty()) {
return input_map;
}
TagKeyValueList out;
for (const auto& [tag_key, value_list] : input_map) {
const auto& name = tag_key.name();
auto it = std::find_if(tag_overrides.begin(), tag_overrides.end(),
[&name](const auto& override) { return override.first.name() == name; });
if (it != tag_overrides.end()) {
out.emplace_back(tag_key, it->second);
} else {
out.emplace_back(tag_key, value_list);
}
}
auto it = std::find_if(tag_overrides.begin(), tag_overrides.end(), [](const auto& override) {
return override.first.name() == "api_version";
});
if (it != tag_overrides.end()) {
out.emplace_back(apiVersionKey(), it->second);
}
it = std::find_if(tag_overrides.begin(), tag_overrides.end(),
[](const auto& override) { return override.first.name() == "api_name"; });
if (it != tag_overrides.end()) {
out.emplace_back(apiNameKey(), it->second);
}
return out;
}
bool hasOverridesMatching(const override_map& overrides, const std::string& metric) {
if (overrides.empty()) {
return false;
}
auto it = std::find_if(
overrides.begin(), overrides.end(),
[&metric](const override_map_value_type& vt) { return absl::StrContains(vt.first, metric); });
return it != overrides.end();
}
} // namespace
void record(bool is_outbound, const ::Wasm::Common::FlatNode& local_node_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const ::Wasm::Common::RequestInfo& request_info, bool record_http_size_metrics,
const override_map& overrides) {
double latency_ms = request_info.duration /* in nanoseconds */ / 1000000.0;
if (is_outbound) {
TagKeyValueList tagMap = getOutboundTagMap(local_node_info, peer_node_info, request_info);
addHttpSpecificTags(request_info, tagMap);
if (hasOverridesMatching(overrides, "client")) {
auto it = overrides.find(Common::kClientRequestCountView);
if (it == overrides.end()) {
opencensus::stats::Record({{clientRequestCountMeasure(), 1}}, tagMap);
} else {
opencensus::stats::Record({{clientRequestCountMeasure(), 1}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kClientRoundtripLatenciesView);
if (it == overrides.end()) {
opencensus::stats::Record({{clientRoundtripLatenciesMeasure(), latency_ms}}, tagMap);
} else {
opencensus::stats::Record({{clientRoundtripLatenciesMeasure(), latency_ms}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kClientRequestBytesView);
if (it == overrides.end()) {
opencensus::stats::Record({{clientRequestBytesMeasure(), request_info.request_size}},
tagMap);
} else {
opencensus::stats::Record({{clientRequestBytesMeasure(), request_info.request_size}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kClientResponseBytesView);
if (it == overrides.end()) {
opencensus::stats::Record({{clientResponseBytesMeasure(), request_info.response_size}},
tagMap);
} else {
opencensus::stats::Record({{clientResponseBytesMeasure(), request_info.response_size}},
getMetricTagMap(tagMap, it->second));
}
return;
}
if (record_http_size_metrics) {
opencensus::stats::Record({{clientRequestCountMeasure(), 1},
{clientRoundtripLatenciesMeasure(), latency_ms},
{clientRequestBytesMeasure(), request_info.request_size},
{clientResponseBytesMeasure(), request_info.response_size}},
tagMap);
} else {
opencensus::stats::Record(
{{clientRequestCountMeasure(), 1}, {clientRoundtripLatenciesMeasure(), latency_ms}},
tagMap);
}
return;
}
TagKeyValueList tagMap = getInboundTagMap(local_node_info, peer_node_info, request_info);
addHttpSpecificTags(request_info, tagMap);
if (hasOverridesMatching(overrides, "server")) {
auto it = overrides.find(Common::kServerRequestCountView);
if (it == overrides.end()) {
opencensus::stats::Record({{serverRequestCountMeasure(), 1}}, tagMap);
} else {
opencensus::stats::Record({{serverRequestCountMeasure(), 1}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kServerResponseLatenciesView);
if (it == overrides.end()) {
opencensus::stats::Record({{serverResponseLatenciesMeasure(), latency_ms}}, tagMap);
} else {
opencensus::stats::Record({{serverResponseLatenciesMeasure(), latency_ms}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kServerRequestBytesView);
if (it == overrides.end()) {
opencensus::stats::Record({{serverRequestBytesMeasure(), request_info.request_size}}, tagMap);
} else {
opencensus::stats::Record({{serverRequestBytesMeasure(), request_info.request_size}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kServerResponseBytesView);
if (it == overrides.end()) {
opencensus::stats::Record({{serverResponseBytesMeasure(), request_info.response_size}},
tagMap);
} else {
opencensus::stats::Record({{serverResponseBytesMeasure(), request_info.response_size}},
getMetricTagMap(tagMap, it->second));
}
return;
}
if (record_http_size_metrics) {
opencensus::stats::Record({{serverRequestCountMeasure(), 1},
{serverResponseLatenciesMeasure(), latency_ms},
{serverRequestBytesMeasure(), request_info.request_size},
{serverResponseBytesMeasure(), request_info.response_size}},
tagMap);
} else {
opencensus::stats::Record(
{{serverRequestCountMeasure(), 1}, {serverResponseLatenciesMeasure(), latency_ms}}, tagMap);
}
}
void recordTCP(bool is_outbound, const ::Wasm::Common::FlatNode& local_node_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const ::Wasm::Common::RequestInfo& request_info, const override_map& overrides) {
if (is_outbound) {
TagKeyValueList tagMap = getOutboundTagMap(local_node_info, peer_node_info, request_info);
if (hasOverridesMatching(overrides, "client")) {
auto it = overrides.find(Common::kClientConnectionsOpenCountView);
if (it == overrides.end()) {
opencensus::stats::Record(
{{clientConnectionsOpenCountMeasure(), request_info.tcp_connections_opened}}, tagMap);
} else {
opencensus::stats::Record(
{{clientConnectionsOpenCountMeasure(), request_info.tcp_connections_opened}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kClientConnectionsCloseCountView);
if (it == overrides.end()) {
opencensus::stats::Record(
{{clientConnectionsCloseCountMeasure(), request_info.tcp_connections_closed}}, tagMap);
} else {
opencensus::stats::Record(
{{clientConnectionsCloseCountMeasure(), request_info.tcp_connections_closed}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kClientReceivedBytesCountView);
if (it == overrides.end()) {
opencensus::stats::Record(
{{clientReceivedBytesCountMeasure(), request_info.tcp_received_bytes}}, tagMap);
} else {
opencensus::stats::Record(
{{clientReceivedBytesCountMeasure(), request_info.tcp_received_bytes}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kClientSentBytesCountView);
if (it == overrides.end()) {
opencensus::stats::Record({{clientSentBytesCountMeasure(), request_info.tcp_sent_bytes}},
tagMap);
} else {
opencensus::stats::Record({{clientSentBytesCountMeasure(), request_info.tcp_sent_bytes}},
getMetricTagMap(tagMap, it->second));
}
return;
}
opencensus::stats::Record(
{{clientConnectionsOpenCountMeasure(), request_info.tcp_connections_opened},
{clientConnectionsCloseCountMeasure(), request_info.tcp_connections_closed},
{clientReceivedBytesCountMeasure(), request_info.tcp_received_bytes},
{clientSentBytesCountMeasure(), request_info.tcp_sent_bytes}},
tagMap);
return;
}
TagKeyValueList tagMap = getInboundTagMap(local_node_info, peer_node_info, request_info);
if (hasOverridesMatching(overrides, "server")) {
auto it = overrides.find(Common::kServerConnectionsOpenCountView);
if (it == overrides.end()) {
opencensus::stats::Record(
{{serverConnectionsOpenCountMeasure(), request_info.tcp_connections_opened}}, tagMap);
} else {
opencensus::stats::Record(
{{serverConnectionsOpenCountMeasure(), request_info.tcp_connections_opened}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kServerConnectionsCloseCountView);
if (it == overrides.end()) {
opencensus::stats::Record(
{{serverConnectionsCloseCountMeasure(), request_info.tcp_connections_closed}}, tagMap);
} else {
opencensus::stats::Record(
{{serverConnectionsCloseCountMeasure(), request_info.tcp_connections_closed}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kServerReceivedBytesCountView);
if (it == overrides.end()) {
opencensus::stats::Record(
{{serverReceivedBytesCountMeasure(), request_info.tcp_received_bytes}}, tagMap);
} else {
opencensus::stats::Record(
{{serverReceivedBytesCountMeasure(), request_info.tcp_received_bytes}},
getMetricTagMap(tagMap, it->second));
}
it = overrides.find(Common::kServerSentBytesCountView);
if (it == overrides.end()) {
opencensus::stats::Record({{serverSentBytesCountMeasure(), request_info.tcp_sent_bytes}},
tagMap);
} else {
opencensus::stats::Record({{serverSentBytesCountMeasure(), request_info.tcp_sent_bytes}},
getMetricTagMap(tagMap, it->second));
}
return;
}
opencensus::stats::Record(
{{serverConnectionsOpenCountMeasure(), request_info.tcp_connections_opened},
{serverConnectionsCloseCountMeasure(), request_info.tcp_connections_closed},
{serverReceivedBytesCountMeasure(), request_info.tcp_received_bytes},
{serverSentBytesCountMeasure(), request_info.tcp_sent_bytes}},
tagMap);
return;
}
} // namespace Metric
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,45 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "extensions/common/context.h"
#include "extensions/stackdriver/config/v1alpha1/stackdriver_plugin_config.pb.h"
#include "opencensus/stats/tag_key.h"
namespace Extensions {
namespace Stackdriver {
namespace Metric {
typedef std::vector<std::pair<opencensus::tags::TagKey, std::string>> TagKeyValueList;
typedef std::unordered_map<std::string, TagKeyValueList> override_map;
typedef std::unordered_map<std::string, TagKeyValueList>::value_type override_map_value_type;
// Record metrics based on local node info and request info.
// Reporter kind deceides the type of metrics to record.
void record(bool is_outbound, const ::Wasm::Common::FlatNode& local_node_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const ::Wasm::Common::RequestInfo& request_info, bool record_http_size_metrics,
const override_map& overrides);
// Record TCP metrics based on local node info and request info.
// Reporter kind deceides the type of metrics to record.
void recordTCP(bool is_outbound, const ::Wasm::Common::FlatNode& local_node_info,
const ::Wasm::Common::FlatNode& peer_node_info,
const ::Wasm::Common::RequestInfo& request_info, const override_map& overrides);
} // namespace Metric
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,431 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/stackdriver/metric/registry.h"
#include <fstream>
#include <sstream>
#include "extensions/stackdriver/common/constants.h"
#include "google/api/monitored_resource.pb.h"
#include "grpcpp/grpcpp.h"
namespace Extensions {
namespace Stackdriver {
namespace Metric {
namespace {
class GoogleUserProjHeaderInterceptor : public grpc::experimental::Interceptor {
public:
GoogleUserProjHeaderInterceptor(const std::string& project_id) : project_id_(project_id) {}
virtual void Intercept(grpc::experimental::InterceptorBatchMethods* methods) {
if (methods->QueryInterceptionHookPoint(
grpc::experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) {
auto* metadata_map = methods->GetSendInitialMetadata();
if (metadata_map != nullptr) {
metadata_map->insert(std::make_pair("x-goog-user-project", project_id_));
}
}
methods->Proceed();
}
private:
const std::string& project_id_;
};
class GoogleUserProjHeaderInterceptorFactory
: public grpc::experimental::ClientInterceptorFactoryInterface {
public:
GoogleUserProjHeaderInterceptorFactory(const std::string& project_id) : project_id_(project_id) {}
virtual grpc::experimental::Interceptor*
CreateClientInterceptor(grpc::experimental::ClientRpcInfo*) override {
return new GoogleUserProjHeaderInterceptor(project_id_);
}
private:
std::string project_id_;
};
} // namespace
using namespace Extensions::Stackdriver::Common;
using namespace opencensus::exporters::stats;
using namespace opencensus::stats;
// Gets opencensus stackdriver exporter options.
StackdriverOptions
getStackdriverOptions(const Wasm::Common::FlatNode& local_node_info,
const ::Extensions::Stackdriver::Common::StackdriverStubOption& stub_option) {
StackdriverOptions options;
auto platform_metadata = local_node_info.platform_metadata();
if (platform_metadata) {
auto project = platform_metadata->LookupByKey(kGCPProjectKey);
if (project) {
options.project_id = flatbuffers::GetString(project->value());
}
}
auto ssl_creds_options = grpc::SslCredentialsOptions();
if (!stub_option.test_root_pem_path.empty()) {
std::ifstream file(stub_option.test_root_pem_path);
if (!file.fail()) {
std::stringstream file_string;
file_string << file.rdbuf();
ssl_creds_options.pem_root_certs = file_string.str();
}
}
auto channel_creds = grpc::SslCredentials(ssl_creds_options);
if (!stub_option.insecure_endpoint.empty()) {
auto channel =
grpc::CreateChannel(stub_option.insecure_endpoint, grpc::InsecureChannelCredentials());
options.metric_service_stub = google::monitoring::v3::MetricService::NewStub(channel);
} else if (!stub_option.sts_port.empty()) {
::grpc::experimental::StsCredentialsOptions sts_options;
std::string token_path =
stub_option.test_token_path.empty() ? kSTSSubjectTokenPath : stub_option.test_token_path;
::Extensions::Stackdriver::Common::setSTSCallCredentialOptions(
&sts_options, stub_option.sts_port, token_path);
auto call_creds = grpc::experimental::StsCredentials(sts_options);
grpc::ChannelArguments args;
std::vector<std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>> creators;
auto header_factory =
std::make_unique<GoogleUserProjHeaderInterceptorFactory>(options.project_id);
creators.push_back(std::move(header_factory));
// When STS is turned on, first check if secure_endpoint is set or not,
// which indicates whether this is for testing senario. If not set, check
// for monitoring_endpoint override, which indicates a different SD backend
// endpoint, such as staging.
std::string monitoring_endpoint = stub_option.default_endpoint;
if (!stub_option.secure_endpoint.empty()) {
monitoring_endpoint = stub_option.secure_endpoint;
} else if (!stub_option.monitoring_endpoint.empty()) {
monitoring_endpoint = stub_option.monitoring_endpoint;
}
auto channel = ::grpc::experimental::CreateCustomChannelWithInterceptors(
monitoring_endpoint, grpc::CompositeChannelCredentials(channel_creds, call_creds), args,
std::move(creators));
options.metric_service_stub = google::monitoring::v3::MetricService::NewStub(channel);
} else if (!stub_option.secure_endpoint.empty()) {
auto channel = grpc::CreateChannel(stub_option.secure_endpoint, channel_creds);
options.metric_service_stub = google::monitoring::v3::MetricService::NewStub(channel);
} else if (!stub_option.monitoring_endpoint.empty()) {
auto channel =
::grpc::CreateChannel(stub_option.monitoring_endpoint, ::grpc::GoogleDefaultCredentials());
options.metric_service_stub = google::monitoring::v3::MetricService::NewStub(channel);
}
std::string server_type = kContainerMonitoredResource;
std::string client_type = kPodMonitoredResource;
if (!platform_metadata) {
server_type = kGenericNode;
client_type = kGenericNode;
} else if (!platform_metadata->LookupByKey(kGCPClusterNameKey)) {
// if there is no cluster name key, assume it is not on kubernetes
if (platform_metadata->LookupByKey(kGCPGCEInstanceIDKey) ||
platform_metadata->LookupByKey(kGCECreatedByKey.data())) {
// if there is instance ID or createdBy key, assume it is a GCE_INSTANCE
server_type = kGCEInstanceMonitoredResource;
client_type = kGCEInstanceMonitoredResource;
} else {
// absent GCE key info, use Generic Node
server_type = kGenericNode;
client_type = kGenericNode;
}
}
// Get server and client monitored resource.
google::api::MonitoredResource server_monitored_resource;
Common::getMonitoredResource(server_type, local_node_info, &server_monitored_resource);
google::api::MonitoredResource client_monitored_resource;
Common::getMonitoredResource(client_type, local_node_info, &client_monitored_resource);
options.per_metric_monitored_resource[kServerRequestCountView] = server_monitored_resource;
options.per_metric_monitored_resource[kServerRequestBytesView] = server_monitored_resource;
options.per_metric_monitored_resource[kServerResponseBytesView] = server_monitored_resource;
options.per_metric_monitored_resource[kServerResponseLatenciesView] = server_monitored_resource;
options.per_metric_monitored_resource[kServerConnectionsOpenCountView] =
server_monitored_resource;
options.per_metric_monitored_resource[kServerConnectionsCloseCountView] =
server_monitored_resource;
options.per_metric_monitored_resource[kServerReceivedBytesCountView] = server_monitored_resource;
options.per_metric_monitored_resource[kServerSentBytesCountView] = server_monitored_resource;
options.per_metric_monitored_resource[kClientRequestCountView] = client_monitored_resource;
options.per_metric_monitored_resource[kClientRequestBytesView] = client_monitored_resource;
options.per_metric_monitored_resource[kClientResponseBytesView] = client_monitored_resource;
options.per_metric_monitored_resource[kClientRoundtripLatenciesView] = client_monitored_resource;
options.per_metric_monitored_resource[kClientConnectionsOpenCountView] =
client_monitored_resource;
options.per_metric_monitored_resource[kClientConnectionsCloseCountView] =
client_monitored_resource;
options.per_metric_monitored_resource[kClientReceivedBytesCountView] = client_monitored_resource;
options.per_metric_monitored_resource[kClientSentBytesCountView] = client_monitored_resource;
options.metric_name_prefix = kIstioMetricPrefix;
return options;
}
/*
* view function macros
*/
#define REGISTER_COUNT_VIEW(_v) \
void register##_v##View(absl::Duration expiry_duration, \
std::vector<std::string> dropped_metrics) { \
auto iter = std::find(dropped_metrics.begin(), dropped_metrics.end(), k##_v##View); \
if (iter != dropped_metrics.end()) { \
return; \
} \
const ViewDescriptor view_descriptor = ViewDescriptor() \
.set_name(k##_v##View) \
.set_measure(k##_v##Measure) \
.set_expiry_duration(expiry_duration) \
.set_aggregation(Aggregation::Count()) ADD_TAGS; \
View view(view_descriptor); \
view_descriptor.RegisterForExport(); \
}
#define REGISTER_TCP_COUNT_VIEW(_v) \
void register##_v##View(absl::Duration expiry_duration, \
std::vector<std::string> dropped_metrics) { \
auto iter = std::find(dropped_metrics.begin(), dropped_metrics.end(), k##_v##View); \
if (iter != dropped_metrics.end()) { \
return; \
} \
const ViewDescriptor view_descriptor = ViewDescriptor() \
.set_name(k##_v##View) \
.set_measure(k##_v##Measure) \
.set_expiry_duration(expiry_duration) \
.set_aggregation(Aggregation::Count()) \
ADD_COMMON_TAGS; \
View view(view_descriptor); \
view_descriptor.RegisterForExport(); \
}
#define REGISTER_TCP_SUM_VIEW(_v) \
void register##_v##View(absl::Duration expiry_duration, \
std::vector<std::string> dropped_metrics) { \
auto iter = std::find(dropped_metrics.begin(), dropped_metrics.end(), k##_v##View); \
if (iter != dropped_metrics.end()) { \
return; \
} \
const ViewDescriptor view_descriptor = ViewDescriptor() \
.set_name(k##_v##View) \
.set_measure(k##_v##Measure) \
.set_expiry_duration(expiry_duration) \
.set_aggregation(Aggregation::Sum()) \
ADD_COMMON_TAGS; \
View view(view_descriptor); \
view_descriptor.RegisterForExport(); \
}
#define REGISTER_DISTRIBUTION_VIEW(_v) \
void register##_v##View(absl::Duration expiry_duration, \
std::vector<std::string> dropped_metrics) { \
auto iter = std::find(dropped_metrics.begin(), dropped_metrics.end(), k##_v##View); \
if (iter != dropped_metrics.end()) { \
return; \
} \
const ViewDescriptor view_descriptor = \
ViewDescriptor() \
.set_name(k##_v##View) \
.set_measure(k##_v##Measure) \
.set_expiry_duration(expiry_duration) \
.set_aggregation(Aggregation::Distribution(BucketBoundaries::Exponential(20, 1, 2))) \
ADD_TAGS; \
View view(view_descriptor); \
view_descriptor.RegisterForExport(); \
}
#define REGISTER_BYTES_DISTRIBUTION_VIEW(_v) \
void register##_v##View(absl::Duration expiry_duration, \
std::vector<std::string> dropped_metrics) { \
auto iter = std::find(dropped_metrics.begin(), dropped_metrics.end(), k##_v##View); \
if (iter != dropped_metrics.end()) { \
return; \
} \
const ViewDescriptor view_descriptor = \
ViewDescriptor() \
.set_name(k##_v##View) \
.set_measure(k##_v##Measure) \
.set_expiry_duration(expiry_duration) \
.set_aggregation(Aggregation::Distribution(BucketBoundaries::Exponential(7, 1, 10))) \
ADD_TAGS; \
View view(view_descriptor); \
view_descriptor.RegisterForExport(); \
}
#define ADD_TAGS ADD_COMMON_TAGS ADD_HTTP_GRPC_TAGS
#define ADD_HTTP_GRPC_TAGS \
.add_column(requestOperationKey()) \
.add_column(responseCodeKey()) \
.add_column(apiVersionKey()) \
.add_column(apiNameKey())
#define ADD_COMMON_TAGS \
.add_column(requestProtocolKey()) \
.add_column(serviceAuthenticationPolicyKey()) \
.add_column(meshUIDKey()) \
.add_column(destinationServiceNameKey()) \
.add_column(destinationServiceNamespaceKey()) \
.add_column(destinationPortKey()) \
.add_column(sourcePrincipalKey()) \
.add_column(sourceWorkloadNameKey()) \
.add_column(sourceWorkloadNamespaceKey()) \
.add_column(sourceOwnerKey()) \
.add_column(destinationPrincipalKey()) \
.add_column(destinationWorkloadNameKey()) \
.add_column(destinationWorkloadNamespaceKey()) \
.add_column(destinationOwnerKey()) \
.add_column(destinationCanonicalServiceNameKey()) \
.add_column(destinationCanonicalServiceNamespaceKey()) \
.add_column(sourceCanonicalServiceNameKey()) \
.add_column(sourceCanonicalServiceNamespaceKey()) \
.add_column(destinationCanonicalRevisionKey()) \
.add_column(sourceCanonicalRevisionKey()) \
.add_column(proxyVersionKey())
// Functions to register opencensus views to export.
REGISTER_COUNT_VIEW(ServerRequestCount)
REGISTER_BYTES_DISTRIBUTION_VIEW(ServerRequestBytes)
REGISTER_BYTES_DISTRIBUTION_VIEW(ServerResponseBytes)
REGISTER_DISTRIBUTION_VIEW(ServerResponseLatencies)
REGISTER_COUNT_VIEW(ClientRequestCount)
REGISTER_BYTES_DISTRIBUTION_VIEW(ClientRequestBytes)
REGISTER_BYTES_DISTRIBUTION_VIEW(ClientResponseBytes)
REGISTER_DISTRIBUTION_VIEW(ClientRoundtripLatencies)
REGISTER_TCP_COUNT_VIEW(ServerConnectionsOpenCount)
REGISTER_TCP_COUNT_VIEW(ServerConnectionsCloseCount)
REGISTER_TCP_SUM_VIEW(ServerReceivedBytesCount)
REGISTER_TCP_SUM_VIEW(ServerSentBytesCount)
REGISTER_TCP_COUNT_VIEW(ClientConnectionsOpenCount)
REGISTER_TCP_COUNT_VIEW(ClientConnectionsCloseCount)
REGISTER_TCP_SUM_VIEW(ClientReceivedBytesCount)
REGISTER_TCP_SUM_VIEW(ClientSentBytesCount)
/*
* measure function macros
*/
#define MEASURE_FUNC(_fn, _m, _u, _t) \
Measure##_t _fn##Measure() { \
static const Measure##_t measure = Measure##_t::Register(k##_m##Measure, "", #_u); \
return measure; \
}
// Meausre functions
MEASURE_FUNC(serverRequestCount, ServerRequestCount, 1, Int64)
MEASURE_FUNC(serverRequestBytes, ServerRequestBytes, By, Int64)
MEASURE_FUNC(serverResponseBytes, ServerResponseBytes, By, Int64)
MEASURE_FUNC(serverResponseLatencies, ServerResponseLatencies, ms, Double)
MEASURE_FUNC(clientRequestCount, ClientRequestCount, 1, Int64)
MEASURE_FUNC(clientRequestBytes, ClientRequestBytes, By, Int64)
MEASURE_FUNC(clientResponseBytes, ClientResponseBytes, By, Int64)
MEASURE_FUNC(clientRoundtripLatencies, ClientRoundtripLatencies, ms, Double)
MEASURE_FUNC(serverConnectionsOpenCount, ServerConnectionsOpenCount, 1, Int64)
MEASURE_FUNC(serverConnectionsCloseCount, ServerConnectionsCloseCount, 1, Int64)
MEASURE_FUNC(serverReceivedBytesCount, ServerReceivedBytesCount, By, Int64)
MEASURE_FUNC(serverSentBytesCount, ServerSentBytesCount, By, Int64)
MEASURE_FUNC(clientConnectionsOpenCount, ClientConnectionsOpenCount, 1, Int64)
MEASURE_FUNC(clientConnectionsCloseCount, ClientConnectionsCloseCount, 1, Int64)
MEASURE_FUNC(clientReceivedBytesCount, ClientReceivedBytesCount, By, Int64)
MEASURE_FUNC(clientSentBytesCount, ClientSentBytesCount, By, Int64)
void registerViews(absl::Duration expiry_duration,
const std::vector<std::string>& dropped_metrics) {
// Register measure first, which views depend on.
serverRequestCountMeasure();
serverRequestBytesMeasure();
serverResponseBytesMeasure();
serverResponseLatenciesMeasure();
clientRequestCountMeasure();
clientRequestBytesMeasure();
clientResponseBytesMeasure();
clientRoundtripLatenciesMeasure();
serverConnectionsOpenCountMeasure();
serverConnectionsCloseCountMeasure();
serverReceivedBytesCountMeasure();
serverSentBytesCountMeasure();
clientConnectionsOpenCountMeasure();
clientConnectionsCloseCountMeasure();
clientReceivedBytesCountMeasure();
clientSentBytesCountMeasure();
// Register views to export;
registerServerRequestCountView(expiry_duration, dropped_metrics);
registerServerRequestBytesView(expiry_duration, dropped_metrics);
registerServerResponseBytesView(expiry_duration, dropped_metrics);
registerServerResponseLatenciesView(expiry_duration, dropped_metrics);
registerClientRequestCountView(expiry_duration, dropped_metrics);
registerClientRequestBytesView(expiry_duration, dropped_metrics);
registerClientResponseBytesView(expiry_duration, dropped_metrics);
registerClientRoundtripLatenciesView(expiry_duration, dropped_metrics);
registerServerConnectionsOpenCountView(expiry_duration, dropped_metrics);
registerServerConnectionsCloseCountView(expiry_duration, dropped_metrics);
registerServerReceivedBytesCountView(expiry_duration, dropped_metrics);
registerServerSentBytesCountView(expiry_duration, dropped_metrics);
registerClientConnectionsOpenCountView(expiry_duration, dropped_metrics);
registerClientConnectionsCloseCountView(expiry_duration, dropped_metrics);
registerClientReceivedBytesCountView(expiry_duration, dropped_metrics);
registerClientSentBytesCountView(expiry_duration, dropped_metrics);
}
void dropViews(const std::vector<std::string>& dropped_metrics) {
for (const auto& metric : dropped_metrics) {
opencensus::stats::StatsExporter::RemoveView(metric);
}
}
/*
* tag key function macros
*/
#define TAG_KEY_FUNC(_t, _f) \
opencensus::tags::TagKey _f##Key() { \
static const auto _t##_key = opencensus::tags::TagKey::Register(#_t); \
return _t##_key; \
}
// Tag key functions
TAG_KEY_FUNC(response_code, responseCode)
TAG_KEY_FUNC(request_operation, requestOperation)
TAG_KEY_FUNC(request_protocol, requestProtocol)
TAG_KEY_FUNC(service_authentication_policy, serviceAuthenticationPolicy)
TAG_KEY_FUNC(mesh_uid, meshUID)
TAG_KEY_FUNC(destination_service_name, destinationServiceName)
TAG_KEY_FUNC(destination_service_namespace, destinationServiceNamespace)
TAG_KEY_FUNC(destination_port, destinationPort)
TAG_KEY_FUNC(response_code, desponseCode)
TAG_KEY_FUNC(source_principal, sourcePrincipal)
TAG_KEY_FUNC(source_workload_name, sourceWorkloadName)
TAG_KEY_FUNC(source_workload_namespace, sourceWorkloadNamespace)
TAG_KEY_FUNC(source_owner, sourceOwner)
TAG_KEY_FUNC(destination_principal, destinationPrincipal)
TAG_KEY_FUNC(destination_workload_name, destinationWorkloadName)
TAG_KEY_FUNC(destination_workload_namespace, destinationWorkloadNamespace)
TAG_KEY_FUNC(destination_owner, destinationOwner)
TAG_KEY_FUNC(source_canonical_service_name, sourceCanonicalServiceName)
TAG_KEY_FUNC(source_canonical_service_namespace, sourceCanonicalServiceNamespace)
TAG_KEY_FUNC(destination_canonical_service_name, destinationCanonicalServiceName)
TAG_KEY_FUNC(destination_canonical_service_namespace, destinationCanonicalServiceNamespace)
TAG_KEY_FUNC(source_canonical_revision, sourceCanonicalRevision)
TAG_KEY_FUNC(destination_canonical_revision, destinationCanonicalRevision)
TAG_KEY_FUNC(api_name, apiName)
TAG_KEY_FUNC(api_version, apiVersion)
TAG_KEY_FUNC(proxy_version, proxyVersion)
} // namespace Metric
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,93 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "extensions/common/context.h"
#include "extensions/stackdriver/common/utils.h"
// OpenCensus is full of unused parameters in metric_service.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include "opencensus/exporters/stats/stackdriver/stackdriver_exporter.h"
#pragma GCC diagnostic pop
#include "opencensus/stats/measure.h"
#include "opencensus/stats/stats.h"
#include "opencensus/stats/tag_key.h"
namespace Extensions {
namespace Stackdriver {
namespace Metric {
// Returns Stackdriver exporter config option based on node metadata.
opencensus::exporters::stats::StackdriverOptions
getStackdriverOptions(const Wasm::Common::FlatNode& local_node_info,
const ::Extensions::Stackdriver::Common::StackdriverStubOption& stub_option);
// registers Opencensus views
void registerViews(absl::Duration, const std::vector<std::string>&);
// drops existing OC views
void dropViews(const std::vector<std::string>&);
// Opencensus tag key functions.
opencensus::tags::TagKey requestOperationKey();
opencensus::tags::TagKey requestProtocolKey();
opencensus::tags::TagKey serviceAuthenticationPolicyKey();
opencensus::tags::TagKey meshUIDKey();
opencensus::tags::TagKey destinationServiceNameKey();
opencensus::tags::TagKey destinationServiceNamespaceKey();
opencensus::tags::TagKey destinationPortKey();
opencensus::tags::TagKey responseCodeKey();
opencensus::tags::TagKey sourcePrincipalKey();
opencensus::tags::TagKey sourceWorkloadNameKey();
opencensus::tags::TagKey sourceWorkloadNamespaceKey();
opencensus::tags::TagKey sourceOwnerKey();
opencensus::tags::TagKey destinationPrincipalKey();
opencensus::tags::TagKey destinationWorkloadNameKey();
opencensus::tags::TagKey destinationWorkloadNamespaceKey();
opencensus::tags::TagKey destinationOwnerKey();
opencensus::tags::TagKey destinationCanonicalServiceNameKey();
opencensus::tags::TagKey destinationCanonicalServiceNamespaceKey();
opencensus::tags::TagKey sourceCanonicalServiceNameKey();
opencensus::tags::TagKey sourceCanonicalServiceNamespaceKey();
opencensus::tags::TagKey destinationCanonicalRevisionKey();
opencensus::tags::TagKey sourceCanonicalRevisionKey();
opencensus::tags::TagKey apiNameKey();
opencensus::tags::TagKey apiVersionKey();
opencensus::tags::TagKey proxyVersionKey();
// Opencensus measure functions.
opencensus::stats::MeasureInt64 serverRequestCountMeasure();
opencensus::stats::MeasureInt64 serverRequestBytesMeasure();
opencensus::stats::MeasureInt64 serverResponseBytesMeasure();
opencensus::stats::MeasureDouble serverResponseLatenciesMeasure();
opencensus::stats::MeasureInt64 clientRequestCountMeasure();
opencensus::stats::MeasureInt64 clientRequestBytesMeasure();
opencensus::stats::MeasureInt64 clientResponseBytesMeasure();
opencensus::stats::MeasureDouble clientRoundtripLatenciesMeasure();
opencensus::stats::MeasureInt64 serverConnectionsOpenCountMeasure();
opencensus::stats::MeasureInt64 serverConnectionsCloseCountMeasure();
opencensus::stats::MeasureInt64 serverReceivedBytesCountMeasure();
opencensus::stats::MeasureInt64 serverSentBytesCountMeasure();
opencensus::stats::MeasureInt64 clientConnectionsOpenCountMeasure();
opencensus::stats::MeasureInt64 clientConnectionsCloseCountMeasure();
opencensus::stats::MeasureInt64 clientReceivedBytesCountMeasure();
opencensus::stats::MeasureInt64 clientSentBytesCountMeasure();
} // namespace Metric
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,135 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/stackdriver/metric/registry.h"
#include "extensions/stackdriver/common/constants.h"
#include "google/protobuf/util/message_differencer.h"
#include "gtest/gtest.h"
namespace Extensions {
namespace Stackdriver {
namespace Metric {
using google::protobuf::util::MessageDifferencer;
const ::Wasm::Common::FlatNode& nodeInfo(flatbuffers::FlatBufferBuilder& fbb) {
auto name = fbb.CreateString("test_pod");
auto namespace_ = fbb.CreateString("test_namespace");
std::vector<flatbuffers::Offset<::Wasm::Common::KeyVal>> platform_metadata = {
::Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(Common::kGCPProjectKey),
fbb.CreateString("test_project")),
::Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(Common::kGCPClusterNameKey),
fbb.CreateString("test_cluster")),
::Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(Common::kGCPLocationKey),
fbb.CreateString("test_location"))};
auto platform_metadata_offset = fbb.CreateVectorOfSortedTables(&platform_metadata);
::Wasm::Common::FlatNodeBuilder node(fbb);
node.add_name(name);
node.add_namespace_(namespace_);
node.add_platform_metadata(platform_metadata_offset);
auto data = node.Finish();
fbb.Finish(data);
return *flatbuffers::GetRoot<::Wasm::Common::FlatNode>(fbb.GetBufferPointer());
}
const ::Wasm::Common::FlatNode& nodeInfoWithNoPlatform(flatbuffers::FlatBufferBuilder& fbb) {
auto name = fbb.CreateString("test_pod");
auto namespace_ = fbb.CreateString("test_namespace");
::Wasm::Common::FlatNodeBuilder node(fbb);
node.add_name(name);
node.add_namespace_(namespace_);
auto data = node.Finish();
fbb.Finish(data);
return *flatbuffers::GetRoot<::Wasm::Common::FlatNode>(fbb.GetBufferPointer());
}
google::api::MonitoredResource serverMonitoredResource() {
google::api::MonitoredResource monitored_resource;
monitored_resource.set_type(Common::kContainerMonitoredResource);
(*monitored_resource.mutable_labels())[Common::kProjectIDLabel] = "test_project";
(*monitored_resource.mutable_labels())[Common::kLocationLabel] = "test_location";
(*monitored_resource.mutable_labels())[Common::kClusterNameLabel] = "test_cluster";
(*monitored_resource.mutable_labels())[Common::kNamespaceNameLabel] = "test_namespace";
(*monitored_resource.mutable_labels())[Common::kPodNameLabel] = "test_pod";
(*monitored_resource.mutable_labels())[Common::kContainerNameLabel] = "istio-proxy";
return monitored_resource;
}
google::api::MonitoredResource clientMonitoredResource() {
google::api::MonitoredResource monitored_resource;
monitored_resource.set_type(Common::kPodMonitoredResource);
(*monitored_resource.mutable_labels())[Common::kProjectIDLabel] = "test_project";
(*monitored_resource.mutable_labels())[Common::kLocationLabel] = "test_location";
(*monitored_resource.mutable_labels())[Common::kClusterNameLabel] = "test_cluster";
(*monitored_resource.mutable_labels())[Common::kNamespaceNameLabel] = "test_namespace";
(*monitored_resource.mutable_labels())[Common::kPodNameLabel] = "test_pod";
return monitored_resource;
}
TEST(RegistryTest, getStackdriverOptionsProjectID) {
flatbuffers::FlatBufferBuilder fbb;
const auto& node_info = nodeInfo(fbb);
::Extensions::Stackdriver::Common::StackdriverStubOption stub_option;
auto options = getStackdriverOptions(node_info, stub_option);
EXPECT_EQ(options.project_id, "test_project");
}
TEST(RegistryTest, getStackdriverOptionsNoProjectID) {
flatbuffers::FlatBufferBuilder fbb;
const auto& node_info = nodeInfoWithNoPlatform(fbb);
::Extensions::Stackdriver::Common::StackdriverStubOption stub_option;
auto options = getStackdriverOptions(node_info, stub_option);
EXPECT_EQ(options.project_id, "");
}
TEST(RegistryTest, getStackdriverOptionsMonitoredResource) {
flatbuffers::FlatBufferBuilder fbb;
const auto& node_info = nodeInfo(fbb);
auto expected_server_monitored_resource = serverMonitoredResource();
auto expected_client_monitored_resource = clientMonitoredResource();
::Extensions::Stackdriver::Common::StackdriverStubOption stub_option;
auto options = getStackdriverOptions(node_info, stub_option);
EXPECT_EQ(options.project_id, "test_project");
EXPECT_TRUE(MessageDifferencer::Equals(
options.per_metric_monitored_resource.at(Common::kServerRequestCountView),
expected_server_monitored_resource));
EXPECT_TRUE(MessageDifferencer::Equals(
options.per_metric_monitored_resource.at(Common::kServerRequestBytesView),
expected_server_monitored_resource));
EXPECT_TRUE(MessageDifferencer::Equals(
options.per_metric_monitored_resource.at(Common::kServerResponseLatenciesView),
expected_server_monitored_resource));
EXPECT_TRUE(MessageDifferencer::Equals(
options.per_metric_monitored_resource.at(Common::kServerResponseBytesView),
expected_server_monitored_resource));
EXPECT_TRUE(MessageDifferencer::Equals(
options.per_metric_monitored_resource.at(Common::kClientRequestCountView),
expected_client_monitored_resource));
EXPECT_TRUE(MessageDifferencer::Equals(
options.per_metric_monitored_resource.at(Common::kClientRequestBytesView),
expected_client_monitored_resource));
EXPECT_TRUE(MessageDifferencer::Equals(
options.per_metric_monitored_resource.at(Common::kClientResponseBytesView),
expected_client_monitored_resource));
EXPECT_TRUE(MessageDifferencer::Equals(
options.per_metric_monitored_resource.at(Common::kClientRoundtripLatenciesView),
expected_client_monitored_resource));
}
} // namespace Metric
} // namespace Stackdriver
} // namespace Extensions

View File

@ -1,842 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extensions/stackdriver/stackdriver.h"
#include <google/protobuf/util/json_util.h>
#include <random>
#include <string>
#include <unordered_map>
#include "extensions/common/proto_util.h"
#include "extensions/common/util.h"
#include "extensions/stackdriver/log/exporter.h"
#include "extensions/stackdriver/metric/registry.h"
#include "google/protobuf/util/time_util.h"
#ifndef NULL_PLUGIN
#include "api/wasm/cpp/proxy_wasm_intrinsics.h"
#else
#include "include/proxy-wasm/null_plugin.h"
namespace proxy_wasm {
namespace null_plugin {
#endif
#include "contrib/proxy_expr.h"
namespace Stackdriver {
using namespace opencensus::exporters::stats;
using namespace google::protobuf::util;
using namespace ::Extensions::Stackdriver::Common;
using namespace ::Extensions::Stackdriver::Metric;
using Extensions::Stackdriver::Log::ExporterImpl;
using ::Extensions::Stackdriver::Log::Logger;
using stackdriver::config::v1alpha1::PluginConfig;
using ::Wasm::Common::kDownstreamMetadataIdKey;
using ::Wasm::Common::kDownstreamMetadataKey;
using ::Wasm::Common::kUpstreamMetadataIdKey;
using ::Wasm::Common::kUpstreamMetadataKey;
using ::Wasm::Common::RequestInfo;
using ::Wasm::Common::TCPConnectionState;
constexpr char kStackdriverExporter[] = "stackdriver_exporter";
constexpr char kExporterRegistered[] = "registered";
constexpr int kDefaultTickerMilliseconds = 10000; // 10s
namespace {
constexpr char kRbacAccessAllowed[] = "AuthzAllowed";
constexpr char kRbacAccessDenied[] = "AuthzDenied";
constexpr char kRBACHttpFilterName[] = "envoy.filters.http.rbac";
constexpr char kRBACNetworkFilterName[] = "envoy.filters.network.rbac";
constexpr char kDryRunDenyShadowEngineResult[] = "istio_dry_run_deny_shadow_engine_result";
constexpr char kDryRunAllowShadowEngineResult[] = "istio_dry_run_allow_shadow_engine_result";
constexpr char kDryRunDenyShadowEffectiveId[] = "istio_dry_run_deny_shadow_effective_policy_id";
constexpr char kDryRunAllowShadowEffectiveId[] = "istio_dry_run_allow_shadow_effective_policy_id";
// Get metric export interval from node metadata. Returns 60 seconds if interval
// is not found in metadata.
int getMonitoringExportInterval() {
std::string interval_s = "";
if (getValue({"node", "metadata", kMonitoringExportIntervalKey}, &interval_s)) {
return std::stoi(interval_s);
}
return 60;
}
// Get proxy timer interval from node metadata in milliseconds. Returns 10
// seconds if interval is not found in metadata.
int getProxyTickerIntervalMilliseconds() {
std::string interval_s = "";
if (getValue({"node", "metadata", kProxyTickerIntervalKey}, &interval_s)) {
return std::stoi(interval_s) * 1000;
}
return kDefaultTickerMilliseconds;
}
// Get logging export interval from node metadata in nanoseconds. Returns 60
// seconds if interval is not found in metadata.
long int getTcpLogEntryTimeoutNanoseconds() {
std::string interval_s = "";
if (getValue({"node", "metadata", kTcpLogEntryTimeoutKey}, &interval_s)) {
return std::stoi(interval_s) * 1000000000;
}
return kDefaultTcpLogEntryTimeoutNanoseconds;
}
// Get port of security token exchange server from node metadata, if not
// provided or "0" is provided, emtpy will be returned.
std::string getSTSPort() {
std::string sts_port;
if (getValue({"node", "metadata", kSTSPortKey}, &sts_port) && sts_port != "0") {
return sts_port;
}
return "";
}
// Get file name for the token test override.
std::string getTokenFile() {
std::string token_file;
if (!getValue({"node", "metadata", kTokenFile}, &token_file)) {
return "";
}
return token_file;
}
// Get file name for the root CA PEM file test override.
std::string getCACertFile() {
std::string ca_cert_file;
if (!getValue({"node", "metadata", kCACertFile}, &ca_cert_file)) {
return "";
}
return ca_cert_file;
}
// Get secure stackdriver endpoint for e2e testing.
std::string getSecureEndpoint() {
std::string secure_endpoint;
if (!getValue({"node", "metadata", kSecureStackdriverEndpointKey}, &secure_endpoint)) {
return "";
}
return secure_endpoint;
}
// Get insecure stackdriver endpoint for e2e testing.
std::string getInsecureEndpoint() {
std::string insecure_endpoint;
if (!getValue({"node", "metadata", kInsecureStackdriverEndpointKey}, &insecure_endpoint)) {
return "";
}
return insecure_endpoint;
}
// Get GCP monitoring endpoint. When this is provided, it will override the
// default production endpoint. This should be used to test staging monitoring
// endpoint.
std::string getMonitoringEndpoint() {
std::string monitoring_endpoint;
if (!getValue({"node", "metadata", kMonitoringEndpointKey}, &monitoring_endpoint)) {
return "";
}
return monitoring_endpoint;
}
// Get GCP project number.
std::string getProjectNumber() {
std::string project_number;
if (!getValue({"node", "metadata", "PLATFORM_METADATA", kGCPProjectNumberKey}, &project_number)) {
return "";
}
return project_number;
}
absl::Duration getMetricExpiryDuration(const stackdriver::config::v1alpha1::PluginConfig& config) {
if (!config.has_metric_expiry_duration()) {
return absl::ZeroDuration();
}
auto& duration = config.metric_expiry_duration();
return absl::Seconds(duration.seconds()) + absl::Nanoseconds(duration.nanos());
}
std::vector<std::string>
getDroppedMetrics(const stackdriver::config::v1alpha1::PluginConfig& config) {
std::vector<std::string> dropped_metrics;
for (const auto& override : config.metrics_overrides()) {
if (override.second.drop()) {
dropped_metrics.push_back(override.first);
}
}
return dropped_metrics;
}
bool isAllowedOverride(std::string metric, std::string tag) {
for (const auto& label : kDefinedLabels) {
if (label == tag) {
return true;
}
}
if (absl::StrContains(metric, "connection_") || absl::StrContains(metric, "bytes_count")) {
// short-circuit for TCP metrics
return false;
}
for (const auto& label : kHttpDefinedLabels) {
if (label == tag) {
return true;
}
}
return false;
}
void clearTcpMetrics(::Wasm::Common::RequestInfo& request_info) {
request_info.tcp_connections_opened = 0;
request_info.tcp_sent_bytes = 0;
request_info.tcp_received_bytes = 0;
}
// Get local node metadata. If mesh id is not filled or does not exist,
// fall back to default format `proj-<project-number>`.
flatbuffers::DetachedBuffer getLocalNodeMetadata() {
google::protobuf::Struct node;
auto local_node_info = ::Wasm::Common::extractLocalNodeFlatBuffer();
::Wasm::Common::extractStructFromNodeFlatBuffer(
*flatbuffers::GetRoot<::Wasm::Common::FlatNode>(local_node_info.data()), &node);
const auto mesh_id_it = node.fields().find("MESH_ID");
if (mesh_id_it != node.fields().end() && !mesh_id_it->second.string_value().empty() &&
absl::StartsWith(mesh_id_it->second.string_value(), "proj-")) {
// do nothing
} else {
// Insert or update mesh id to default format as it is missing, empty, or
// not properly set.
auto project_number = getProjectNumber();
auto* mesh_id_field = (*node.mutable_fields())["MESH_ID"].mutable_string_value();
if (!project_number.empty()) {
*mesh_id_field = absl::StrCat("proj-", project_number);
}
}
return ::Wasm::Common::extractNodeFlatBufferFromStruct(node);
}
bool extractAuthzPolicyName(const std::string& policy, std::string& out_namespace,
std::string& out_name, std::string& out_rule) {
// The policy has format "ns[foo]-policy[httpbin-deny]-rule[0]".
if (absl::StartsWith(policy, "ns[") && absl::EndsWith(policy, "]")) {
std::string sepPolicy = "]-policy[";
std::size_t beginNs = 3;
std::size_t endNs = policy.find(sepPolicy, beginNs);
if (endNs == std::string::npos) {
return false;
}
std::string sepNs = "]-rule[";
std::size_t beginName = endNs + sepPolicy.size();
std::size_t endName = policy.find(sepNs, beginName);
if (endName == std::string::npos) {
return false;
}
std::size_t beginRule = endName + sepNs.size();
std::size_t endRule = policy.size() - 1;
out_namespace = policy.substr(beginNs, endNs - beginNs);
out_name = policy.substr(beginName, endName - beginName);
out_rule = policy.substr(beginRule, endRule - beginRule);
return true;
}
return false;
}
void fillAuthzDryRunInfo(std::unordered_map<std::string, std::string>& extra_labels) {
auto md = getProperty({"metadata", "filter_metadata", kRBACHttpFilterName});
if (!md.has_value()) {
md = getProperty({"metadata", "filter_metadata", kRBACNetworkFilterName});
if (!md.has_value()) {
LOG_DEBUG("RBAC metadata not found");
return;
}
}
bool shadow_deny_result = true;
bool shadow_allow_result = true;
bool has_shadow_metadata = false;
std::string shadow_deny_policy = "";
std::string shadow_allow_policy = "";
for (const auto& [key, val] : md.value()->pairs()) {
LOG_DEBUG(absl::StrCat("RBAC metadata found: key=", Wasm::Common::toAbslStringView(key),
", value=", Wasm::Common::toAbslStringView(val)));
if (key == kDryRunDenyShadowEngineResult) {
shadow_deny_result = (val == "allowed");
} else if (key == kDryRunAllowShadowEngineResult) {
shadow_allow_result = (val == "allowed");
} else if (key == kDryRunDenyShadowEffectiveId) {
shadow_deny_policy = val;
} else if (key == kDryRunAllowShadowEffectiveId) {
shadow_allow_policy = val;
} else {
continue;
}
has_shadow_metadata = true;
}
if (!has_shadow_metadata) {
LOG_DEBUG("RBAC dry-run metadata not found");
return;
}
bool shadow_result = false;
std::string shadow_effective_policy = "";
if (shadow_deny_result && shadow_allow_result) {
// If allowed by both DENY and ALLOW policy, the final shadow_result should
// be true (allow) and the shadow_effective_policy should be from the ALLOW
// policy.
shadow_result = true;
shadow_effective_policy = shadow_allow_policy;
LOG_DEBUG("RBAC dry-run result: allowed");
} else {
// If denied by either DENY or ALLOW policy, the final shadow_reulst should
// be false (denied).
shadow_result = false;
if (!shadow_deny_result) {
// If denied by DENY policy, the shadow_effective_policy should be from
// the DENY policy.
shadow_effective_policy = shadow_deny_policy;
LOG_DEBUG("RBAC dry-run result: denied by DENY policy");
} else {
// If denied by ALLOW policy, the shadow_effective_policy shold be from
// the ALLOW policy.
shadow_effective_policy = shadow_allow_policy;
LOG_DEBUG("RBAC dry-run result: denied by ALLOW policy");
}
}
extra_labels["dry_run_result"] = shadow_result ? kRbacAccessAllowed : kRbacAccessDenied;
std::string policy_namespace = "";
std::string policy_name = "";
std::string policy_rule = "";
if (extractAuthzPolicyName(shadow_effective_policy, policy_namespace, policy_name, policy_rule)) {
extra_labels["dry_run_policy_name"] = absl::StrCat(policy_namespace, ".", policy_name);
extra_labels["dry_run_policy_rule"] = policy_rule;
LOG_DEBUG(absl::StrCat("RBAC dry-run matched policy: ns=", policy_namespace,
", name=", policy_name, ", rule=", policy_rule));
}
}
} // namespace
// onConfigure == false makes the proxy crash.
// Only policy plugins should return false.
bool StackdriverRootContext::onConfigure(size_t size) {
initialized_ = configure(size);
return true;
}
bool StackdriverRootContext::initializeLogFilter() {
uint32_t token = 0;
if (config_.access_logging_filter_expression() == "") {
log_filter_token_ = token;
return true;
}
if (createExpression(config_.access_logging_filter_expression(), &token) != WasmResult::Ok) {
LOG_TRACE(absl::StrCat("cannot create an filter expression: " +
config_.access_logging_filter_expression()));
return false;
}
log_filter_token_ = token;
return true;
}
bool StackdriverRootContext::configure(size_t configuration_size) {
// onStart is called prior to onConfigure
int proxy_tick_ms = getProxyTickerIntervalMilliseconds();
proxy_set_tick_period_milliseconds(getProxyTickerIntervalMilliseconds());
// Parse configuration JSON string.
std::string configuration = "{}";
if (configuration_size > 0) {
auto configuration_data =
getBufferBytes(WasmBufferType::PluginConfiguration, 0, configuration_size);
configuration = configuration_data->toString();
}
// TODO: add config validation to reject the listener if project id is not in
// metadata. Parse configuration JSON string.
JsonParseOptions json_options;
json_options.ignore_unknown_fields = true;
const auto status = JsonStringToMessage(configuration, &config_, json_options);
if (!status.ok()) {
logWarn("Cannot parse Stackdriver plugin configuration JSON string " + configuration + ", " +
std::string(status.message()));
return false;
}
local_node_info_ = getLocalNodeMetadata();
if (config_.has_log_report_duration()) {
log_report_duration_nanos_ =
::google::protobuf::util::TimeUtil::DurationToNanoseconds(config_.log_report_duration());
long int proxy_tick_ns = proxy_tick_ms * 1000;
if (log_report_duration_nanos_ < (proxy_tick_ns) ||
log_report_duration_nanos_ % proxy_tick_ns != 0) {
logWarn(absl::StrCat("The duration set is less than or not a multiple of default timer's "
"period. Default Timer MS: ",
proxy_tick_ms,
" Lod Duration Nanosecond: ", log_report_duration_nanos_));
}
}
direction_ = ::Wasm::Common::getTrafficDirection();
use_host_header_fallback_ = !config_.disable_host_header_fallback();
const ::Wasm::Common::FlatNode& local_node =
*flatbuffers::GetRoot<::Wasm::Common::FlatNode>(local_node_info_.data());
// Common stackdriver stub option for logging and monitoring.
::Extensions::Stackdriver::Common::StackdriverStubOption stub_option;
stub_option.sts_port = getSTSPort();
stub_option.test_token_path = getTokenFile();
stub_option.test_root_pem_path = getCACertFile();
stub_option.secure_endpoint = getSecureEndpoint();
stub_option.insecure_endpoint = getInsecureEndpoint();
stub_option.monitoring_endpoint = getMonitoringEndpoint();
stub_option.enable_log_compression =
config_.has_enable_log_compression() && config_.enable_log_compression().value();
const auto platform_metadata = local_node.platform_metadata();
if (platform_metadata) {
const auto project_iter = platform_metadata->LookupByKey(kGCPProjectKey);
if (project_iter) {
stub_option.project_id = flatbuffers::GetString(project_iter->value());
}
}
if (enableAccessLog()) {
std::unordered_map<std::string, std::string> extra_labels;
cleanupExpressions();
cleanupLogFilter();
if (!initializeLogFilter()) {
LOG_WARN("Could not build filter expression for logging.");
}
if (config_.has_custom_log_config()) {
for (const auto& dimension : config_.custom_log_config().dimensions()) {
uint32_t token;
if (createExpression(dimension.second, &token) != WasmResult::Ok) {
LOG_TRACE(absl::StrCat("Could not create expression for ", dimension.second));
continue;
}
expressions_.push_back({token, dimension.first, dimension.second});
}
}
// logger should only be initiated once, for now there is no reason to
// recreate logger because of config update.
if (!logger_) {
auto logging_stub_option = stub_option;
logging_stub_option.default_endpoint = kLoggingService;
auto exporter = std::make_unique<ExporterImpl>(this, logging_stub_option);
// logger takes ownership of exporter.
if (config_.max_log_batch_size_in_bytes() > 0) {
logger_ = std::make_unique<Logger>(local_node, std::move(exporter), extra_labels,
config_.max_log_batch_size_in_bytes());
} else {
logger_ = std::make_unique<Logger>(local_node, std::move(exporter), extra_labels);
}
}
tcp_log_entry_timeout_ = getTcpLogEntryTimeoutNanoseconds();
}
// Extract metric tags expressions
cleanupMetricsExpressions();
for (const auto& override : config_.metrics_overrides()) {
for (const auto& tag : override.second.tag_overrides()) {
if (!isAllowedOverride(override.first, tag.first)) {
LOG_WARN(absl::StrCat("cannot use tag \"", tag.first, "\" in metric \"", override.first,
"\"; ignoring override"));
continue;
}
uint32_t token;
if (createExpression(tag.second, &token) != WasmResult::Ok) {
LOG_WARN(absl::StrCat("Could not create expression: \"", tag.second, "\" for tag \"",
tag.first, "\" on metric \"", override.first,
"\"; ignoring override"));
continue;
}
const auto& tag_key = ::opencensus::tags::TagKey::Register(tag.first);
metrics_expressions_.push_back({token, override.first, tag_key, tag.second});
}
}
// Register OC Stackdriver exporter and views to be exported.
// Note exporter and views are global singleton so they should only be
// registered once.
WasmDataPtr registered;
if (WasmResult::Ok == getSharedData(kStackdriverExporter, &registered)) {
return true;
}
setSharedData(kStackdriverExporter, kExporterRegistered);
auto monitoring_stub_option = stub_option;
monitoring_stub_option.default_endpoint = kMonitoringService;
opencensus::exporters::stats::StackdriverExporter::Register(
getStackdriverOptions(local_node, monitoring_stub_option));
opencensus::stats::StatsExporter::SetInterval(absl::Seconds(getMonitoringExportInterval()));
// Register opencensus measures and views.
auto dropped = getDroppedMetrics(config_);
dropViews(dropped);
registerViews(getMetricExpiryDuration(config_), dropped);
return true;
}
bool StackdriverRootContext::onStart(size_t) { return true; }
void StackdriverRootContext::onTick() {
auto cur = static_cast<long int>(getCurrentTimeNanoseconds());
for (auto const& item : tcp_request_queue_) {
// requestinfo is null, so continue.
if (item.second == nullptr) {
continue;
}
Context* context = getContext(item.first);
if (context == nullptr) {
continue;
}
context->setEffectiveContext();
if (recordTCP(item.first)) {
// Clear existing data in TCP metrics, so that we don't double count the
// metrics.
clearTcpMetrics(*(item.second->request_info));
}
}
if (enableAccessLog() && (cur - last_log_report_call_nanos_ > log_report_duration_nanos_)) {
logger_->exportLogEntry(/* is_on_done= */ false);
last_log_report_call_nanos_ = cur;
}
}
bool StackdriverRootContext::onDone() {
bool done = true;
// Check if logger is empty. In base Wasm VM, only onStart and onDone are
// called, but onConfigure is not triggered. onConfigure is only triggered in
// thread local VM, which makes it possible that logger_ is empty ptr even
// when logging is enabled.
if (logger_ && enableAccessLog() && logger_->exportLogEntry(/* is_on_done= */ true)) {
done = false;
}
for (auto const& item : tcp_request_queue_) {
// requestinfo is null, so continue.
if (item.second == nullptr) {
continue;
}
recordTCP(item.first);
}
tcp_request_queue_.clear();
cleanupExpressions();
cleanupMetricsExpressions();
cleanupLogFilter();
return done;
}
void StackdriverRootContext::record() {
const bool outbound = isOutbound();
Wasm::Common::PeerNodeInfo peer_node_info(
{outbound ? kUpstreamMetadataIdKey : kDownstreamMetadataIdKey},
{outbound ? kUpstreamMetadataKey : kDownstreamMetadataKey});
const ::Wasm::Common::FlatNode& local_node = getLocalNode();
::Wasm::Common::RequestInfo request_info;
::Wasm::Common::populateHTTPRequestInfo(outbound, useHostHeaderFallback(), &request_info);
override_map overrides;
evaluateMetricsExpressions(overrides);
::Extensions::Stackdriver::Metric::record(outbound, local_node, peer_node_info.get(),
request_info, !config_.disable_http_size_metrics(),
overrides);
bool extended_info_populated = false;
if ((enableAllAccessLog() ||
(enableAccessLogOnError() && (request_info.response_code >= 400 ||
request_info.response_flag != ::Wasm::Common::NONE))) &&
shouldLogThisRequest(request_info) && evaluateLogFilter()) {
::Wasm::Common::populateExtendedHTTPRequestInfo(&request_info);
std::unordered_map<std::string, std::string> extra_labels;
evaluateExpressions(extra_labels);
extended_info_populated = true;
fillAuthzDryRunInfo(extra_labels);
logger_->addLogEntry(request_info, peer_node_info.get(), extra_labels, outbound,
false /* audit */);
}
// TODO(dougreid): should Audits override log filters? I believe so. At this
// time, we won't apply logging filters to audit logs.
if (enableAuditLog() && shouldAuditThisRequest()) {
if (!extended_info_populated) {
::Wasm::Common::populateExtendedHTTPRequestInfo(&request_info);
}
logger_->addLogEntry(request_info, peer_node_info.get(), {}, outbound, true /* audit */);
}
}
bool StackdriverRootContext::recordTCP(uint32_t id) {
const bool outbound = isOutbound();
Wasm::Common::PeerNodeInfo peer_node_info(
{outbound ? kUpstreamMetadataIdKey : kDownstreamMetadataIdKey},
{outbound ? kUpstreamMetadataKey : kDownstreamMetadataKey});
const ::Wasm::Common::FlatNode& local_node = getLocalNode();
auto req_iter = tcp_request_queue_.find(id);
if (req_iter == tcp_request_queue_.end() || req_iter->second == nullptr) {
return false;
}
StackdriverRootContext::TcpRecordInfo& record_info = *(req_iter->second);
::Wasm::Common::RequestInfo& request_info = *(record_info.request_info);
// For TCP, if peer metadata is not available, peer id is set as not found.
// Otherwise, we wait for metadata exchange to happen before we report any
// metric before a timeout.
// We keep waiting if response flags is zero, as that implies, there has
// been no error in connection.
uint64_t response_flags = 0;
getValue({"response", "flags"}, &response_flags);
auto cur = static_cast<long int>(proxy_wasm::null_plugin::getCurrentTimeNanoseconds());
bool waiting_for_metadata = peer_node_info.maybeWaiting();
bool no_error = response_flags == 0;
bool log_open_on_timeout = !record_info.tcp_open_entry_logged &&
(cur - request_info.start_time) > tcp_log_entry_timeout_;
if (waiting_for_metadata && no_error && !log_open_on_timeout) {
return false;
}
if (!request_info.is_populated) {
::Wasm::Common::populateTCPRequestInfo(outbound, &request_info);
}
// Record TCP Metrics.
override_map overrides;
evaluateMetricsExpressions(overrides);
::Extensions::Stackdriver::Metric::recordTCP(outbound, local_node, peer_node_info.get(),
request_info, overrides);
bool extended_info_populated = false;
// Add LogEntry to Logger. Log Entries are batched and sent on timer
// to Stackdriver Logging Service.
if (!record_info.log_filter_evaluated) {
record_info.log_connection = evaluateLogFilter();
record_info.log_filter_evaluated = true;
}
if ((enableAllAccessLog() || (enableAccessLogOnError() && !no_error)) &&
record_info.log_connection) {
::Wasm::Common::populateExtendedRequestInfo(&request_info);
extended_info_populated = true;
if (!record_info.expressions_evaluated) {
evaluateExpressions(record_info.extra_log_labels);
record_info.expressions_evaluated = true;
}
fillAuthzDryRunInfo(record_info.extra_log_labels);
// It's possible that for a short lived TCP connection, we log TCP
// Connection Open log entry on connection close.
if (!record_info.tcp_open_entry_logged &&
request_info.tcp_connection_state == ::Wasm::Common::TCPConnectionState::Close) {
record_info.request_info->tcp_connection_state = ::Wasm::Common::TCPConnectionState::Open;
logger_->addTcpLogEntry(*record_info.request_info, peer_node_info.get(),
record_info.extra_log_labels, record_info.request_info->start_time,
outbound, false /* audit */);
record_info.request_info->tcp_connection_state = ::Wasm::Common::TCPConnectionState::Close;
}
logger_->addTcpLogEntry(request_info, peer_node_info.get(), record_info.extra_log_labels,
getCurrentTimeNanoseconds(), outbound, false /* audit */);
}
// TODO(dougreid): confirm that audit should override filtering.
if (enableAuditLog() && shouldAuditThisRequest()) {
if (!extended_info_populated) {
::Wasm::Common::populateExtendedRequestInfo(&request_info);
}
// It's possible that for a short lived TCP connection, we audit log TCP
// Connection Open log entry on connection close.
if (!record_info.tcp_open_entry_logged &&
request_info.tcp_connection_state == ::Wasm::Common::TCPConnectionState::Close) {
record_info.request_info->tcp_connection_state = ::Wasm::Common::TCPConnectionState::Open;
logger_->addTcpLogEntry(*record_info.request_info, peer_node_info.get(), {},
record_info.request_info->start_time, outbound, true /* audit */);
record_info.request_info->tcp_connection_state = ::Wasm::Common::TCPConnectionState::Close;
}
logger_->addTcpLogEntry(*record_info.request_info, peer_node_info.get(), {},
record_info.request_info->start_time, outbound, true /* audit */);
}
if (log_open_on_timeout) {
// If we logged the request on timeout, for outbound requests, we try to
// populate the request info again when metadata is available.
request_info.is_populated = outbound ? false : true;
}
if (!record_info.tcp_open_entry_logged) {
record_info.tcp_open_entry_logged = true;
}
return true;
}
inline bool StackdriverRootContext::isOutbound() {
return direction_ == ::Wasm::Common::TrafficDirection::Outbound;
}
inline bool StackdriverRootContext::enableAccessLog() {
return enableAllAccessLog() || enableAccessLogOnError();
}
inline bool StackdriverRootContext::enableAllAccessLog() {
// TODO(gargnupur): Remove (!config_.disable_server_access_logging() &&
// !isOutbound) once disable_server_access_logging config is removed.
return (!config_.disable_server_access_logging() && !isOutbound()) ||
config_.access_logging() == stackdriver::config::v1alpha1::PluginConfig::FULL;
}
inline bool StackdriverRootContext::evaluateLogFilter() {
if (config_.access_logging_filter_expression() == "") {
return true;
}
bool value;
if (!evaluateExpression(log_filter_token_, &value)) {
LOG_TRACE(absl::StrCat("Could not evaluate expression: ",
config_.access_logging_filter_expression()));
return true;
}
return value;
}
inline bool StackdriverRootContext::enableAccessLogOnError() {
return config_.access_logging() == stackdriver::config::v1alpha1::PluginConfig::ERRORS_ONLY;
}
inline bool StackdriverRootContext::enableAuditLog() { return config_.enable_audit_log(); }
bool StackdriverRootContext::shouldLogThisRequest(::Wasm::Common::RequestInfo& request_info) {
std::string shouldLog = "";
if (!getValue({::Wasm::Common::kAccessLogPolicyKey}, &shouldLog)) {
LOG_DEBUG("cannot get envoy access log info from filter state.");
return true;
}
// Add label log_sampled if Access Log Policy sampling was applied to logs.
request_info.log_sampled = (shouldLog != "no");
return request_info.log_sampled;
}
bool StackdriverRootContext::shouldAuditThisRequest() { return Wasm::Common::getAuditPolicy(); }
void StackdriverRootContext::addToTCPRequestQueue(uint32_t id) {
std::unique_ptr<::Wasm::Common::RequestInfo> request_info =
std::make_unique<::Wasm::Common::RequestInfo>();
request_info->tcp_connections_opened++;
request_info->start_time =
static_cast<long int>(proxy_wasm::null_plugin::getCurrentTimeNanoseconds());
std::unique_ptr<StackdriverRootContext::TcpRecordInfo> record_info =
std::make_unique<StackdriverRootContext::TcpRecordInfo>();
record_info->request_info = std::move(request_info);
record_info->tcp_open_entry_logged = false;
tcp_request_queue_[id] = std::move(record_info);
}
void StackdriverRootContext::deleteFromTCPRequestQueue(uint32_t id) {
tcp_request_queue_.erase(id);
}
void StackdriverRootContext::incrementReceivedBytes(uint32_t id, size_t size) {
tcp_request_queue_[id]->request_info->tcp_received_bytes += size;
tcp_request_queue_[id]->request_info->tcp_total_received_bytes += size;
}
void StackdriverRootContext::incrementSentBytes(uint32_t id, size_t size) {
tcp_request_queue_[id]->request_info->tcp_sent_bytes += size;
tcp_request_queue_[id]->request_info->tcp_total_sent_bytes += size;
}
void StackdriverRootContext::incrementConnectionClosed(uint32_t id) {
tcp_request_queue_[id]->request_info->tcp_connections_closed++;
}
void StackdriverRootContext::setConnectionState(uint32_t id,
::Wasm::Common::TCPConnectionState state) {
tcp_request_queue_[id]->request_info->tcp_connection_state = state;
}
void StackdriverRootContext::evaluateExpressions(
std::unordered_map<std::string, std::string>& extra_labels) {
for (const auto& expression : expressions_) {
std::string value;
if (!evaluateExpression(expression.token, &value)) {
LOG_TRACE(absl::StrCat("Could not evaluate expression: ", expression.expression));
continue;
}
extra_labels[expression.tag] = value;
}
}
void StackdriverRootContext::evaluateMetricsExpressions(override_map& overrides) {
for (const auto& expression : metrics_expressions_) {
std::string value;
if (!evaluateExpression(expression.token, &value)) {
LOG_WARN(absl::StrCat("Could not evaluate expression: ", expression.expression));
continue;
}
overrides[expression.metric].emplace_back(expression.tag, value);
}
}
void StackdriverRootContext::cleanupExpressions() {
for (const auto& expression : expressions_) {
exprDelete(expression.token);
}
expressions_.clear();
}
void StackdriverRootContext::cleanupMetricsExpressions() {
for (const auto& expression : metrics_expressions_) {
exprDelete(expression.token);
}
metrics_expressions_.clear();
}
void StackdriverRootContext::cleanupLogFilter() {
exprDelete(log_filter_token_);
log_filter_token_ = 0;
}
// TODO(bianpengyuan) Add final export once root context supports onDone.
// https://github.com/envoyproxy/envoy-wasm/issues/240
StackdriverRootContext* StackdriverContext::getRootContext() {
RootContext* root = this->root();
return dynamic_cast<StackdriverRootContext*>(root);
}
void StackdriverContext::onLog() {
if (!is_initialized_) {
return;
}
if (is_tcp_) {
getRootContext()->incrementConnectionClosed(context_id_);
getRootContext()->setConnectionState(context_id_, ::Wasm::Common::TCPConnectionState::Close);
getRootContext()->recordTCP(context_id_);
getRootContext()->deleteFromTCPRequestQueue(context_id_);
return;
}
// Record telemetry based on request info.
getRootContext()->record();
}
} // namespace Stackdriver
#ifdef NULL_PLUGIN
} // namespace null_plugin
} // namespace proxy_wasm
#endif

View File

@ -1,270 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "extensions/common/context.h"
#include "extensions/stackdriver/common/constants.h"
#include "extensions/stackdriver/config/v1alpha1/stackdriver_plugin_config.pb.h"
#include "extensions/stackdriver/log/logger.h"
#include "extensions/stackdriver/metric/record.h"
// OpenCensus is full of unused parameters in metric_service.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include "opencensus/exporters/stats/stackdriver/stackdriver_exporter.h"
#pragma GCC diagnostic pop
#ifndef NULL_PLUGIN
#include "api/wasm/cpp/proxy_wasm_intrinsics.h"
#else
#include "include/proxy-wasm/null_plugin.h"
namespace proxy_wasm {
namespace null_plugin {
#endif
namespace Stackdriver {
// 10m
constexpr long int kDefaultTcpLogEntryTimeoutNanoseconds = 60000000000; // 1m
constexpr long int kDefaultLogExportNanoseconds = 10000000000; // 10s
#ifdef NULL_PLUGIN
PROXY_WASM_NULL_PLUGIN_REGISTRY;
#endif
// StackdriverRootContext is the root context for all streams processed by the
// thread. It has the same lifetime as the worker thread and acts as target for
// interactions that outlives individual stream, e.g. timer, async calls.
class StackdriverRootContext : public RootContext {
public:
StackdriverRootContext(uint32_t id, std::string_view root_id) : RootContext(id, root_id) {
empty_node_info_ = ::Wasm::Common::extractEmptyNodeFlatBuffer();
}
~StackdriverRootContext() = default;
bool onConfigure(size_t) override;
bool configure(size_t);
bool onStart(size_t) override;
void onTick() override;
bool onDone() override;
// Get direction of traffic relative to this proxy.
bool isOutbound();
bool useHostHeaderFallback() const { return use_host_header_fallback_; };
// Records telemetry for the current active stream/connection. Returns true,
// if request was recorded.
bool recordTCP(uint32_t id);
// Records telemetry for the current active stream.
void record();
// Functions for TCP connection's RequestInfo queue.
void addToTCPRequestQueue(uint32_t id);
void deleteFromTCPRequestQueue(uint32_t id);
void incrementReceivedBytes(uint32_t id, size_t size);
void incrementSentBytes(uint32_t id, size_t size);
void incrementConnectionClosed(uint32_t id);
void setConnectionState(uint32_t id, ::Wasm::Common::TCPConnectionState state);
const ::Wasm::Common::FlatNode& getLocalNode() {
return *flatbuffers::GetRoot<::Wasm::Common::FlatNode>(local_node_info_.data());
}
bool initialized() const { return initialized_; };
private:
// Stores information about TCP request.
struct TcpRecordInfo {
std::unique_ptr<::Wasm::Common::RequestInfo> request_info;
bool tcp_open_entry_logged;
// This caches evaluated extra access log labels.
std::unordered_map<std::string, std::string> extra_log_labels;
bool expressions_evaluated;
// cache filter expression value
bool log_connection;
bool log_filter_evaluated;
};
// Indicates whether to export any kind of access log or not.
bool enableAccessLog();
// Indicates whether to export all server/client access log or not.
bool enableAllAccessLog();
// Indicates whether to export any access log or not when there was an
// error in request/connection.
bool enableAccessLogOnError();
bool shouldLogThisRequest(::Wasm::Common::RequestInfo& request_info);
// Indicates whether to export server audit log or not.
bool enableAuditLog();
// Indicates whether the request should be logged based on audit policy
bool shouldAuditThisRequest();
// Indicates whether or not to report TCP Logs.
bool enableTCPServerAccessLog();
// Evaluate Expressions in expressions_ vector and add it in extra_labels.
void evaluateExpressions(std::unordered_map<std::string, std::string>& extra_labels);
// Evaluate Expressions in metrics_expressions_ vector.
void evaluateMetricsExpressions(::Extensions::Stackdriver::Metric::override_map& overrides);
// Evaluates a logging filter. If the returned value is `false`, no log
// entry will be added for the request/connection.
bool evaluateLogFilter();
// Initializes a configured logging filter.
bool initializeLogFilter();
// Cleanup expressions in expressions_ vector.
void cleanupExpressions();
// Cleanup expressions in metrics_expressions_ vector.
void cleanupMetricsExpressions();
// Cleanup any access logging filter expression.
void cleanupLogFilter();
// Config for Stackdriver plugin.
stackdriver::config::v1alpha1::PluginConfig config_;
// Local node info extracted from node metadata.
flatbuffers::DetachedBuffer local_node_info_;
flatbuffers::DetachedBuffer empty_node_info_;
// Indicates the traffic direction relative to this proxy.
::Wasm::Common::TrafficDirection direction_{::Wasm::Common::TrafficDirection::Unspecified};
// Logger records and exports log entries to Stackdriver backend.
std::unique_ptr<::Extensions::Stackdriver::Log::Logger> logger_;
long int tcp_log_entry_timeout_ = kDefaultTcpLogEntryTimeoutNanoseconds;
long int last_log_report_call_nanos_ = 0;
long int log_report_duration_nanos_ = kDefaultLogExportNanoseconds;
bool use_host_header_fallback_;
bool initialized_ = false;
std::unordered_map<uint32_t, std::unique_ptr<StackdriverRootContext::TcpRecordInfo>>
tcp_request_queue_;
// Stores expressions for evaluation for custom access logs.
struct expressionInfo {
uint32_t token;
std::string tag;
std::string expression;
};
std::vector<struct expressionInfo> expressions_;
// Stores expressions for evaluation for metrics.
struct metricsExpressionInfo {
uint32_t token;
std::string metric;
::opencensus::tags::TagKey tag;
std::string expression;
};
std::vector<struct metricsExpressionInfo> metrics_expressions_;
// Stores the reference token for a configured access logging filter
// expression.
uint32_t log_filter_token_;
};
// StackdriverContext is per stream context. It has the same lifetime as
// the request stream itself.
class StackdriverContext : public Context {
public:
StackdriverContext(uint32_t id, RootContext* root)
: Context(id, root), is_tcp_(false), context_id_(id),
is_initialized_(getRootContext()->initialized()) {}
void onLog() override;
FilterStatus onNewConnection() override {
if (!is_initialized_) {
return FilterStatus::Continue;
}
is_tcp_ = true;
getRootContext()->addToTCPRequestQueue(context_id_);
getRootContext()->setConnectionState(context_id_, ::Wasm::Common::TCPConnectionState::Open);
return FilterStatus::Continue;
}
// Called on onData call, so counting the data that is received.
FilterStatus onDownstreamData(size_t size, bool) override {
if (!is_initialized_) {
return FilterStatus::Continue;
}
getRootContext()->incrementReceivedBytes(context_id_, size);
getRootContext()->setConnectionState(context_id_,
::Wasm::Common::TCPConnectionState::Connected);
return FilterStatus::Continue;
}
// Called on onWrite call, so counting the data that is sent.
FilterStatus onUpstreamData(size_t size, bool) override {
if (!is_initialized_) {
return FilterStatus::Continue;
}
getRootContext()->incrementSentBytes(context_id_, size);
getRootContext()->setConnectionState(context_id_,
::Wasm::Common::TCPConnectionState::Connected);
return FilterStatus::Continue;
}
private:
// Gets root Stackdriver context that this stream Stackdriver context
// associated with.
StackdriverRootContext* getRootContext();
bool is_tcp_;
uint32_t context_id_;
const bool is_initialized_;
};
class StackdriverOutboundRootContext : public StackdriverRootContext {
public:
StackdriverOutboundRootContext(uint32_t id, std::string_view root_id)
: StackdriverRootContext(id, root_id) {}
};
class StackdriverInboundRootContext : public StackdriverRootContext {
public:
StackdriverInboundRootContext(uint32_t id, std::string_view root_id)
: StackdriverRootContext(id, root_id) {}
};
static RegisterContextFactory
register_OutboundStackdriverContext(CONTEXT_FACTORY(StackdriverContext),
ROOT_FACTORY(StackdriverOutboundRootContext),
::Extensions::Stackdriver::Common::kOutboundRootContextId);
static RegisterContextFactory
register_InboundStackdriverContext(CONTEXT_FACTORY(StackdriverContext),
ROOT_FACTORY(StackdriverInboundRootContext),
::Extensions::Stackdriver::Common::kInboundRootContextId);
} // namespace Stackdriver
#ifdef NULL_PLUGIN
} // namespace null_plugin
} // namespace proxy_wasm
#endif

View File

@ -1,31 +0,0 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "include/proxy-wasm/null_plugin.h"
#include "stackdriver.h"
namespace proxy_wasm {
namespace null_plugin {
namespace Stackdriver {
NullPluginRegistry* context_registry_{};
RegisterNullVmPluginFactory register_stackdriver_filter("envoy.wasm.null.stackdriver", []() {
return std::make_unique<NullPlugin>(context_registry_);
});
} // namespace Stackdriver
} // namespace null_plugin
} // namespace proxy_wasm

View File

@ -1,75 +0,0 @@
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: stackdriver-filter
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_OUTBOUND
listener:
filterChain:
filter:
name: "envoy.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.wasm
config:
config:
root_id: stackdriver_outbound
configuration: |
{}
vm_config:
vm_id: stackdriver_outbound
runtime: envoy.wasm.runtime.null
code:
local: { inline_string: envoy.wasm.null.stackdriver }
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: "envoy.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.wasm
config:
config:
root_id: stackdriver_inbound
configuration: |
{}
vm_config:
vm_id: stackdriver_inbound
runtime: envoy.wasm.runtime.null
code:
local: { inline_string: envoy.wasm.null.stackdriver }
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
filterChain:
filter:
name: "envoy.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.wasm
config:
config:
root_id: stackdriver_outbound
configuration: |
{"disable_host_header_fallback": true}
vm_config:
vm_id: stackdriver_outbound
runtime: envoy.wasm.runtime.null
code:
local: { inline_string: envoy.wasm.null.stackdriver }

50
go.mod
View File

@ -1,37 +1,33 @@
module istio.io/proxy
go 1.19
go 1.24
require (
cloud.google.com/go/logging v1.8.1
cloud.google.com/go/monitoring v1.16.0
cloud.google.com/go/trace v1.10.1
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4
github.com/envoyproxy/go-control-plane v0.12.1-0.20240119184926-7c74dbb4baa1
github.com/golang/protobuf v1.5.3
github.com/google/go-cmp v0.5.9
github.com/prometheus/client_model v0.5.0
github.com/prometheus/common v0.44.0
go.opentelemetry.io/proto/otlp v1.0.0
go.starlark.net v0.0.0-20231016134836-22325403fcb3
google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c
google.golang.org/grpc v1.58.3
google.golang.org/protobuf v1.32.0
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f
github.com/envoyproxy/go-control-plane v0.13.5-0.20250705082150-f8f2cd45490a
github.com/envoyproxy/go-control-plane/envoy v1.32.4
github.com/golang/protobuf v1.5.4
github.com/google/go-cmp v0.7.0
github.com/prometheus/client_model v0.6.1
github.com/prometheus/common v0.46.0
go.opentelemetry.io/proto/otlp v1.1.0
go.starlark.net v0.0.0-20240123142251-f86470692795
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a
google.golang.org/grpc v1.73.0
google.golang.org/protobuf v1.36.6
gopkg.in/yaml.v2 v2.4.0
sigs.k8s.io/yaml v1.3.0
sigs.k8s.io/yaml v1.4.0
)
require (
cloud.google.com/go/longrunning v0.5.1 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
cel.dev/expr v0.23.0 // indirect
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/planetscale/vtprotobuf v0.5.1-0.20231212170721-e7d721933795 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.25.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect
)

173
go.sum
View File

@ -1,114 +1,85 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go/logging v1.8.1 h1:26skQWPeYhvIasWKm48+Eq7oUqdcdbwsCVwz5Ys0FvU=
cloud.google.com/go/logging v1.8.1/go.mod h1:TJjR+SimHwuC8MZ9cjByQulAMgni+RkXeI3wwctHJEI=
cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI=
cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
cloud.google.com/go/monitoring v1.16.0 h1:rlndy4K8yknMY9JuGe2aK4SbCh21FXoCdX7SAGHmRgI=
cloud.google.com/go/monitoring v1.16.0/go.mod h1:Ptp15HgAyM1fNICAojDMoNc/wUmn67mLHQfyqbw+poY=
cloud.google.com/go/trace v1.10.1 h1:EwGdOLCNfYOOPtgqo+D2sDLZmRCEO1AagRTJCU6ztdg=
cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
cel.dev/expr v0.23.0 h1:wUb94w6OYQS4uXraxo9U+wUAs9jT47Xvl4iPgAwM2ss=
cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k=
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.12.1-0.20240119184926-7c74dbb4baa1 h1:PvIitQw+XxT2BZR2Oih5AeCTL2VX2c+l+9q9dXIaRSw=
github.com/envoyproxy/go-control-plane v0.12.1-0.20240119184926-7c74dbb4baa1/go.mod h1:lFu6itz1hckLR2A3aJ+ZKf3lu8HpjTsJSsqvVF6GL6g=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/envoyproxy/go-control-plane v0.13.5-0.20250705082150-f8f2cd45490a h1:k0yPxzI8NWvWx9TKX3ysJabi1XEkrKmutgfIe27WX7M=
github.com/envoyproxy/go-control-plane v0.13.5-0.20250705082150-f8f2cd45490a/go.mod h1:whHrEUXbTAzBJlzd3Gz4us5zEFP1gL6o3LbfA+a/xbg=
github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/planetscale/vtprotobuf v0.5.1-0.20231212170721-e7d721933795 h1:pH+U6pJP0BhxqQ4njBUjOg0++WMMvv3eByWzB+oATBY=
github.com/planetscale/vtprotobuf v0.5.1-0.20231212170721-e7d721933795/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.starlark.net v0.0.0-20231016134836-22325403fcb3 h1:CKbpFNZNfaNyEWd6C+F1vLZ0WJjukoU45zDErBmRKPs=
go.starlark.net v0.0.0-20231016134836-22325403fcb3/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0=
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk=
google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13 h1:U7+wNaVuSTaUqNvK2+osJ9ejEZxbjHHk8F2b6Hpx0AE=
google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:RdyHbowztCGQySiCvQPgWQWgWhGnouTdCflKoDBt32U=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c h1:jHkCUWkseRf+W+edG5hMzr/Uh1xkDREY4caybAq4dpY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y=
github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI=
go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY=
go.starlark.net v0.0.0-20240123142251-f86470692795 h1:LmbG8Pq7KDGkglKVn8VpZOZj6vb9b8nKEGcg9l03epM=
go.starlark.net v0.0.0-20240123142251-f86470692795/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a h1:SGktgSolFCo75dnHJF2yMvnns6jCmHFJ0vE4Vn2JKvQ=
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

View File

@ -31,7 +31,8 @@ GOPATH=/home/prow/go
ROOT=/go/src
# Configure available resources and disable IPv6 tests.
export BAZEL_BUILD_ARGS="--verbose_failures --test_env=ENVOY_IP_TEST_VERSIONS=v4only --test_output=errors"
BAZEL_BUILD_ARGS="${BAZEL_BUILD_EXTRA_ARGS:-} --verbose_failures --test_env=ENVOY_IP_TEST_VERSIONS=v4only --test_output=errors"
export BAZEL_BUILD_ARGS="${BAZEL_BUILD_ARGS# }"
# Override envoy.
if [[ "${ENVOY_REPOSITORY:-}" && "${ENVOY_PREFIX:-}" ]]; then

View File

@ -134,7 +134,7 @@ do
fi
;;
"debug")
CONFIG_PARAMS="--config=debug"
CONFIG_PARAMS="-c dbg"
BINARY_BASE_NAME="${BASE_BINARY_NAME}-debug"
# shellcheck disable=SC2086
BAZEL_OUT="$(bazel info ${BAZEL_BUILD_ARGS} output_path)/${ARCH_NAME}-dbg/bin"
@ -162,39 +162,6 @@ do
fi
done
# Skip check if envoy repo is overridden in bazel.
if [[ "$BAZEL_BUILD_ARGS" != *"override_repository=envoy"* ]]; then
echo "Checking extensions build config"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
WORKSPACE="${ROOT}/WORKSPACE"
ENVOY_ORG="$(grep -Pom1 "^ENVOY_ORG = \"\K[a-zA-Z-]+" "${WORKSPACE}")"
ENVOY_REPO="$(grep -Pom1 "^ENVOY_REPO = \"\K[a-zA-Z-]+" "${WORKSPACE}")"
ENVOY_SHA="$(grep -Pom1 "^ENVOY_SHA = \"\K[a-zA-Z0-9]{40}" "${WORKSPACE}")"
TMP_DIR=$(mktemp -d)
ENVOY_EXTENSIONS_BUILD_CONFIG="${TMP_DIR}/envoy.bzl"
PROXY_EXTENSIONS_BUILD_CONFIG="${TMP_DIR}/proxy.bzl"
echo "get envoy extensions build config from ${ENVOY_ORG}/${ENVOY_REPO} commit: ${ENVOY_SHA}"
curl --silent --show-error --retry 10 --location \
"https://raw.githubusercontent.com/${ENVOY_ORG}/${ENVOY_REPO}/${ENVOY_SHA}/source/extensions/extensions_build_config.bzl" \
-o "${ENVOY_EXTENSIONS_BUILD_CONFIG}" \
|| { echo "Could not get envoy extensions build config." ; exit 1 ; }
# backup proxy extension build config
cp "${ROOT}/bazel/extension_config/extensions_build_config.bzl" "${TMP_DIR}/proxy.bzl"
# remove the first line
sed -i "1d" "${PROXY_EXTENSIONS_BUILD_CONFIG}"
go run tools/extension-check/main.go \
--ignore-extensions tools/extension-check/wellknown-extensions \
--envoy-extensions-build-config "${ENVOY_EXTENSIONS_BUILD_CONFIG}" \
--proxy-extensions-build-config "${PROXY_EXTENSIONS_BUILD_CONFIG}" \
|| { echo "failed to check extension build config"; exit 1;}
fi
# Exit early to skip wasm build
if [ "${BUILD_ENVOY_BINARY_ONLY}" -eq 1 ]; then
exit 0

View File

@ -1,76 +0,0 @@
#!/bin/bash
#
# Copyright 2021 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
# This script verifies the LastFlag response flag in istio/proxy matches the one in envoyproxy/envoy
# and fails with a non-zero exit code if they differ.
set -x
if [[ -n "${ENVOY_REPOSITORY}" ]]; then
echo "Skipping LastFlag verification, custom envoy used"
exit 0
fi
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
WORKSPACE=${ROOT}/WORKSPACE
PATH_LASTFLAG_SPEC_DOWNSTREAM="${ROOT}/extensions/common/util.cc"
PATH_LASTFLAG_SPEC_UPSTREAM="stream_info.h"
ENVOY_PATH_LASTFLAG_SPEC="envoy/stream_info/stream_info.h"
ENVOY_ORG="$(grep -Pom1 "^ENVOY_ORG = \"\K[a-zA-Z-]+" "${WORKSPACE}")"
ENVOY_REPO="$(grep -Pom1 "^ENVOY_REPO = \"\K[a-zA-Z-]+" "${WORKSPACE}")"
ENVOY_SHA="$(grep -Pom1 "^ENVOY_SHA = \"\K[a-zA-Z0-9]{40}" "${WORKSPACE}")"
trap 'rm -rf ${PATH_LASTFLAG_SPEC_UPSTREAM}' EXIT
curl -sSL "https://raw.githubusercontent.com/${ENVOY_ORG}/${ENVOY_REPO}/${ENVOY_SHA}/${ENVOY_PATH_LASTFLAG_SPEC}" > "${PATH_LASTFLAG_SPEC_UPSTREAM}"
# Extract the LastFlag specification from both sources and trim all white spaces.
if grep -q "^\s*LastFlag\s*=.*$" "${PATH_LASTFLAG_SPEC_DOWNSTREAM}"
then
DOWNSTREAM_LASTFLAG=$(grep -m1 "^\s*LastFlag\s*=.*$" "${PATH_LASTFLAG_SPEC_DOWNSTREAM}"|tr -d '[:space:]')
else
echo "istio/proxy: LastFlag not specified in ${PATH_LASTFLAG_SPEC_DOWNSTREAM}"
exit 1
fi
if grep -q "^\s*LastFlag\s*=.*$" ${PATH_LASTFLAG_SPEC_UPSTREAM}
then
UPSTREAM_LASTFLAG=$(grep -m1 "^\s*LastFlag\s*=.*$" ${PATH_LASTFLAG_SPEC_UPSTREAM}|tr -d '[:space:]')
else
echo "envoyproxy/envoy: LastFlag not specified in https://raw.githubusercontent.com/${ENVOY_ORG}/${ENVOY_REPO}/${ENVOY_SHA}/${ENVOY_PATH_LASTFLAG_SPEC}"
exit 1
fi
# The trailing comma is optional and will be removed from the extracted values before comparison.
if [[ "${DOWNSTREAM_LASTFLAG:${#DOWNSTREAM_LASTFLAG}-1}" == "," ]]
then
DOWNSTREAM_LASTFLAG="${DOWNSTREAM_LASTFLAG:0:${#DOWNSTREAM_LASTFLAG}-1}"
fi
if [[ "${UPSTREAM_LASTFLAG:${#UPSTREAM_LASTFLAG}-1}" == "," ]]
then
UPSTREAM_LASTFLAG="${UPSTREAM_LASTFLAG:0:${#UPSTREAM_LASTFLAG}-1}"
fi
if [[ "$DOWNSTREAM_LASTFLAG" != "$UPSTREAM_LASTFLAG" ]]
then
echo "The LastFlag specification for downstream and upstream differs. Downstream is ${DOWNSTREAM_LASTFLAG}. Upstream is ${UPSTREAM_LASTFLAG}."
exit 1
fi

View File

@ -17,17 +17,15 @@
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_extension",
"envoy_cc_test",
"envoy_extension_package",
"envoy_cc_library",
"envoy_proto_library",
)
envoy_extension_package()
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
envoy_cc_extension(
envoy_cc_library(
name = "api_lib",
srcs = ["api.cc"],
hdrs = ["api.h"],

View File

@ -29,8 +29,10 @@
#include "source/extensions/common/workload_discovery/extension.pb.validate.h"
namespace Envoy::Extensions::Common::WorkloadDiscovery {
namespace {
constexpr absl::string_view DefaultNamespace = "default";
constexpr absl::string_view DefaultServiceAccount = "default";
constexpr absl::string_view DefaultTrustDomain = "cluster.local";
Istio::Common::WorkloadMetadataObject convert(const istio::workload::Workload& workload) {
auto workload_type = Istio::Common::WorkloadType::Deployment;
switch (workload.workload_type()) {
@ -46,10 +48,28 @@ Istio::Common::WorkloadMetadataObject convert(const istio::workload::Workload& w
default:
break;
}
absl::string_view ns = workload.namespace_();
absl::string_view trust_domain = workload.trust_domain();
absl::string_view service_account = workload.service_account();
// Trust domain may be elided if it's equal to "cluster.local"
if (trust_domain.empty()) {
trust_domain = DefaultTrustDomain;
}
// The namespace may be elided if it's equal to "default"
if (ns.empty()) {
ns = DefaultNamespace;
}
// The service account may be elided if it's equal to "default"
if (service_account.empty()) {
service_account = DefaultServiceAccount;
}
const auto identity =
absl::StrCat("spiffe://", trust_domain, "/ns/", ns, "/sa/", service_account);
return Istio::Common::WorkloadMetadataObject(
workload.name(), workload.cluster_id(), workload.namespace_(), workload.workload_name(),
workload.name(), workload.cluster_id(), ns, workload.workload_name(),
workload.canonical_name(), workload.canonical_revision(), workload.canonical_name(),
workload.canonical_revision(), workload_type);
workload.canonical_revision(), workload_type, identity);
}
} // namespace
@ -79,8 +99,8 @@ public:
const uint64_t high = absl::Uint128High64(ipv6->address());
const uint64_t low = absl::Uint128Low64(ipv6->address());
std::array<uint8_t, 16> output;
absl::little_endian::Store64(&output, high);
absl::little_endian::Store64(&output[8], low);
absl::little_endian::Store64(&output, low);
absl::little_endian::Store64(&output[8], high);
return tls_->get(std::string(output.begin(), output.end()));
}
}
@ -129,11 +149,13 @@ private:
: Config::SubscriptionBase<istio::workload::Workload>(
parent.factory_context_.messageValidationVisitor(), "uid"),
parent_(parent) {
subscription_ = parent.factory_context_.clusterManager()
.subscriptionFactory()
.subscriptionFromConfigSource(
parent.config_source_, Grpc::Common::typeUrl(getResourceName()),
*parent.scope_, *this, resource_decoder_, {});
subscription_ = THROW_OR_RETURN_VALUE(
parent.factory_context_.clusterManager()
.subscriptionFactory()
.subscriptionFromConfigSource(parent.config_source_,
Grpc::Common::typeUrl(getResourceName()),
*parent.scope_, *this, resource_decoder_, {}),
Config::SubscriptionPtr);
}
void start() { subscription_->start({}); }
@ -227,6 +249,8 @@ public:
});
}
void onWorkerThreadInitialized() override{};
private:
Server::Configuration::ServerFactoryContext& factory_context_;
const istio::workload::BootstrapExtension config_;

View File

@ -22,19 +22,40 @@ option go_package = "test/envoye2e/workloadapi";
* https://github.com/istio/ztunnel/blob/e36680f1534fae3d158964500ae9185495ec5d7b/proto/workload.proto
* with the following changes:
*
* 1) delete unused fields;
* 2) change go_package;
* 3) append bootstrap extension stub;
* 1) change go_package;
* 2) append bootstrap extension stub;
*/
message Workload {
string uid = 20;
// NetworkMode indicates how the addresses of the workload should be treated.
enum NetworkMode {
// STANDARD means that the workload is uniquely identified by its address (within its network).
STANDARD = 0;
// HOST_NETWORK means the workload has an IP address that is shared by many workloads. The data plane should avoid
// attempting to lookup these workloads by IP address (which could return the wrong result).
HOST_NETWORK = 1;
}
// Workload represents a workload - an endpoint (or collection behind a hostname).
// The xds primary key is "uid" as defined on the workload below.
// Secondary (alias) keys are the unique `network/IP` pairs that the workload can be reached at.
message Workload {
// UID represents a globally unique opaque identifier for this workload.
// For k8s resources, it is recommended to use the more readable format:
//
// cluster/group/kind/namespace/name/section-name
//
// As an example, a ServiceEntry with two WorkloadEntries inlined could become
// two Workloads with the following UIDs:
// - cluster1/networking.istio.io/v1alpha3/ServiceEntry/default/external-svc/endpoint1
// - cluster1/networking.istio.io/v1alpha3/ServiceEntry/default/external-svc/endpoint2
//
// For VMs and other workloads other formats are also supported; for example,
// a single UID string: "0ae5c03d-5fb3-4eb9-9de8-2bd4b51606ba"
string uid = 20;
// Name represents the name for the workload.
// For Kubernetes, this is the pod name.
// This is just for debugging and may be elided as an optimization.
string name = 1;
// Namespace represents the namespace for the workload.
// This is just for debugging and may be elided as an optimization.
string namespace = 2;
@ -43,61 +64,97 @@ message Workload {
// This should be globally unique.
// This should not have a port number.
// Each workload must have at least either an address or hostname; not both.
// TODO: support dual stack by making this repeated
// TODO: when this is repeated, update xds primary key from network/IP to network/UID
repeated bytes addresses = 3;
reserved "hostname";
reserved 21;
// The hostname for the workload to be resolved by the ztunnel.
// DNS queries are sent on-demand by default.
// If the resolved DNS query has several endpoints, the request will be forwarded
// to the first response.
//
// At a minimum, each workload must have either an address or hostname. For example,
// a workload that backs a Kubernetes service will typically have only endpoints. A
// workload that backs a headless Kubernetes service, however, will have both
// addresses as well as a hostname used for direct access to the headless endpoint.
string hostname = 21;
// Network represents the network this workload is on. This may be elided for the default network.
// A (network,address) pair makeup a unique key for a workload *at a point in time*.
string network = 4;
reserved "tunnel_protocol";
reserved 5;
// Protocol that should be used to connect to this workload.
TunnelProtocol tunnel_protocol = 5;
// The SPIFFE identity of the workload. The identity is joined to form spiffe://<trust_domain>/ns/<namespace>/sa/<service_account>.
// TrustDomain of the workload. May be elided if this is the mesh wide default (typically cluster.local)
string trust_domain = 6;
// ServiceAccount of the workload. May be elided if this is "default"
string service_account = 7;
reserved "waypoint";
reserved 8;
// If present, the waypoint proxy for this workload.
// All incoming requests must go through the waypoint.
GatewayAddress waypoint = 8;
reserved "network_gateway";
reserved 19;
// If present, East West network gateway this workload can be reached through.
// Requests from remote networks should traverse this gateway.
GatewayAddress network_gateway = 19;
reserved "node";
reserved 9;
// Name of the node the workload runs on
string node = 9;
// CanonicalName for the workload. Used for telemetry.
string canonical_name = 10;
// CanonicalRevision for the workload. Used for telemetry.
string canonical_revision = 11;
// WorkloadType represents the type of the workload. Used for telemetry.
WorkloadType workload_type = 12;
// WorkloadName represents the name for the workload (of type WorkloadType). Used for telemetry.
string workload_name = 13;
reserved "native_tunnel";
reserved 14;
// If set, this indicates a workload expects to directly receive tunnel traffic.
// In ztunnel, this means:
// * Requests *from* this workload do not need to be tunneled if they already are tunneled by the tunnel_protocol.
// * Requests *to* this workload, via the tunnel_protocol, do not need to be de-tunneled.
bool native_tunnel = 14;
reserved "virtual_ips";
reserved 15;
// If an application, such as a sandwiched waypoint proxy, supports directly
// receiving information from zTunnel they can set application_protocol.
ApplicationTunnel application_tunnel = 23;
reserved "authorization_policies";
reserved 16;
// The services for which this workload is an endpoint.
// The key is the NamespacedHostname string of the format namespace/hostname.
map<string, PortList> services = 22;
reserved "status";
reserved 17;
// A list of authorization policies applicable to this workload.
// NOTE: this *only* includes Selector based policies. Namespace and global polices
// are returned out of band.
// Authorization policies are only valid for workloads with `addresses` rather than `hostname`.
repeated string authorization_policies = 16;
WorkloadStatus status = 17;
// The cluster ID that the workload instance belongs to
string cluster_id = 18;
// The Locality defines information about where a workload is geographically deployed
Locality locality = 24;
NetworkMode network_mode = 25;
// Reservations for deleted fields.
reserved 15;
}
message Locality {
string region = 1;
string zone = 2;
string subzone = 3;
}
enum WorkloadStatus {
// Workload is healthy and ready to serve traffic.
HEALTHY = 0;
// Workload is unhealthy and NOT ready to serve traffic.
UNHEALTHY = 1;
}
enum WorkloadType {
@ -106,3 +163,77 @@ enum WorkloadType {
POD = 2;
JOB = 3;
}
// PorList represents the ports for a service
message PortList {
repeated Port ports = 1;
}
message Port {
// Port the service is reached at (frontend).
uint32 service_port = 1;
// Port the service forwards to (backend).
uint32 target_port = 2;
}
// TunnelProtocol indicates the tunneling protocol for requests.
enum TunnelProtocol {
// NONE means requests should be forwarded as-is, without tunneling.
NONE = 0;
// HBONE means requests should be tunneled over HTTP.
// This does not dictate HTTP/1.1 vs HTTP/2; ALPN should be used for that purpose.
HBONE = 1;
// Future options may include things like QUIC/HTTP3, etc.
}
// ApplicationProtocol specifies a workload (application or gateway) can
// consume tunnel information.
message ApplicationTunnel {
enum Protocol {
// Bytes are copied from the inner stream without modification.
NONE = 0;
// Prepend PROXY protocol headers before copying bytes
// Standard PROXY source and destination information
// is included, along with potential extra TLV headers:
// 0xD0 - The SPIFFE identity of the source workload
// 0xD1 - The FQDN or Hostname of the targeted Service
PROXY = 1;
}
// A target natively handles this type of traffic.
Protocol protocol = 1;
// optional: if set, traffic should be sent to this port after the last zTunnel hop
uint32 port = 2;
}
// GatewayAddress represents the address of a gateway
message GatewayAddress {
// address can either be a hostname (ex: gateway.example.com) or an IP (ex: 1.2.3.4).
oneof destination {
// TODO: add support for hostname lookup
NamespacedHostname hostname = 1;
NetworkAddress address = 2;
}
// port to reach the gateway at for mTLS HBONE connections
uint32 hbone_mtls_port = 3;
reserved "hbone_single_tls_port";
reserved 4;
}
// NetworkAddress represents an address bound to a specific network.
message NetworkAddress {
// Network represents the network this address is on.
string network = 1;
// Address presents the IP (v4 or v6).
bytes address = 2;
}
// NamespacedHostname represents a service bound to a specific namespace.
message NamespacedHostname {
// The namespace the service is in.
string namespace = 1;
// hostname (ex: gateway.example.com)
string hostname = 2;
}

View File

@ -19,10 +19,9 @@ load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_library",
"envoy_cc_test",
"envoy_extension_package",
)
envoy_extension_package()
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
@ -47,7 +46,6 @@ envoy_cc_library(
deps = [
":alpn_filter",
"@envoy//envoy/registry",
"@envoy//source/exe:all_extensions_lib",
"@envoy//source/extensions/filters/http/common:factory_base_lib",
],
)

View File

@ -17,15 +17,14 @@
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_extension",
"envoy_extension_package",
"envoy_cc_library",
)
envoy_extension_package()
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
envoy_cc_extension(
envoy_cc_library(
name = "istio_stats",
srcs = ["istio_stats.cc"],
hdrs = ["istio_stats.h"],
@ -47,7 +46,6 @@ envoy_cc_extension(
"@envoy//source/common/http:header_utility_lib",
"@envoy//source/common/network:utility_lib",
"@envoy//source/common/stream_info:utility_lib",
"@envoy//source/extensions/filters/common/expr:cel_state_lib",
"@envoy//source/extensions/filters/common/expr:context_lib",
"@envoy//source/extensions/filters/common/expr:evaluator_lib",
"@envoy//source/extensions/filters/http/common:pass_through_filter_lib",

View File

@ -27,8 +27,8 @@
#include "source/common/http/header_utility.h"
#include "source/common/network/utility.h"
#include "source/common/stream_info/utility.h"
#include "source/extensions/filters/common/expr/cel_state.h"
#include "source/extensions/filters/common/expr/context.h"
#include "source/extensions/filters/common/expr/cel_state.h"
#include "source/extensions/filters/common/expr/evaluator.h"
#include "source/extensions/filters/http/common/pass_through_filter.h"
#include "source/extensions/filters/http/grpc_stats/grpc_stats_filter.h"
@ -70,7 +70,7 @@ absl::optional<absl::string_view> getNamespace(absl::string_view principal) {
constexpr absl::string_view CustomStatNamespace = "istiocustom";
absl::string_view extractString(const ProtobufWkt::Struct& metadata, const std::string& key) {
absl::string_view extractString(const ProtobufWkt::Struct& metadata, absl::string_view key) {
const auto& it = metadata.fields().find(key);
if (it == metadata.fields().end()) {
return {};
@ -79,7 +79,7 @@ absl::string_view extractString(const ProtobufWkt::Struct& metadata, const std::
}
absl::string_view extractMapString(const ProtobufWkt::Struct& metadata, const std::string& map_key,
const std::string& key) {
absl::string_view key) {
const auto& it = metadata.fields().find(map_key);
if (it == metadata.fields().end()) {
return {};
@ -117,28 +117,53 @@ enum class Reporter {
bool peerInfoRead(Reporter reporter, const StreamInfo::FilterState& filter_state) {
const auto& filter_state_key =
reporter == Reporter::ServerSidecar || reporter == Reporter::ServerGateway
? "wasm.downstream_peer_id"
: "wasm.upstream_peer_id";
? Istio::Common::DownstreamPeer
: Istio::Common::UpstreamPeer;
return filter_state.hasDataWithName(filter_state_key) ||
filter_state.hasDataWithName("envoy.wasm.metadata_exchange.peer_unknown");
filter_state.hasDataWithName(Istio::Common::NoPeer);
}
const Wasm::Common::FlatNode* peerInfo(Reporter reporter,
const StreamInfo::FilterState& filter_state) {
std::optional<Istio::Common::WorkloadMetadataObject>
peerInfo(Reporter reporter, const StreamInfo::FilterState& filter_state) {
const auto& filter_state_key =
reporter == Reporter::ServerSidecar || reporter == Reporter::ServerGateway
? "wasm.downstream_peer"
: "wasm.upstream_peer";
const auto* object =
? Istio::Common::DownstreamPeer
: Istio::Common::UpstreamPeer;
// This's a workaround before FilterStateObject support operation like `.labels['role']`.
// The workaround is to use CelState to store the peer metadata.
// Rebuild the WorkloadMetadataObject from the CelState.
const auto* cel_state =
filter_state.getDataReadOnly<Envoy::Extensions::Filters::Common::Expr::CelState>(
filter_state_key);
return object ? flatbuffers::GetRoot<Wasm::Common::FlatNode>(object->value().data()) : nullptr;
if (!cel_state) {
return {};
}
ProtobufWkt::Struct obj;
if (!obj.ParseFromString(absl::string_view(cel_state->value()))) {
return {};
}
Istio::Common::WorkloadMetadataObject peer_info(
extractString(obj, Istio::Common::InstanceNameToken),
extractString(obj, Istio::Common::ClusterNameToken),
extractString(obj, Istio::Common::NamespaceNameToken),
extractString(obj, Istio::Common::WorkloadNameToken),
extractString(obj, Istio::Common::ServiceNameToken),
extractString(obj, Istio::Common::ServiceVersionToken),
extractString(obj, Istio::Common::AppNameToken),
extractString(obj, Istio::Common::AppVersionToken),
Istio::Common::fromSuffix(extractString(obj, Istio::Common::WorkloadTypeToken)),
extractString(obj, Istio::Common::IdentityToken));
return peer_info;
}
// Process-wide context shared with all filter instances.
struct Context : public Singleton::Instance {
explicit Context(Stats::SymbolTable& symbol_table, const envoy::config::core::v3::Node& node)
: pool_(symbol_table), node_(node), stat_namespace_(pool_.add(CustomStatNamespace)),
explicit Context(Stats::SymbolTable& symbol_table, const LocalInfo::LocalInfo& local_info)
: pool_(symbol_table), local_info_(local_info),
stat_namespace_(pool_.add(CustomStatNamespace)),
requests_total_(pool_.add("istio_requests_total")),
request_duration_milliseconds_(pool_.add("istio_request_duration_milliseconds")),
request_bytes_(pool_.add("istio_request_bytes")),
@ -176,18 +201,20 @@ struct Context : public Singleton::Instance {
connection_security_policy_(pool_.add("connection_security_policy")),
response_code_(pool_.add("response_code")),
grpc_response_status_(pool_.add("grpc_response_status")),
workload_name_(pool_.add(extractString(node.metadata(), "WORKLOAD_NAME"))),
namespace_(pool_.add(extractString(node.metadata(), "NAMESPACE"))),
canonical_name_(pool_.add(
extractMapString(node.metadata(), "LABELS", "service.istio.io/canonical-name"))),
canonical_revision_(pool_.add(
extractMapString(node.metadata(), "LABELS", "service.istio.io/canonical-revision"))),
cluster_name_(pool_.add(extractString(node.metadata(), "CLUSTER_ID"))),
app_name_(pool_.add(extractMapString(node.metadata(), "LABELS", "app"))),
app_version_(pool_.add(extractMapString(node.metadata(), "LABELS", "version"))),
istio_build_(pool_.add("istio_build")), component_(pool_.add("component")),
proxy_(pool_.add("proxy")), tag_(pool_.add("tag")),
istio_version_(pool_.add(extractString(node.metadata(), "ISTIO_VERSION"))) {
workload_name_(pool_.add(extractString(local_info.node().metadata(), "WORKLOAD_NAME"))),
namespace_(pool_.add(extractString(local_info.node().metadata(), "NAMESPACE"))),
canonical_name_(pool_.add(extractMapString(local_info.node().metadata(), "LABELS",
Istio::Common::CanonicalNameLabel))),
canonical_revision_(pool_.add(extractMapString(local_info.node().metadata(), "LABELS",
Istio::Common::CanonicalRevisionLabel))),
app_name_(pool_.add(
extractMapString(local_info.node().metadata(), "LABELS", Istio::Common::AppNameLabel))),
app_version_(pool_.add(extractMapString(local_info.node().metadata(), "LABELS",
Istio::Common::AppVersionLabel))),
cluster_name_(pool_.add(extractString(local_info.node().metadata(), "CLUSTER_ID"))),
waypoint_(pool_.add("waypoint")), istio_build_(pool_.add("istio_build")),
component_(pool_.add("component")), proxy_(pool_.add("proxy")), tag_(pool_.add("tag")),
istio_version_(pool_.add(extractString(local_info.node().metadata(), "ISTIO_VERSION"))) {
all_metrics_ = {
{"requests_total", requests_total_},
{"request_duration_milliseconds", request_duration_milliseconds_},
@ -230,7 +257,7 @@ struct Context : public Singleton::Instance {
}
Stats::StatNamePool pool_;
const envoy::config::core::v3::Node& node_;
const LocalInfo::LocalInfo& local_info_;
absl::flat_hash_map<std::string, Stats::StatName> all_metrics_;
absl::flat_hash_map<std::string, Stats::StatName> all_tags_;
@ -294,9 +321,10 @@ struct Context : public Singleton::Instance {
const Stats::StatName namespace_;
const Stats::StatName canonical_name_;
const Stats::StatName canonical_revision_;
const Stats::StatName cluster_name_;
const Stats::StatName app_name_;
const Stats::StatName app_version_;
const Stats::StatName cluster_name_;
const Stats::StatName waypoint_;
// istio_build metric:
// Publishes Istio version for the proxy as a gauge, sample data:
@ -313,8 +341,6 @@ using ContextSharedPtr = std::shared_ptr<Context>;
SINGLETON_MANAGER_REGISTRATION(Context)
using google::api::expr::runtime::CelValue;
// Instructions on dropping, creating, and overriding labels.
// This is not the "hot path" of the metrics system and thus, fairly
// unoptimized.
@ -483,7 +509,7 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
[&factory_context] {
return std::make_shared<Context>(
factory_context.serverFactoryContext().scope().symbolTable(),
factory_context.serverFactoryContext().localInfo().node());
factory_context.serverFactoryContext().localInfo());
})),
scope_(factory_context, PROTOBUF_GET_MS_OR_DEFAULT(proto_config, rotation_interval, 0),
PROTOBUF_GET_MS_OR_DEFAULT(proto_config, graceful_deletion_interval,
@ -491,6 +517,7 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
disable_host_header_fallback_(proto_config.disable_host_header_fallback()),
report_duration_(
PROTOBUF_GET_MS_OR_DEFAULT(proto_config, tcp_reporting_duration, /* 5s */ 5000)) {
recordVersion(factory_context);
reporter_ = Reporter::ClientSidecar;
switch (proto_config.reporter()) {
case stats::Reporter::UNSPECIFIED:
@ -638,6 +665,7 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
const Http::ResponseTrailerMap* response_trailers = nullptr) {
evaluated_ = true;
if (parent_.metric_overrides_) {
local_info_ = &parent_.context_->local_info_;
activation_info_ = &info;
activation_request_headers_ = request_headers;
activation_response_headers_ = response_headers;
@ -649,6 +677,13 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
Protobuf::Arena arena;
auto eval_status = compiled_exprs[id].first->Evaluate(*this, &arena);
if (!eval_status.ok() || eval_status.value().IsError()) {
if (!eval_status.ok()) {
ENVOY_LOG(debug, "Failed to evaluate metric expression: {}", eval_status.status());
}
if (eval_status.value().IsError()) {
ENVOY_LOG(debug, "Failed to evaluate metric expression: {}",
eval_status.value().ErrorOrDie()->message());
}
expr_values_.push_back(std::make_pair(parent_.context_->unknown_, 0));
} else {
const auto string_value = Filters::Common::Expr::print(eval_status.value());
@ -667,27 +702,6 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
}
}
absl::optional<CelValue> FindValue(absl::string_view name,
Protobuf::Arena* arena) const override {
auto obj = StreamActivation::FindValue(name, arena);
if (obj) {
return obj;
}
if (name == "node") {
return Filters::Common::Expr::CelProtoWrapper::CreateMessage(&parent_.context_->node_,
arena);
}
if (activation_info_) {
const auto* obj = activation_info_->filterState()
.getDataReadOnly<Envoy::Extensions::Filters::Common::Expr::CelState>(
absl::StrCat("wasm.", name));
if (obj) {
return obj->exprValue(arena, false);
}
}
return {};
}
void addCounter(Stats::StatName metric, const Stats::StatNameTagVector& tags,
uint64_t amount = 1) {
ASSERT(evaluated_);
@ -761,13 +775,13 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
bool evaluated_{false};
};
void recordVersion() {
void recordVersion(Server::Configuration::FactoryContext& factory_context) {
Stats::StatNameTagVector tags;
tags.push_back({context_->component_, context_->proxy_});
tags.push_back({context_->tag_, context_->istio_version_.empty() ? context_->unknown_
: context_->istio_version_});
Stats::Utility::gaugeFromStatNames(*scope(),
Stats::Utility::gaugeFromStatNames(factory_context.scope(),
{context_->stat_namespace_, context_->istio_build_},
Stats::Gauge::ImportMode::Accumulate, tags)
.set(1);
@ -788,6 +802,7 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
using ConfigSharedPtr = std::shared_ptr<Config>;
class IstioStatsFilter : public Http::PassThroughFilter,
public Logger::Loggable<Logger::Id::filter>,
public AccessLog::Instance,
public Network::ReadFilter,
public Network::ConnectionCallbacks {
@ -798,9 +813,11 @@ public:
tags_.reserve(25);
switch (config_->reporter()) {
case Reporter::ServerSidecar:
case Reporter::ServerGateway:
tags_.push_back({context_.reporter_, context_.destination_});
break;
case Reporter::ServerGateway:
tags_.push_back({context_.reporter_, context_.waypoint_});
break;
case Reporter::ClientSidecar:
tags_.push_back({context_.reporter_, context_.source_});
break;
@ -912,6 +929,7 @@ private:
const auto& info = decoder_callbacks_->streamInfo();
peer_read_ = peerInfoRead(config_->reporter(), info.filterState());
if (peer_read_ || end_stream) {
ENVOY_LOG(trace, "Populating peer metadata from HTTP MX.");
populatePeerInfo(info, info.filterState());
}
if (is_grpc_ && (peer_read_ || end_stream)) {
@ -950,6 +968,7 @@ private:
peer_read_ = peerInfoRead(config_->reporter(), filter_state);
// Report connection open once peer info is read or connection is closed.
if (peer_read_ || end_stream) {
ENVOY_LOG(trace, "Populating peer metadata from TCP MX.");
populatePeerInfo(info, filter_state);
tags_.push_back({context_.request_protocol_, context_.tcp_});
populateFlagsAndConnectionSecurity(info);
@ -994,9 +1013,9 @@ private:
const StreamInfo::FilterState& filter_state) {
// Compute peer info with client-side fallbacks.
absl::optional<Istio::Common::WorkloadMetadataObject> peer;
const auto* object = peerInfo(config_->reporter(), filter_state);
auto object = peerInfo(config_->reporter(), filter_state);
if (object) {
peer.emplace(Istio::Common::convertFlatNodeToWorkloadMetadata(*object));
peer.emplace(object.value());
} else if (config_->reporter() == Reporter::ClientSidecar) {
if (auto label_obj = extractEndpointMetadata(info); label_obj) {
peer.emplace(label_obj.value());
@ -1006,6 +1025,7 @@ private:
// Compute destination service with client-side fallbacks.
absl::string_view service_host;
absl::string_view service_host_name;
absl::string_view service_namespace;
if (!config_->disable_host_header_fallback_) {
const auto* headers = info.getRequestHeaders();
if (headers && headers->Host()) {
@ -1022,6 +1042,7 @@ private:
if (cluster_info && cluster_info.value()) {
const auto& cluster_name = cluster_info.value()->name();
if (cluster_name == "BlackHoleCluster" || cluster_name == "PassthroughCluster" ||
cluster_name == "InboundPassthroughCluster" ||
cluster_name == "InboundPassthroughClusterIpv4" ||
cluster_name == "InboundPassthroughClusterIpv6") {
service_host_name = cluster_name;
@ -1039,6 +1060,10 @@ private:
service_host = host_it->second.string_value();
}
const auto& name_it = service.find("name");
const auto& namespace_it = service.find("namespace");
if (namespace_it != service.end()) {
service_namespace = namespace_it->second.string_value();
}
if (name_it != service.end()) {
service_host_name = name_it->second.string_value();
} else {
@ -1051,7 +1076,7 @@ private:
}
}
absl::string_view peer_san;
std::string peer_san;
absl::string_view local_san;
switch (config_->reporter()) {
case Reporter::ServerSidecar:
@ -1082,9 +1107,19 @@ private:
case Reporter::ClientSidecar: {
const Ssl::ConnectionInfoConstSharedPtr ssl_info =
info.upstreamInfo() ? info.upstreamInfo()->upstreamSslConnection() : nullptr;
std::optional<Istio::Common::WorkloadMetadataObject> endpoint_peer;
if (ssl_info && !ssl_info->uriSanPeerCertificate().empty()) {
peer_san = ssl_info->uriSanPeerCertificate()[0];
}
if (peer_san.empty()) {
auto endpoint_object = peerInfo(config_->reporter(), filter_state);
if (endpoint_object) {
endpoint_peer.emplace(endpoint_object.value());
peer_san = endpoint_peer->identity_;
}
}
// This won't work for sidecar/ingress -> ambient becuase of the CONNECT
// tunnel.
if (ssl_info && !ssl_info->uriSanLocalCertificate().empty()) {
local_san = ssl_info->uriSanLocalCertificate()[0];
}
@ -1132,30 +1167,51 @@ private:
switch (config_->reporter()) {
case Reporter::ServerGateway: {
std::optional<Istio::Common::WorkloadMetadataObject> endpoint_peer;
const auto* endpoint_object = peerInfo(Reporter::ClientSidecar, filter_state);
auto endpoint_object = peerInfo(Reporter::ClientSidecar, filter_state);
if (endpoint_object) {
endpoint_peer.emplace(Istio::Common::convertFlatNodeToWorkloadMetadata(*endpoint_object));
endpoint_peer.emplace(endpoint_object.value());
}
tags_.push_back(
{context_.destination_workload_,
endpoint_peer ? pool_.add(endpoint_peer->workload_name_) : context_.unknown_});
tags_.push_back({context_.destination_workload_namespace_, context_.namespace_});
tags_.push_back({context_.destination_principal_,
!local_san.empty() ? pool_.add(local_san) : context_.unknown_});
// Endpoint encoding does not have app and version.
tags_.push_back({context_.destination_app_, context_.unknown_});
tags_.push_back({context_.destination_version_, context_.unknown_});
auto canonical_name =
endpoint_peer ? pool_.add(endpoint_peer->canonical_name_) : context_.unknown_;
tags_.push_back({context_.destination_service_,
service_host.empty() ? canonical_name : pool_.add(service_host)});
tags_.push_back({context_.destination_canonical_service_, canonical_name});
{context_.destination_workload_, endpoint_peer && !endpoint_peer->workload_name_.empty()
? pool_.add(endpoint_peer->workload_name_)
: context_.unknown_});
tags_.push_back({context_.destination_workload_namespace_,
endpoint_peer && !endpoint_peer->namespace_name_.empty()
? pool_.add(endpoint_peer->namespace_name_)
: context_.unknown_});
tags_.push_back(
{context_.destination_canonical_revision_,
endpoint_peer ? pool_.add(endpoint_peer->canonical_revision_) : context_.unknown_});
{context_.destination_principal_, endpoint_peer && !endpoint_peer->identity_.empty()
? pool_.add(endpoint_peer->identity_)
: context_.unknown_});
// Endpoint encoding does not have app and version.
tags_.push_back(
{context_.destination_app_, endpoint_peer && !endpoint_peer->app_name_.empty()
? pool_.add(endpoint_peer->app_name_)
: context_.unknown_});
tags_.push_back(
{context_.destination_version_, endpoint_peer && !endpoint_peer->app_version_.empty()
? pool_.add(endpoint_peer->app_version_)
: context_.unknown_});
tags_.push_back({context_.destination_service_,
service_host.empty() ? context_.unknown_ : pool_.add(service_host)});
tags_.push_back({context_.destination_canonical_service_,
endpoint_peer && !endpoint_peer->canonical_name_.empty()
? pool_.add(endpoint_peer->canonical_name_)
: context_.unknown_});
tags_.push_back({context_.destination_canonical_revision_,
endpoint_peer && !endpoint_peer->canonical_revision_.empty()
? pool_.add(endpoint_peer->canonical_revision_)
: context_.unknown_});
tags_.push_back({context_.destination_service_name_, service_host_name.empty()
? canonical_name
? context_.unknown_
: pool_.add(service_host_name)});
tags_.push_back({context_.destination_service_namespace_, !service_namespace.empty()
? pool_.add(service_namespace)
: context_.unknown_});
tags_.push_back(
{context_.destination_cluster_, endpoint_peer && !endpoint_peer->cluster_name_.empty()
? pool_.add(endpoint_peer->cluster_name_)
: context_.unknown_});
break;
}
default:
@ -1173,10 +1229,10 @@ private:
tags_.push_back({context_.destination_service_name_, service_host_name.empty()
? context_.canonical_name_
: pool_.add(service_host_name)});
tags_.push_back({context_.destination_service_namespace_, context_.namespace_});
tags_.push_back({context_.destination_cluster_, context_.cluster_name_});
break;
}
tags_.push_back({context_.destination_service_namespace_, context_.namespace_});
tags_.push_back({context_.destination_cluster_, context_.cluster_name_});
break;
}
@ -1215,8 +1271,11 @@ private:
tags_.push_back({context_.destination_service_name_, service_host_name.empty()
? context_.unknown_
: pool_.add(service_host_name)});
tags_.push_back({context_.destination_service_namespace_,
!peer_namespace.empty() ? pool_.add(peer_namespace) : context_.unknown_});
tags_.push_back(
{context_.destination_service_namespace_,
!service_namespace.empty()
? pool_.add(service_namespace)
: (!peer_namespace.empty() ? pool_.add(peer_namespace) : context_.unknown_)});
tags_.push_back({context_.destination_cluster_, peer && !peer->cluster_name_.empty()
? pool_.add(peer->cluster_name_)
: context_.unknown_});
@ -1253,7 +1312,6 @@ absl::StatusOr<Http::FilterFactoryCb> IstioStatsFilterConfigFactory::createFilte
CustomStatNamespace);
ConfigSharedPtr config = std::make_shared<Config>(
dynamic_cast<const stats::PluginConfig&>(proto_config), factory_context);
config->recordVersion();
return [config](Http::FilterChainFactoryCallbacks& callbacks) {
auto filter = std::make_shared<IstioStatsFilter>(config);
callbacks.addStreamFilter(filter);
@ -1266,13 +1324,13 @@ absl::StatusOr<Http::FilterFactoryCb> IstioStatsFilterConfigFactory::createFilte
REGISTER_FACTORY(IstioStatsFilterConfigFactory,
Server::Configuration::NamedHttpFilterConfigFactory);
Network::FilterFactoryCb IstioStatsNetworkFilterConfigFactory::createFilterFactoryFromProto(
absl::StatusOr<Network::FilterFactoryCb>
IstioStatsNetworkFilterConfigFactory::createFilterFactoryFromProto(
const Protobuf::Message& proto_config, Server::Configuration::FactoryContext& factory_context) {
factory_context.serverFactoryContext().api().customStatNamespaces().registerStatNamespace(
CustomStatNamespace);
ConfigSharedPtr config = std::make_shared<Config>(
dynamic_cast<const stats::PluginConfig&>(proto_config), factory_context);
config->recordVersion();
return [config](Network::FilterManager& filter_manager) {
filter_manager.addReadFilter(std::make_shared<IstioStatsFilter>(config));
};

View File

@ -45,7 +45,7 @@ public:
return std::make_unique<stats::PluginConfig>();
}
Network::FilterFactoryCb
absl::StatusOr<Network::FilterFactoryCb>
createFilterFactoryFromProto(const Protobuf::Message& proto_config,
Server::Configuration::FactoryContext& factory_context) override;
};

View File

@ -17,25 +17,23 @@
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_extension",
"envoy_cc_library",
"envoy_cc_test",
"envoy_extension_package",
"envoy_proto_library",
)
envoy_extension_package()
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
envoy_cc_extension(
envoy_cc_library(
name = "filter_lib",
srcs = ["filter.cc"],
hdrs = ["filter.h"],
repository = "@envoy",
deps = [
":config_cc_proto",
"//extensions/common:context",
"//extensions/common:metadata_object_lib",
"//extensions/common:proto_util",
"//source/extensions/common/workload_discovery:api_lib",
"@envoy//envoy/registry",
"@envoy//source/common/common:base64_lib",
@ -49,12 +47,7 @@ envoy_cc_extension(
],
)
cc_proto_library(
name = "config_cc_proto",
deps = ["config"],
)
proto_library(
envoy_proto_library(
name = "config",
srcs = ["config.proto"],
)
@ -70,6 +63,5 @@ envoy_cc_test(
"@envoy//test/mocks/server:factory_context_mocks",
"@envoy//test/mocks/stream_info:stream_info_mocks",
"@envoy//test/test_common:logging_lib",
"@envoy//test/test_common:wasm_lib",
],
)

View File

@ -75,4 +75,8 @@ message Config {
// True to enable sharing with the upstream.
bool shared_with_upstream = 5;
// Additional labels to be added to the peer metadata to help your understand the traffic.
// e.g. `role`, `location` etc.
repeated string additional_labels = 6;
}

View File

@ -16,43 +16,20 @@
#include "envoy/registry/registry.h"
#include "envoy/server/factory_context.h"
#include "extensions/common/context.h"
#include "extensions/common/metadata_object.h"
#include "extensions/common/proto_util.h"
#include "source/common/common/hash.h"
#include "source/common/common/base64.h"
#include "source/common/http/header_utility.h"
#include "source/common/http/utility.h"
#include "source/common/network/utility.h"
#include "source/extensions/filters/common/expr/cel_state.h"
#include "extensions/common/metadata_object.h"
namespace Envoy {
namespace Extensions {
namespace HttpFilters {
namespace PeerMetadata {
// Extended peer info that supports "hashing" to enable sharing with the
// upstream connection via an internal listener.
class CelStateHashable : public Filters::Common::Expr::CelState, public Hashable {
public:
explicit CelStateHashable(const Filters::Common::Expr::CelStatePrototype& proto)
: CelState(proto) {}
absl::optional<uint64_t> hash() const override { return HashUtil::xxHash64(value()); }
};
struct CelPrototypeValues {
const Filters::Common::Expr::CelStatePrototype NodeInfo{
true, Filters::Common::Expr::CelStateType::FlatBuffers,
toAbslStringView(Wasm::Common::nodeInfoSchema()),
// Life span is only needed for Wasm set_property, not in the native filters.
StreamInfo::FilterState::LifeSpan::FilterChain};
const Filters::Common::Expr::CelStatePrototype NodeId{
true, Filters::Common::Expr::CelStateType::String, absl::string_view(),
// Life span is only needed for Wasm set_property, not in the native filters.
StreamInfo::FilterState::LifeSpan::FilterChain};
};
using CelPrototypes = ConstSingleton<CelPrototypeValues>;
using ::Envoy::Extensions::Filters::Common::Expr::CelState;
class XDSMethod : public DiscoveryMethod {
public:
@ -103,15 +80,17 @@ absl::optional<PeerInfo> XDSMethod::derivePeerInfo(const StreamInfo::StreamInfo&
}
}
}
const auto metadata_object = metadata_provider_->GetMetadata(peer_address);
if (metadata_object) {
return Istio::Common::convertWorkloadMetadataToFlatNode(metadata_object.value());
if (!peer_address) {
return {};
}
return {};
ENVOY_LOG_MISC(debug, "Peer address: {}", peer_address->asString());
return metadata_provider_->GetMetadata(peer_address);
}
MXMethod::MXMethod(bool downstream, Server::Configuration::ServerFactoryContext& factory_context)
: downstream_(downstream), tls_(factory_context.threadLocal()) {
MXMethod::MXMethod(bool downstream, const absl::flat_hash_set<std::string> additional_labels,
Server::Configuration::ServerFactoryContext& factory_context)
: downstream_(downstream), tls_(factory_context.threadLocal()),
additional_labels_(additional_labels) {
tls_.set([](Event::Dispatcher&) { return std::make_shared<MXCache>(); });
}
@ -155,43 +134,39 @@ absl::optional<PeerInfo> MXMethod::lookup(absl::string_view id, absl::string_vie
if (!metadata.ParseFromString(bytes)) {
return {};
}
const auto fb = ::Wasm::Common::extractNodeFlatBufferFromStruct(metadata);
std::string out(reinterpret_cast<const char*>(fb.data()), fb.size());
auto out = Istio::Common::convertStructToWorkloadMetadata(metadata, additional_labels_);
if (max_peer_cache_size_ > 0 && !id.empty()) {
// do not let the cache grow beyond max cache size.
if (static_cast<uint32_t>(cache.size()) > max_peer_cache_size_) {
cache.erase(cache.begin(), std::next(cache.begin(), max_peer_cache_size_ / 4));
}
cache.emplace(id, out);
cache.emplace(id, *out);
}
return out;
return *out;
}
MXPropagationMethod::MXPropagationMethod(
bool downstream, Server::Configuration::ServerFactoryContext& factory_context,
const absl::flat_hash_set<std::string>& additional_labels,
const io::istio::http::peer_metadata::Config_IstioHeaders& istio_headers)
: downstream_(downstream), id_(factory_context.localInfo().node().id()),
value_(computeValue(factory_context)),
value_(computeValue(additional_labels, factory_context)),
skip_external_clusters_(istio_headers.skip_external_clusters()) {}
std::string MXPropagationMethod::computeValue(
const absl::flat_hash_set<std::string>& additional_labels,
Server::Configuration::ServerFactoryContext& factory_context) const {
const auto fb = ::Wasm::Common::extractNodeFlatBufferFromStruct(
factory_context.localInfo().node().metadata());
google::protobuf::Struct metadata;
::Wasm::Common::extractStructFromNodeFlatBuffer(
*flatbuffers::GetRoot<::Wasm::Common::FlatNode>(fb.data()), &metadata);
std::string metadata_bytes;
::Wasm::Common::serializeToStringDeterministic(metadata, &metadata_bytes);
const auto obj = Istio::Common::convertStructToWorkloadMetadata(
factory_context.localInfo().node().metadata(), additional_labels);
const google::protobuf::Struct metadata = Istio::Common::convertWorkloadMetadataToStruct(*obj);
const std::string metadata_bytes = Istio::Common::serializeToStringDeterministic(metadata);
return Base64::encode(metadata_bytes.data(), metadata_bytes.size());
}
void MXPropagationMethod::inject(const StreamInfo::StreamInfo& info, Http::HeaderMap& headers,
Context& ctx) const {
if (skip_external_clusters_) {
if (skipMXHeaders(info)) {
return;
}
if (skipMXHeaders(skip_external_clusters_, info)) {
return;
}
if (!downstream_ || ctx.request_peer_id_received_) {
headers.setReference(Headers::get().ExchangeMetadataHeaderId, id_);
@ -204,19 +179,24 @@ void MXPropagationMethod::inject(const StreamInfo::StreamInfo& info, Http::Heade
FilterConfig::FilterConfig(const io::istio::http::peer_metadata::Config& config,
Server::Configuration::FactoryContext& factory_context)
: shared_with_upstream_(config.shared_with_upstream()),
downstream_discovery_(
buildDiscoveryMethods(config.downstream_discovery(), true, factory_context)),
upstream_discovery_(
buildDiscoveryMethods(config.upstream_discovery(), false, factory_context)),
downstream_propagation_(
buildPropagationMethods(config.downstream_propagation(), true, factory_context)),
upstream_propagation_(
buildPropagationMethods(config.upstream_propagation(), false, factory_context)) {}
downstream_discovery_(buildDiscoveryMethods(config.downstream_discovery(),
buildAdditionalLabels(config.additional_labels()),
true, factory_context)),
upstream_discovery_(buildDiscoveryMethods(config.upstream_discovery(),
buildAdditionalLabels(config.additional_labels()),
false, factory_context)),
downstream_propagation_(buildPropagationMethods(
config.downstream_propagation(), buildAdditionalLabels(config.additional_labels()), true,
factory_context)),
upstream_propagation_(buildPropagationMethods(
config.upstream_propagation(), buildAdditionalLabels(config.additional_labels()), false,
factory_context)) {}
std::vector<DiscoveryMethodPtr> FilterConfig::buildDiscoveryMethods(
const Protobuf::RepeatedPtrField<io::istio::http::peer_metadata::Config::DiscoveryMethod>&
config,
bool downstream, Server::Configuration::FactoryContext& factory_context) const {
const absl::flat_hash_set<std::string>& additional_labels, bool downstream,
Server::Configuration::FactoryContext& factory_context) const {
std::vector<DiscoveryMethodPtr> methods;
methods.reserve(config.size());
for (const auto& method : config) {
@ -228,8 +208,8 @@ std::vector<DiscoveryMethodPtr> FilterConfig::buildDiscoveryMethods(
break;
case io::istio::http::peer_metadata::Config::DiscoveryMethod::MethodSpecifierCase::
kIstioHeaders:
methods.push_back(
std::make_unique<MXMethod>(downstream, factory_context.serverFactoryContext()));
methods.push_back(std::make_unique<MXMethod>(downstream, additional_labels,
factory_context.serverFactoryContext()));
break;
default:
break;
@ -241,15 +221,17 @@ std::vector<DiscoveryMethodPtr> FilterConfig::buildDiscoveryMethods(
std::vector<PropagationMethodPtr> FilterConfig::buildPropagationMethods(
const Protobuf::RepeatedPtrField<io::istio::http::peer_metadata::Config::PropagationMethod>&
config,
bool downstream, Server::Configuration::FactoryContext& factory_context) const {
const absl::flat_hash_set<std::string>& additional_labels, bool downstream,
Server::Configuration::FactoryContext& factory_context) const {
std::vector<PropagationMethodPtr> methods;
methods.reserve(config.size());
for (const auto& method : config) {
switch (method.method_specifier_case()) {
case io::istio::http::peer_metadata::Config::PropagationMethod::MethodSpecifierCase::
kIstioHeaders:
methods.push_back(std::make_unique<MXPropagationMethod>(
downstream, factory_context.serverFactoryContext(), method.istio_headers()));
methods.push_back(
std::make_unique<MXPropagationMethod>(downstream, factory_context.serverFactoryContext(),
additional_labels, method.istio_headers()));
break;
default:
break;
@ -258,6 +240,15 @@ std::vector<PropagationMethodPtr> FilterConfig::buildPropagationMethods(
return methods;
}
absl::flat_hash_set<std::string>
FilterConfig::buildAdditionalLabels(const Protobuf::RepeatedPtrField<std::string>& labels) const {
absl::flat_hash_set<std::string> result;
for (const auto& label : labels) {
result.emplace(label);
}
return result;
}
void FilterConfig::discoverDownstream(StreamInfo::StreamInfo& info, Http::RequestHeaderMap& headers,
Context& ctx) const {
discover(info, true, headers, ctx);
@ -297,29 +288,20 @@ void FilterConfig::injectUpstream(const StreamInfo::StreamInfo& info,
}
void FilterConfig::setFilterState(StreamInfo::StreamInfo& info, bool downstream,
const std::string& value) const {
const absl::string_view key = downstream ? WasmDownstreamPeer : WasmUpstreamPeer;
const PeerInfo& value) const {
const absl::string_view key =
downstream ? Istio::Common::DownstreamPeer : Istio::Common::UpstreamPeer;
if (!info.filterState()->hasDataWithName(key)) {
auto node_info = std::make_unique<CelStateHashable>(CelPrototypes::get().NodeInfo);
node_info->setValue(value);
// Use CelState to allow operation filter_state.upstream_peer.labels['role']
auto pb = value.serializeAsProto();
auto peer_info = std::make_unique<CelState>(FilterConfig::peerInfoPrototype());
peer_info->setValue(absl::string_view(pb->SerializeAsString()));
info.filterState()->setData(
key, std::move(node_info), StreamInfo::FilterState::StateType::Mutable,
key, std::move(peer_info), StreamInfo::FilterState::StateType::Mutable,
StreamInfo::FilterState::LifeSpan::FilterChain, sharedWithUpstream());
} else {
ENVOY_LOG(debug, "Duplicate peer metadata, skipping");
}
// This is needed because stats filter awaits for the prefix on the wire and checks for the key
// presence before emitting any telemetry.
const absl::string_view id_key = downstream ? WasmDownstreamPeerID : WasmUpstreamPeerID;
if (!info.filterState()->hasDataWithName(id_key)) {
auto node_id = std::make_unique<Filters::Common::Expr::CelState>(CelPrototypes::get().NodeId);
node_id->setValue("unknown");
info.filterState()->setData(
id_key, std::move(node_id), StreamInfo::FilterState::StateType::Mutable,
StreamInfo::FilterState::LifeSpan::FilterChain, sharedWithUpstream());
} else {
ENVOY_LOG(debug, "Duplicate peer id, skipping");
}
}
Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, bool) {
@ -328,19 +310,34 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers,
return Http::FilterHeadersStatus::Continue;
}
bool MXPropagationMethod::skipMXHeaders(const StreamInfo::StreamInfo& info) const {
bool MXPropagationMethod::skipMXHeaders(const bool skip_external_clusters,
const StreamInfo::StreamInfo& info) const {
// We skip metadata in two cases.
// 1. skip_external_clusters is enabled, and we detect the upstream as external.
const auto& cluster_info = info.upstreamClusterInfo();
if (cluster_info && cluster_info.value()) {
const auto& cluster_name = cluster_info.value()->name();
if (cluster_name == "PassthroughCluster") {
// PassthroughCluster is always considered external
if (skip_external_clusters && cluster_name == "PassthroughCluster") {
return true;
}
const auto& filter_metadata = cluster_info.value()->metadata().filter_metadata();
const auto& it = filter_metadata.find("istio");
// Otherwise, cluster must be tagged as external
if (it != filter_metadata.end()) {
const auto& skip_mx = it->second.fields().find("external");
if (skip_external_clusters) {
const auto& skip_mx = it->second.fields().find("external");
if (skip_mx != it->second.fields().end()) {
if (skip_mx->second.bool_value()) {
return true;
}
}
}
const auto& skip_mx = it->second.fields().find("disable_mx");
if (skip_mx != it->second.fields().end()) {
return skip_mx->second.bool_value();
if (skip_mx->second.bool_value()) {
return true;
}
}
}
}

View File

@ -14,22 +14,20 @@
#pragma once
#include "source/extensions/filters/common/expr/cel_state.h"
#include "source/extensions/filters/http/common/factory_base.h"
#include "source/extensions/filters/http/common/pass_through_filter.h"
#include "source/extensions/filters/http/peer_metadata/config.pb.h"
#include "source/extensions/common/workload_discovery/api.h"
#include "source/common/singleton/const_singleton.h"
#include "extensions/common/context.h"
namespace Envoy {
namespace Extensions {
namespace HttpFilters {
namespace PeerMetadata {
constexpr absl::string_view WasmDownstreamPeer = "wasm.downstream_peer";
constexpr absl::string_view WasmDownstreamPeerID = "wasm.downstream_peer_id";
constexpr absl::string_view WasmUpstreamPeer = "wasm.upstream_peer";
constexpr absl::string_view WasmUpstreamPeerID = "wasm.upstream_peer_id";
using ::Envoy::Extensions::Filters::Common::Expr::CelStatePrototype;
using ::Envoy::Extensions::Filters::Common::Expr::CelStateType;
struct HeaderValues {
const Http::LowerCaseString ExchangeMetadataHeader{"x-envoy-peer-metadata"};
@ -38,8 +36,7 @@ struct HeaderValues {
using Headers = ConstSingleton<HeaderValues>;
// Peer info in the flatbuffers format.
using PeerInfo = std::string;
using PeerInfo = Istio::Common::WorkloadMetadataObject;
struct Context {
bool request_peer_id_received_{false};
@ -59,7 +56,8 @@ using DiscoveryMethodPtr = std::unique_ptr<DiscoveryMethod>;
class MXMethod : public DiscoveryMethod {
public:
MXMethod(bool downstream, Server::Configuration::ServerFactoryContext& factory_context);
MXMethod(bool downstream, const absl::flat_hash_set<std::string> additional_labels,
Server::Configuration::ServerFactoryContext& factory_context);
absl::optional<PeerInfo> derivePeerInfo(const StreamInfo::StreamInfo&, Http::HeaderMap&,
Context&) const override;
void remove(Http::HeaderMap&) const override;
@ -68,9 +66,10 @@ private:
absl::optional<PeerInfo> lookup(absl::string_view id, absl::string_view value) const;
const bool downstream_;
struct MXCache : public ThreadLocal::ThreadLocalObject {
absl::flat_hash_map<std::string, std::string> cache_;
absl::flat_hash_map<std::string, PeerInfo> cache_;
};
mutable ThreadLocal::TypedSlot<MXCache> tls_;
const absl::flat_hash_set<std::string> additional_labels_;
const int64_t max_peer_cache_size_{500};
};
@ -86,16 +85,18 @@ using PropagationMethodPtr = std::unique_ptr<PropagationMethod>;
class MXPropagationMethod : public PropagationMethod {
public:
MXPropagationMethod(bool downstream, Server::Configuration::ServerFactoryContext& factory_context,
const absl::flat_hash_set<std::string>& additional_labels,
const io::istio::http::peer_metadata::Config_IstioHeaders&);
void inject(const StreamInfo::StreamInfo&, Http::HeaderMap&, Context&) const override;
private:
const bool downstream_;
std::string computeValue(Server::Configuration::ServerFactoryContext&) const;
std::string computeValue(const absl::flat_hash_set<std::string>&,
Server::Configuration::ServerFactoryContext&) const;
const std::string id_;
const std::string value_;
const bool skip_external_clusters_;
bool skipMXHeaders(const StreamInfo::StreamInfo&) const;
bool skipMXHeaders(const bool, const StreamInfo::StreamInfo&) const;
};
class FilterConfig : public Logger::Loggable<Logger::Id::filter> {
@ -107,20 +108,31 @@ public:
void injectDownstream(const StreamInfo::StreamInfo&, Http::ResponseHeaderMap&, Context&) const;
void injectUpstream(const StreamInfo::StreamInfo&, Http::RequestHeaderMap&, Context&) const;
static const CelStatePrototype& peerInfoPrototype() {
static const CelStatePrototype* const prototype = new CelStatePrototype(
true, CelStateType::Protobuf, "type.googleapis.com/google.protobuf.Struct",
StreamInfo::FilterState::LifeSpan::FilterChain);
return *prototype;
}
private:
std::vector<DiscoveryMethodPtr> buildDiscoveryMethods(
const Protobuf::RepeatedPtrField<io::istio::http::peer_metadata::Config::DiscoveryMethod>&,
bool downstream, Server::Configuration::FactoryContext&) const;
const absl::flat_hash_set<std::string>& additional_labels, bool downstream,
Server::Configuration::FactoryContext&) const;
std::vector<PropagationMethodPtr> buildPropagationMethods(
const Protobuf::RepeatedPtrField<io::istio::http::peer_metadata::Config::PropagationMethod>&,
bool downstream, Server::Configuration::FactoryContext&) const;
const absl::flat_hash_set<std::string>& additional_labels, bool downstream,
Server::Configuration::FactoryContext&) const;
absl::flat_hash_set<std::string>
buildAdditionalLabels(const Protobuf::RepeatedPtrField<std::string>&) const;
StreamInfo::StreamSharingMayImpactPooling sharedWithUpstream() const {
return shared_with_upstream_
? StreamInfo::StreamSharingMayImpactPooling::SharedWithUpstreamConnectionOnce
: StreamInfo::StreamSharingMayImpactPooling::None;
}
void discover(StreamInfo::StreamInfo&, bool downstream, Http::HeaderMap&, Context&) const;
void setFilterState(StreamInfo::StreamInfo&, bool downstream, const std::string& value) const;
void setFilterState(StreamInfo::StreamInfo&, bool downstream, const PeerInfo& value) const;
const bool shared_with_upstream_;
const std::vector<DiscoveryMethodPtr> downstream_discovery_;
const std::vector<DiscoveryMethodPtr> upstream_discovery_;

View File

@ -14,7 +14,6 @@
#include "source/extensions/filters/http/peer_metadata/filter.h"
#include "source/extensions/filters/common/expr/cel_state.h"
#include "source/common/network/address_impl.h"
#include "test/common/stream_info/test_util.h"
#include "test/mocks/stream_info/mocks.h"
@ -76,25 +75,27 @@ protected:
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, true));
}
void checkNoPeer(bool downstream) {
EXPECT_FALSE(stream_info_.filterState()->hasDataWithName(downstream ? WasmDownstreamPeerID
: WasmUpstreamPeerID));
EXPECT_FALSE(stream_info_.filterState()->hasDataWithName(downstream ? WasmDownstreamPeer
: WasmUpstreamPeer));
EXPECT_FALSE(stream_info_.filterState()->hasDataWithName(
downstream ? Istio::Common::DownstreamPeer : Istio::Common::UpstreamPeer));
}
void checkPeerNamespace(bool downstream, const std::string& expected) {
EXPECT_TRUE(stream_info_.filterState()->hasDataWithName(downstream ? WasmDownstreamPeerID
: WasmUpstreamPeerID));
const auto* obj = stream_info_.filterState()->getDataReadOnly<Filters::Common::Expr::CelState>(
downstream ? WasmDownstreamPeer : WasmUpstreamPeer);
ASSERT_NE(nullptr, obj);
Protobuf::Arena arena;
auto map = obj->exprValue(&arena, false);
ASSERT_TRUE(map.IsMap());
auto value =
(*map.MapOrDie())[google::api::expr::runtime::CelValue::CreateStringView("namespace")];
ASSERT_TRUE(value.has_value());
EXPECT_EQ(expected, value.value().StringOrDie().value());
const auto* cel_state =
stream_info_.filterState()
->getDataReadOnly<Envoy::Extensions::Filters::Common::Expr::CelState>(
downstream ? Istio::Common::DownstreamPeer : Istio::Common::UpstreamPeer);
ProtobufWkt::Struct obj;
ASSERT_TRUE(obj.ParseFromString(cel_state->value().data()));
EXPECT_EQ(expected, extractString(obj, "namespace"));
}
absl::string_view extractString(const ProtobufWkt::Struct& metadata, absl::string_view key) {
const auto& it = metadata.fields().find(key);
if (it == metadata.fields().end()) {
return {};
}
return it->second.string_value();
}
void checkShared(bool expected) {
EXPECT_EQ(expected,
stream_info_.filterState()->objectsSharedWithUpstreamConnection()->size() > 0);
@ -132,7 +133,7 @@ TEST_F(PeerMetadataTest, DownstreamXDSNone) {
TEST_F(PeerMetadataTest, DownstreamXDS) {
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod);
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
-> std::optional<WorkloadMetadataObject> {
@ -154,7 +155,7 @@ TEST_F(PeerMetadataTest, DownstreamXDS) {
TEST_F(PeerMetadataTest, UpstreamXDS) {
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "foo", "foo", "foo-service",
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod);
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
-> std::optional<WorkloadMetadataObject> {
@ -190,7 +191,7 @@ TEST_F(PeerMetadataTest, UpstreamXDSInternal) {
*host_metadata);
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "foo", "foo", "foo-service",
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod);
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
-> std::optional<WorkloadMetadataObject> {
@ -259,7 +260,7 @@ TEST_F(PeerMetadataTest, DownstreamFallbackFirst) {
TEST_F(PeerMetadataTest, DownstreamFallbackSecond) {
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod);
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
-> std::optional<WorkloadMetadataObject> {
@ -281,7 +282,8 @@ TEST_F(PeerMetadataTest, DownstreamFallbackSecond) {
TEST(MXMethod, Cache) {
NiceMock<Server::Configuration::MockServerFactoryContext> context;
MXMethod method(true, context);
absl::flat_hash_set<std::string> additional_labels;
MXMethod method(true, additional_labels, context);
NiceMock<StreamInfo::MockStreamInfo> stream_info;
Http::TestRequestHeaderMapImpl request_headers;
const int32_t max = 1000;
@ -341,7 +343,7 @@ TEST_F(PeerMetadataTest, UpstreamFallbackFirst) {
TEST_F(PeerMetadataTest, UpstreamFallbackSecond) {
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "foo", "foo", "foo-service",
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod);
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
-> std::optional<WorkloadMetadataObject> {
@ -363,7 +365,7 @@ TEST_F(PeerMetadataTest, UpstreamFallbackSecond) {
TEST_F(PeerMetadataTest, UpstreamFallbackFirstXDS) {
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "foo", "foo", "foo-service",
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod);
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
-> std::optional<WorkloadMetadataObject> {
@ -396,6 +398,20 @@ TEST_F(PeerMetadataTest, DownstreamMXPropagation) {
checkNoPeer(false);
}
TEST_F(PeerMetadataTest, DownstreamMXPropagationWithAdditionalLabels) {
initialize(R"EOF(
downstream_propagation:
- istio_headers: {}
additional_labels:
- foo
- bar
)EOF");
EXPECT_EQ(0, request_headers_.size());
EXPECT_EQ(0, response_headers_.size());
checkNoPeer(true);
checkNoPeer(false);
}
TEST_F(PeerMetadataTest, DownstreamMXDiscoveryPropagation) {
request_headers_.setReference(Headers::get().ExchangeMetadataHeaderId, "test-pod");
request_headers_.setReference(Headers::get().ExchangeMetadataHeader, SampleIstioHeader);

View File

@ -39,12 +39,10 @@ envoy_cc_library(
],
repository = "@envoy",
deps = [
"//extensions/common:context",
"//extensions/common:proto_util",
"//extensions/common:metadata_object_lib",
"//source/extensions/common/workload_discovery:api_lib",
"//source/extensions/filters/network/metadata_exchange/config:metadata_exchange_cc_proto",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/base:endian",
"@com_google_absl//absl/strings",
"@envoy//envoy/local_info:local_info_interface",
"@envoy//envoy/network:connection_interface",
@ -53,11 +51,12 @@ envoy_cc_library(
"@envoy//envoy/stats:stats_macros",
"@envoy//envoy/stream_info:filter_state_interface",
"@envoy//source/common/http:utility_lib",
"@envoy//source/common/network:filter_state_dst_address_lib",
"@envoy//source/common/network:utility_lib",
"@envoy//source/common/protobuf",
"@envoy//source/common/protobuf:utility_lib",
"@envoy//source/common/stream_info:bool_accessor_lib",
"@envoy//source/extensions/filters/common/expr:cel_state_lib",
"@envoy//source/extensions/filters/network:well_known_names",
],
)
@ -88,6 +87,5 @@ envoy_cc_test(
"@envoy//test/mocks/network:network_mocks",
"@envoy//test/mocks/protobuf:protobuf_mocks",
"@envoy//test/mocks/server:server_factory_context_mocks",
"@envoy//test/test_common:wasm_lib",
],
)

View File

@ -31,9 +31,16 @@ Network::FilterFactoryCb createFilterFactoryHelper(
Server::Configuration::ServerFactoryContext& context, FilterDirection filter_direction) {
ASSERT(!proto_config.protocol().empty());
absl::flat_hash_set<std::string> additional_labels;
if (!proto_config.additional_labels().empty()) {
for (const auto& label : proto_config.additional_labels()) {
additional_labels.emplace(label);
}
}
MetadataExchangeConfigSharedPtr filter_config(std::make_shared<MetadataExchangeConfig>(
StatPrefix, proto_config.protocol(), filter_direction, proto_config.enable_discovery(),
context, context.scope()));
additional_labels, context, context.scope()));
return [filter_config, &context](Network::FilterManager& filter_manager) -> void {
filter_manager.addFilter(
std::make_shared<MetadataExchangeFilter>(filter_config, context.localInfo()));
@ -41,7 +48,8 @@ Network::FilterFactoryCb createFilterFactoryHelper(
}
} // namespace
Network::FilterFactoryCb MetadataExchangeConfigFactory::createFilterFactoryFromProto(
absl::StatusOr<Network::FilterFactoryCb>
MetadataExchangeConfigFactory::createFilterFactoryFromProto(
const Protobuf::Message& config, Server::Configuration::FactoryContext& context) {
return createFilterFactory(
dynamic_cast<const envoy::tcp::metadataexchange::config::MetadataExchange&>(config), context);

View File

@ -29,7 +29,7 @@ namespace MetadataExchange {
class MetadataExchangeConfigFactory
: public Server::Configuration::NamedNetworkFilterConfigFactory {
public:
Network::FilterFactoryCb
absl::StatusOr<Network::FilterFactoryCb>
createFilterFactoryFromProto(const Protobuf::Message&,
Server::Configuration::FactoryContext&) override;

Some files were not shown because too many files have changed in this diff Show More