-
Notifications
You must be signed in to change notification settings - Fork 4
feat: support a CA bundle for the control plane connection #447
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
867db94
8090806
256b91c
6d905a8
b4bd118
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -120,6 +120,7 @@ type ControlPlaneAuth struct { | |
| // ControlPlaneProvider defines configuration for control plane provider. | ||
| // +kubebuilder:validation:XValidation:rule="has(self.endpoints) != has(self.service)" | ||
| // +kubebuilder:validation:XValidation:rule="oldSelf == null || (!has(self.mode) && !has(oldSelf.mode)) || self.mode == oldSelf.mode",message="mode is immutable" | ||
| // +kubebuilder:validation:XValidation:rule="!has(self.caBundle) || self.caBundle.contains('-----BEGIN CERTIFICATE-----')",message="caBundle must be a PEM-encoded certificate" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n== api/v1alpha1/gatewayproxy_types.go ==\n'
sed -n '1,220p' api/v1alpha1/gatewayproxy_types.go
printf '\n== config/crd/bases/apisix.apache.org_gatewayproxies.yaml ==\n'
sed -n '150,190p' config/crd/bases/apisix.apache.org_gatewayproxies.yaml
printf '\n== internal/adc/translator/gatewayproxy.go ==\n'
sed -n '1,120p' internal/adc/translator/gatewayproxy.goRepository: api7/api7-ingress-controller Length of output: 13909 🏁 Script executed: #!/bin/bash
set -euo pipefail
cat > /tmp/pemtst.go <<'GO'
package main
import (
"crypto/x509"
"encoding/pem"
"fmt"
)
func main() {
// One minimal self-signed-ish CERTIFICATE block is not required for parser behavior;
// any valid certificate PEM data would do. Use a real-looking cert block from docs? No,
// just inspect parser behavior with canned inputs and report append result.
tests := map[string]string{
"valid_cert_only": `-----BEGIN CERTIFICATE-----
MIIBszCCAVmgAwIBAgIUH9hWQJ4zJr9fQfFQj3c1e1nXqk0wCgYIKoZIzj0EAwIw
EjEQMA4GA1UEAwwHZHVtbXkwHhcNMjQwMTAxMDAwMDAwWhcNMzQwMTAxMDAwMDAw
WjASMRAwDgYDVQQDDAdkdW1teTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQw
8H2Xq3dKx8VnNf8nJf6m8j2W2VQ0Wz1k2k1wP+T6R3T+8bGQG2bP1F0Q4p9j5h7W
qV6p3o+QvG9j8P2jUzBRMB0GA1UdDgQWBBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
MB8GA1UdIwQYMBaAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwDwYDVR0TAQH/BAUw
AwEB/zAKBggqhkjOPQQDAgNJADBGAiEA0Q==
-----END CERTIFICATE-----
`,
"valid_cert_plus_garbage": `-----BEGIN CERTIFICATE-----
MIIBszCCAVmgAwIBAgIUH9hWQJ4zJr9fQfFQj3c1e1nXqk0wCgYIKoZIzj0EAwIw
EjEQMA4GA1UEAwwHZHVtbXkwHhcNMjQwMTAxMDAwMDAwWhcNMzQwMTAxMDAwMDAw
WjASMRAwDgYDVQQDDAdkdW1teTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQw
8H2Xq3dKx8VnNf8nJf6m8j2W2VQ0Wz1k2k1wP+T6R3T+8bGQG2bP1F0Q4p9j5h7W
qV6p3o+QvG9j8P2jUzBRMB0GA1UdDgQWBBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
MB8GA1UdIwQYMBaAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwDwYDVR0TAQH/BAUw
AwEB/zAKBggqhkjOPQQDAgNJADBGAiEA0Q==
-----END CERTIFICATE-----
garbage`,
"garbage_then_valid_cert": `garbage
-----BEGIN CERTIFICATE-----
MIIBszCCAVmgAwIBAgIUH9hWQJ4zJr9fQfFQj3c1e1nXqk0wCgYIKoZIzj0EAwIw
EjEQMA4GA1UEAwwHZHVtbXkwHhcNMjQwMTAxMDAwMDAwWhcNMzQwMTAxMDAwMDAw
WjASMRAwDgYDVQQDDAdkdW1teTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQw
8H2Xq3dKx8VnNf8nJf6m8j2W2VQ0Wz1k2k1wP+T6R3T+8bGQG2bP1F0Q4p9j5h7W
qV6p3o+QvG9j8P2jUzBRMB0GA1UdDgQWBBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
MB8GA1UdIwQYMBaAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwDwYDVR0TAQH/BAUw
AwEB/zAKBggqhkjOPQQDAgNJADBGAiEA0Q==
-----END CERTIFICATE-----
`,
"header_only": `-----BEGIN CERTIFICATE-----`,
"non_cert_pem": `-----BEGIN FOO-----
abcd
-----END FOO-----`,
}
for name, s := range tests {
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM([]byte(s))
fmt.Printf("%s: ok=%v subjects=%d firstBlock=%q\n", name, ok, len(pool.Subjects()), firstBlockType(s))
}
}
func firstBlockType(s string) string {
b, _ := pem.Decode([]byte(s))
if b == nil {
return "nil"
}
return b.Type
}
GO
go run /tmp/pemtst.goRepository: api7/api7-ingress-controller Length of output: 469 🏁 Script executed: #!/bin/bash
set -euo pipefail
cat /tmp/coderabbit-shell-logs/shell-output-*.log | tail -n +1 >/dev/nullRepository: api7/api7-ingress-controller Length of output: 246 🏁 Script executed: #!/bin/bash
set -euo pipefail
bundle=""
for f in /etc/ssl/certs/ca-certificates.crt /etc/ssl/cert.pem /etc/pki/tls/certs/ca-bundle.crt; do
if [ -f "$f" ]; then bundle="$f"; break; fi
done
if [ -z "$bundle" ]; then
echo "no system CA bundle found" >&2
exit 1
fi
cert=$(awk '
BEGIN{p=0}
/BEGIN CERTIFICATE/ {p=1}
p {print}
/END CERTIFICATE/ {exit}
' "$bundle")
cat > /tmp/pemtst.go <<'GO'
package main
import (
"crypto/x509"
"fmt"
)
func check(name, s string) {
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM([]byte(s))
fmt.Printf("%s: ok=%v subjects=%d\n", name, ok, len(pool.Subjects()))
}
func main() {
valid := CERTDATA
check("valid_only", valid)
check("valid_plus_garbage", valid+"\nGARBAGE\n")
check("valid_plus_noncert_pem", valid+"\n-----BEGIN FOO-----\na\n-----END FOO-----\n")
check("garbage_plus_valid", "GARBAGE\n"+valid)
check("two_valid", valid+"\n"+valid)
}
GO
python3 - <<'PY'
from pathlib import Path
p = Path('/tmp/pemtst.go')
s = p.read_text()
cert = Path('/tmp/cert.pem').write_text("""__CERT__""")
PYRepository: api7/api7-ingress-controller Length of output: 166 🏁 Script executed: #!/bin/bash
set -euo pipefail
bundle=""
for f in /etc/ssl/certs/ca-certificates.crt /etc/ssl/cert.pem /etc/pki/tls/certs/ca-bundle.crt; do
if [ -f "$f" ]; then bundle="$f"; break; fi
done
if [ -z "$bundle" ]; then
echo "no system CA bundle found" >&2
exit 1
fi
cert_file=/tmp/one_cert.pem
awk '
BEGIN{p=0}
/BEGIN CERTIFICATE/ {p=1}
p {print}
/END CERTIFICATE/ {exit}
' "$bundle" > "$cert_file"
python3 - <<'PY'
from pathlib import Path
cert = Path('/tmp/one_cert.pem').read_text()
go = f'''package main
import (
"crypto/x509"
"fmt"
)
func check(name, s string) {{
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM([]byte(s))
fmt.Printf("%s: ok=%v subjects=%d\\n", name, ok, len(pool.Subjects()))
}}
func main() {{
valid := {cert!r}
check("valid_only", valid)
check("valid_plus_garbage", valid+"\\nGARBAGE\\n")
check("valid_plus_noncert_pem", valid+"\\n-----BEGIN FOO-----\\na\\n-----END FOO-----\\n")
check("garbage_plus_valid", "GARBAGE\\n"+valid)
check("two_valid", valid+"\\n"+valid)
}}
'''
Path('/tmp/pemtst.go').write_text(go)
PY
go run /tmp/pemtst.goRepository: api7/api7-ingress-controller Length of output: 253 🏁 Script executed: #!/bin/bash
set -euo pipefail
bundle=""
for f in /etc/ssl/certs/ca-certificates.crt /etc/ssl/cert.pem /etc/pki/tls/certs/ca-bundle.crt; do
if [ -f "$f" ]; then bundle="$f"; break; fi
done
if [ -z "$bundle" ]; then
echo "no system CA bundle found" >&2
exit 1
fi
awk '
BEGIN{p=0}
/BEGIN CERTIFICATE/ {p=1}
p {print}
/END CERTIFICATE/ {exit}
' "$bundle" > /tmp/one_cert.pem
python3 - <<'PY'
from pathlib import Path
cert = Path('/tmp/one_cert.pem').read_text()
go = f'''package main
import (
"crypto/x509"
"fmt"
)
func check(name, s string) {{
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM([]byte(s))
fmt.Printf("%s: ok=%v subjects=%d\\n", name, ok, len(pool.Subjects()))
}}
func main() {{
valid := {cert!r}
check("valid_only", valid)
check("valid_plus_garbage", valid+"\\nGARBAGE\\n")
check("valid_plus_noncert_pem", valid+"\\n-----BEGIN FOO-----\\na\\n-----END FOO-----\\n")
check("garbage_plus_valid", "GARBAGE\\n"+valid)
check("two_valid", valid+"\\n"+valid)
}}
'''
Path('/tmp/pemtst.go').write_text(go)
PY
go run /tmp/pemtst.goRepository: api7/api7-ingress-controller Length of output: 253 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '== caBundle references ==\n'
rg -n "caBundle|CaBundle" api internal config test . -g '!**/vendor/**'
printf '\n== relevant tests near gatewayproxy ==\n'
fd -a 'gatewayproxy' api internal test config | sed -n '1,120p'Repository: api7/api7-ingress-controller Length of output: 8992 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Find tests or docs around gateway proxy control-plane validation.
rg -n "caBundle|AppendCertsFromPEM|ControlPlaneProvider|GatewayProxyProvider" \
api internal test config docs . \
-g '!**/vendor/**' -g '!**/dist/**' -g '!**/build/**'Repository: api7/api7-ingress-controller Length of output: 12292 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Probe AppendCertsFromPEM with a known real certificate and trailing garbage.
bundle=""
for f in /etc/ssl/certs/ca-certificates.crt /etc/ssl/cert.pem /etc/pki/tls/certs/ca-bundle.crt; do
if [ -f "$f" ]; then bundle="$f"; break; fi
done
if [ -z "$bundle" ]; then
echo "no system CA bundle found" >&2
exit 1
fi
cert_file=/tmp/one_cert.pem
awk '
BEGIN{p=0}
/BEGIN CERTIFICATE/ {p=1}
p {print}
/END CERTIFICATE/ {exit}
' "$bundle" > "$cert_file"
python3 - <<'PY'
from pathlib import Path
cert = Path('/tmp/one_cert.pem').read_text()
go = f'''package main
import (
"crypto/x509"
"fmt"
)
func check(name, s string) {{
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM([]byte(s))
fmt.Printf("%s: ok=%v subjects=%d\\n", name, ok, len(pool.Subjects()))
}}
func main() {{
valid := {cert!r}
check("valid_only", valid)
check("valid_plus_garbage", valid+"\\nGARBAGE\\n")
check("garbage_plus_valid", "GARBAGE\\n"+valid)
check("valid_plus_noncert_pem", valid+"\\n-----BEGIN FOO-----\\na\\n-----END FOO-----\\n")
}}
'''
Path('/tmp/pemtst.go').write_text(go)
PY
go run /tmp/pemtst.goRepository: api7/api7-ingress-controller Length of output: 253 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '== internal/adc/translator/gatewayproxy_test.go ==\n'
sed -n '1,180p' internal/adc/translator/gatewayproxy_test.go
printf '\n== internal/webhook/v1/gatewayproxy_webhook_test.go ==\n'
sed -n '1,180p' internal/webhook/v1/gatewayproxy_webhook_test.goRepository: api7/api7-ingress-controller Length of output: 9191 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Better probe using a real PEM block and JSON-escaped Go string.
bundle=""
for f in /etc/ssl/certs/ca-certificates.crt /etc/ssl/cert.pem /etc/pki/tls/certs/ca-bundle.crt; do
if [ -f "$f" ]; then bundle="$f"; break; fi
done
if [ -z "$bundle" ]; then
echo "no system CA bundle found" >&2
exit 1
fi
awk '
BEGIN{p=0}
/BEGIN CERTIFICATE/ {p=1}
p {print}
/END CERTIFICATE/ {exit}
' "$bundle" > /tmp/one_cert.pem
python3 - <<'PY'
from pathlib import Path
import json
cert = Path('/tmp/one_cert.pem').read_text()
go = f'''package main
import (
"crypto/x509"
"fmt"
)
func check(name, s string) {{
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM([]byte(s))
fmt.Printf("%s: ok=%v subjects=%d\\n", name, ok, len(pool.Subjects()))
}}
func main() {{
valid := {json.dumps(cert)}
check("valid_only", valid)
check("valid_plus_garbage", valid+"\\nGARBAGE\\n")
check("garbage_plus_valid", "GARBAGE\\n"+valid)
check("valid_plus_noncert_pem", valid+"\\n-----BEGIN FOO-----\\na\\n-----END FOO-----\\n")
}}
'''
Path('/tmp/pemtst.go').write_text(go)
PY
go run /tmp/pemtst.goRepository: api7/api7-ingress-controller Length of output: 318 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Focus the docs/tests search on gatewayproxy validation behavior.
rg -n "invalid caBundle|caBundle.*PEM|AppendCertsFromPEM|tlsVerify is disabled|GatewayProxyToConfigCaBundle" \
internal/adc/translator/gatewayproxy_test.go \
internal/webhook/v1/gatewayproxy_webhook_test.go \
internal/webhook/v1/adc_validation_test.go \
docs/en/latest/reference/api-reference.mdRepository: api7/api7-ingress-controller Length of output: 710 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '== internal/webhook/v1/gatewayproxy_webhook.go ==\n'
sed -n '1,220p' internal/webhook/v1/gatewayproxy_webhook.go
printf '\n== internal/webhook/v1/adc_validation_test.go ==\n'
sed -n '1,180p' internal/webhook/v1/adc_validation_test.go
printf '\n== internal/webhook/v1/gatewayproxy_webhook_test.go ==\n'
sed -n '1,180p' internal/webhook/v1/gatewayproxy_webhook_test.goRepository: api7/api7-ingress-controller Length of output: 16366 🌐 Web query:
💡 Result: In the Go programming language, the crypto/x509.CertPool.AppendCertsFromPEM method handles PEM-encoded data by attempting to parse a series of certificates [1][2][3]. Its behavior regarding "garbage" (data that is not a valid PEM block or a valid certificate) is permissive: it silently skips any data that does not conform to the expected format [2][3]. Specifically, the function operates in a loop that uses pem.Decode to extract PEM blocks [2][4][3]: 1. If pem.Decode returns nil (indicating no more PEM blocks are found), the function breaks the loop [2][4][3]. Any remaining data at that point is treated as "trailing garbage" and is ignored without returning an error [2][3]. 2. If a PEM block is found but it does not have the type "CERTIFICATE" or contains headers, the function ignores that block and continues to the next one [2][3]. 3. If the block is a valid PEM "CERTIFICATE" but cannot be parsed by x509.ParseCertificate, the error is ignored, and the function continues processing the remaining data [2][3]. Because of this silent skipping, AppendCertsFromPEM will return true as long as at least one valid certificate is found and added to the pool [2][3]. It does not report whether invalid data, non-certificate blocks, or malformed certificate blocks were present [2][3]. Developers requiring strict validation of a PEM bundle (e.g., to ensure no invalid or unexpected data exists) should implement manual parsing using encoding/pem and x509.ParseCertificate to inspect every block individually [5]. Citations:
Tighten 📍 Affects 3 files
🤖 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This remains valid after the translator parser follow-up: a value containing only There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== API declaration =='
sed -n '115,150p' api/v1alpha1/gatewayproxy_types.go
printf '%s\n' '== Generated CRD caBundle schema =='
rg -n -A12 -B8 'caBundle|caBundle must be a PEM-encoded certificate' \
config/crd/bases/apisix.apache.org_gatewayproxies.yaml \
config/crd-nocel/apisix.apache.org_v2.yaml
printf '%s\n' '== GatewayProxy admission tests and helpers =='
ast-grep outline internal/webhook/v1/gatewayproxy_webhook_test.go --items all
rg -n -A12 -B8 'GatewayProxy|ControlPlaneProvider|caBundle|admission|validate' \
internal/webhook/v1/gatewayproxy_webhook_test.go \
internal/webhook/v1/gatewayproxy_webhook.goLength of output: 51590 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Admission and CRD validation test harnesses =='
rg -n -i -A8 -B5 \
'envtest|kube-apiserver|CustomResourceDefinition|x-kubernetes-validations|CEL|admission.*valid|validat.*admission|InstallCRDs|CRDDirectoryPaths' \
--glob '*_test.go' \
--glob '!**/vendor/**' \
.
printf '%s\n' '== GatewayProxy test files =='
fd -a -t f 'gatewayproxy.*(_test)?\.go|.*gatewayproxy.*\.ya?ml' . | sortLength of output: 13887
You are interacting with an AI system. |
||
| type ControlPlaneProvider struct { | ||
| // Mode specifies the mode of control plane provider. | ||
| // Can be `apisix` or `apisix-standalone`. | ||
|
|
@@ -136,6 +137,13 @@ type ControlPlaneProvider struct { | |
| // +optional | ||
| TlsVerify *bool `json:"tlsVerify,omitempty"` | ||
|
|
||
| // CaBundle is a PEM-encoded CA certificate (or bundle) used to verify the | ||
| // control plane's TLS certificate, in place of the system trust store. | ||
| // Set it when the control plane uses a self-signed or private CA certificate. | ||
| // It has no effect when tlsVerify is false. | ||
| // +optional | ||
| CaBundle string `json:"caBundle,omitempty"` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P1] Update the Helm-bundled CRD before exposing this field. |
||
|
|
||
| // Auth specifies the authentication configuration. | ||
| // +kubebuilder:validation:Required | ||
| Auth ControlPlaneAuth `json:"auth"` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,7 +84,11 @@ type ADCServerOpts struct { | |
| LabelSelector map[string]string `json:"labelSelector,omitempty"` | ||
| IncludeResourceType []string `json:"includeResourceType,omitempty"` | ||
| TlsSkipVerify *bool `json:"tlsSkipVerify,omitempty"` | ||
| CacheKey string `json:"cacheKey"` | ||
| // CaCert is the PEM-encoded CA certificate (or bundle) the ADC server verifies | ||
| // the control plane against. Older ADC servers ignore it, and omitempty keeps | ||
| // requests without a CA bundle byte for byte what they were. | ||
| CaCert string `json:"caCert,omitempty"` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P1] Ship an ADC version that honors |
||
| CacheKey string `json:"cacheKey"` | ||
| // BypassCache is only accepted by the /sync task of ADC >= 0.27.0. Both ADC task | ||
| // schemas reject unknown fields, so omitempty is what keeps every other request -- | ||
| // /validate, and every sync that is not recovering from a rejection -- byte for byte | ||
|
|
@@ -103,6 +107,7 @@ func (r ADCServerRequest) MarshalLog() any { | |
| "labelSelector": r.Task.Opts.LabelSelector, | ||
| "includeResourceType": r.Task.Opts.IncludeResourceType, | ||
| "tlsSkipVerify": r.Task.Opts.TlsSkipVerify, | ||
| "hasCaCert": r.Task.Opts.CaCert != "", | ||
| "cacheKey": r.Task.Opts.CacheKey, | ||
| "config": r.Task.Config.MarshalLog(), | ||
| } | ||
|
|
@@ -244,7 +249,7 @@ func (e *HTTPADCExecutor) runHTTPSyncForSingleServer(ctx context.Context, server | |
| } | ||
|
|
||
| // Build HTTP request | ||
| req, err := e.buildHTTPRequest(ctx, serverAddr, config, labels, types, resources, http.MethodPut, pathSync) | ||
| req, err := e.buildHTTPRequest(ctx, serverAddr, config, labels, types, resources, pathSync) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to build HTTP request: %w", err) | ||
| } | ||
|
|
@@ -278,7 +283,7 @@ func (e *HTTPADCExecutor) runHTTPValidateForSingleServer(ctx context.Context, se | |
| return fmt.Errorf("failed to load resources from file %s: %w", filePath, err) | ||
| } | ||
|
|
||
| req, err := e.buildHTTPRequest(ctx, serverAddr, config, labels, types, resources, http.MethodPut, pathValidate) | ||
| req, err := e.buildHTTPRequest(ctx, serverAddr, config, labels, types, resources, pathValidate) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to build validate request: %w", err) | ||
| } | ||
|
|
@@ -349,7 +354,7 @@ func (e *HTTPADCExecutor) loadResourcesFromFile(filePath string) (*adctypes.Reso | |
| } | ||
|
|
||
| // buildHTTPRequest builds the HTTP request for ADC Server | ||
| func (e *HTTPADCExecutor) buildHTTPRequest(ctx context.Context, serverAddr string, config adctypes.Config, labels map[string]string, types []string, resources *adctypes.Resources, method string, path string) (*http.Request, error) { | ||
| func (e *HTTPADCExecutor) buildHTTPRequest(ctx context.Context, serverAddr string, config adctypes.Config, labels map[string]string, types []string, resources *adctypes.Resources, path string) (*http.Request, error) { | ||
| // Prepare request body | ||
| tlsVerify := config.TlsVerify | ||
| bypassCache := path == pathSync && config.BypassCache | ||
|
|
@@ -362,6 +367,7 @@ func (e *HTTPADCExecutor) buildHTTPRequest(ctx context.Context, serverAddr strin | |
| LabelSelector: labels, | ||
| IncludeResourceType: types, | ||
| TlsSkipVerify: ptr.To(!tlsVerify), | ||
| CaCert: config.CaBundle, | ||
| CacheKey: config.Name, | ||
| BypassCache: bypassCache, | ||
| }, | ||
|
|
@@ -385,10 +391,11 @@ func (e *HTTPADCExecutor) buildHTTPRequest(ctx context.Context, serverAddr strin | |
| "labelSelector", labels, | ||
| "includeResourceType", types, | ||
| "tlsSkipVerify", !tlsVerify, | ||
| "hasCaCert", config.CaBundle != "", | ||
| ) | ||
|
|
||
| // Create HTTP request | ||
| req, err := http.NewRequestWithContext(ctx, method, e.serverURL+path, bytes.NewBuffer(jsonData)) | ||
| req, err := http.NewRequestWithContext(ctx, http.MethodPut, e.serverURL+path, bytes.NewBuffer(jsonData)) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to create HTTP request: %w", err) | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: api7/api7-ingress-controller
Length of output: 10521
🏁 Script executed:
Repository: api7/api7-ingress-controller
Length of output: 11607
Handle Windows ADC archives in the download rule.
CI intentionally uses
ADC_VERSION=devin the E2E workflows. Thev0.29.0Linux and macOS assets match the.tar.gzdownload rule, but its Windows assets use.zip. If Windows is supported, select the correct archive format and extraction command.🤖 Prompt for AI Agents