blob: a047f7584792527430a2d15d84d519fd9ed4b3fe [file] [log] [blame]
//go:build integ
// +build integ
// Copyright Istio Authors
//
// 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 filemountedcerts
import (
"context"
"fmt"
"os"
"path"
"strings"
"testing"
)
import (
v1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
import (
"github.com/apache/dubbo-go-pixiu/pkg/test/env"
"github.com/apache/dubbo-go-pixiu/pkg/test/framework"
"github.com/apache/dubbo-go-pixiu/pkg/test/framework/components/istio"
"github.com/apache/dubbo-go-pixiu/pkg/test/framework/components/namespace"
"github.com/apache/dubbo-go-pixiu/pkg/test/framework/label"
"github.com/apache/dubbo-go-pixiu/pkg/test/framework/resource"
)
var inst istio.Instance
const (
PilotCertsPath = "tests/testdata/certs/pilot"
PilotSecretName = "test-istiod-server-cred"
ProxyMetadataJSON = `
{
"FILE_MOUNTED_CERTS": "true",
"ISTIO_META_TLS_CLIENT_CERT_CHAIN": "/client-certs/cert-chain.pem",
"ISTIO_META_TLS_CLIENT_KEY": "/client-certs/key.pem",
"ISTIO_META_TLS_CLIENT_ROOT_CERT": "/client-certs/root-cert.pem",
"ISTIO_META_TLS_SERVER_CERT_CHAIN": "/server-certs/cert-chain.pem",
"ISTIO_META_TLS_SERVER_KEY": "/server-certs/key.pem",
"ISTIO_META_TLS_SERVER_ROOT_CERT": "/server-certs/root-cert.pem",
}
`
)
func TestMain(m *testing.M) {
// nolint: staticcheck
framework.
NewSuite(m).
Label(label.CustomSetup).
RequireSingleCluster().
RequireMultiPrimary().
Label("CustomSetup").
Setup(istio.Setup(&inst, setupConfig, CreateCustomIstiodSecret)).
Run()
}
func setupConfig(_ resource.Context, cfg *istio.Config) {
if cfg == nil {
return
}
cfg.ControlPlaneValues = `
components:
egressGateways:
- enabled: true
name: istio-egressgateway
k8s:
overlays:
- kind: Deployment
name: istio-egressgateway
patches:
- path: spec.template.spec.volumes[100]
value: |-
name: server-certs
secret:
secretName: ` + PilotSecretName + `
defaultMode: 420
- path: spec.template.spec.volumes[101]
value: |-
name: client-certs
secret:
secretName: ` + PilotSecretName + `
defaultMode: 420
- path: spec.template.spec.containers[0].volumeMounts[100]
value: |-
name: server-certs
mountPath: /server-certs
- path: spec.template.spec.containers[0].volumeMounts[101]
value: |-
name: client-certs
mountPath: /client-certs
ingressGateways:
- enabled: true
name: istio-ingressgateway
k8s:
overlays:
- kind: Deployment
name: istio-ingressgateway
patches:
- path: spec.template.spec.volumes[100]
value: |-
name: server-certs
secret:
secretName: ` + PilotSecretName + `
defaultMode: 420
- path: spec.template.spec.volumes[101]
value: |-
name: client-certs
secret:
secretName: ` + PilotSecretName + `
defaultMode: 420
- path: spec.template.spec.containers[0].volumeMounts[100]
value: |-
name: server-certs
mountPath: /server-certs
- path: spec.template.spec.containers[0].volumeMounts[101]
value: |-
name: client-certs
mountPath: /client-certs
pilot:
enabled: true
k8s:
overlays:
- kind: Deployment
name: istiod
patches:
- path: spec.template.spec.containers.[name:discovery].args[1001]
value: "--caCertFile=/server-certs/root-cert.pem"
- path: spec.template.spec.containers.[name:discovery].args[1002]
value: "--tlsCertFile=/server-certs/cert-chain.pem"
- path: spec.template.spec.containers.[name:discovery].args[1003]
value: "--tlsKeyFile=/server-certs/key.pem"
- path: spec.template.spec.volumes[-1]
value: |-
name: server-certs
secret:
secretName: ` + PilotSecretName + `
defaultMode: 420
- path: spec.template.spec.containers[name:discovery].volumeMounts[-1]
value: |-
name: server-certs
mountPath: /server-certs
meshConfig:
defaultConfig:
controlPlaneAuthPolicy: "MUTUAL_TLS"
proxyMetadata: ` + strings.Replace(ProxyMetadataJSON, "\n", "", -1) +
`
values:
global:
pilotCertProvider: "mycopki"
pilot:
env:
# We need to turn off the XDS Auth because test certificates only have a fixed/hardcoded identity, but the identity of the actual
# deployed test services changes on each run due to a randomly generated namespace suffixes.
# Turning the XDS-Auth ON will result in the error messages like:
# Unauthorized XDS: 10.1.0.159:41960 with identity [spiffe://cluster.local/ns/mounted-certs/sa/client client.mounted-certs.svc]:
# no identities ([spiffe://cluster.local/ns/mounted-certs/sa/client client.mounted-certs.svc]) matched istio-fd-sds-1-4523/default
XDS_AUTH: "false"
`
cfg.DeployEastWestGW = false
}
func CreateCustomIstiodSecret(ctx resource.Context) error {
systemNs, err := istio.ClaimSystemNamespace(ctx)
if err != nil {
return err
}
err = CreateCustomSecret(ctx, PilotSecretName, systemNs, PilotCertsPath)
if err != nil {
return err
}
return nil
}
func CreateCustomSecret(ctx resource.Context, name string, namespace namespace.Instance, certsPath string) error {
var privateKey, clientCert, caCert []byte
var err error
if privateKey, err = ReadCustomCertFromFile(certsPath, "key.pem"); err != nil {
return err
}
if clientCert, err = ReadCustomCertFromFile(certsPath, "cert-chain.pem"); err != nil {
return err
}
if caCert, err = ReadCustomCertFromFile(certsPath, "root-cert.pem"); err != nil {
return err
}
kubeAccessor := ctx.Clusters().Default()
secret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace.Name(),
},
Data: map[string][]byte{
"key.pem": privateKey,
"cert-chain.pem": clientCert,
"root-cert.pem": caCert,
},
}
_, err = kubeAccessor.CoreV1().Secrets(namespace.Name()).Create(context.TODO(), secret, metav1.CreateOptions{})
if err != nil {
if kerrors.IsAlreadyExists(err) {
if _, err := kubeAccessor.CoreV1().Secrets(namespace.Name()).Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil {
return fmt.Errorf("failed updating secret %s: %v", secret.Name, err)
}
} else {
return fmt.Errorf("failed creating secret %s: %v", secret.Name, err)
}
}
return nil
}
func ReadCustomCertFromFile(certsPath string, f string) ([]byte, error) {
b, err := os.ReadFile(path.Join(env.IstioSrc, certsPath, f))
if err != nil {
return nil, err
}
return b, nil
}