blob: bbe855e59c9e52ca4d6d6d86e38053ef4cc4e83f [file] [log] [blame]
// 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 bootstrap
import (
"context"
"fmt"
"os"
"path/filepath"
)
import (
"istio.io/pkg/env"
"istio.io/pkg/log"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
import (
"github.com/apache/dubbo-go-pixiu/pilot/pkg/features"
"github.com/apache/dubbo-go-pixiu/pkg/kube/inject"
"github.com/apache/dubbo-go-pixiu/pkg/webhooks"
)
const (
// Name of the webhook config in the config - no need to change it.
webhookName = "sidecar-injector.istio.io"
// defaultInjectorConfigMapName is the default name of the ConfigMap with the injection config
// The actual name can be different - use getInjectorConfigMapName
defaultInjectorConfigMapName = "istio-sidecar-injector"
)
var injectionEnabled = env.RegisterBoolVar("INJECT_ENABLED", true, "Enable mutating webhook handler.")
func (s *Server) initSidecarInjector(args *PilotArgs) (*inject.Webhook, error) {
// currently the constant: "./var/lib/istio/inject"
injectPath := args.InjectionOptions.InjectionDirectory
if injectPath == "" || !injectionEnabled.Get() {
log.Infof("Skipping sidecar injector, injection path is missing or disabled.")
return nil, nil
}
// If the injection config exists either locally or remotely, we will set up injection.
var watcher inject.Watcher
if _, err := os.Stat(filepath.Join(injectPath, "config")); !os.IsNotExist(err) {
configFile := filepath.Join(injectPath, "config")
valuesFile := filepath.Join(injectPath, "values")
watcher, err = inject.NewFileWatcher(configFile, valuesFile)
if err != nil {
return nil, err
}
} else if s.kubeClient != nil {
configMapName := getInjectorConfigMapName(args.Revision)
cms := s.kubeClient.CoreV1().ConfigMaps(args.Namespace)
if _, err := cms.Get(context.TODO(), configMapName, metav1.GetOptions{}); err != nil {
if errors.IsNotFound(err) {
log.Infof("Skipping sidecar injector, template not found")
return nil, nil
}
return nil, err
}
watcher = inject.NewConfigMapWatcher(s.kubeClient, args.Namespace, configMapName, "config", "values")
} else {
log.Infof("Skipping sidecar injector, template not found")
return nil, nil
}
log.Info("initializing sidecar injector")
parameters := inject.WebhookParameters{
Watcher: watcher,
Env: s.environment,
Mux: s.httpsMux,
Revision: args.Revision,
}
wh, err := inject.NewWebhook(parameters)
if err != nil {
return nil, fmt.Errorf("failed to create injection webhook: %v", err)
}
// Patch cert if a webhook config name is provided.
// This requires RBAC permissions - a low-priv Istiod should not attempt to patch but rely on
// operator or CI/CD
if features.InjectionWebhookConfigName != "" {
s.addStartFunc(func(stop <-chan struct{}) error {
// No leader election - different istiod revisions will patch their own cert.
// update webhook configuration by watching the cabundle
patcher, err := webhooks.NewWebhookCertPatcher(s.kubeClient, args.Revision, webhookName, s.istiodCertBundleWatcher)
if err != nil {
log.Errorf("failed to create webhook cert patcher: %v", err)
return nil
}
go patcher.Run(stop)
return nil
})
}
s.addStartFunc(func(stop <-chan struct{}) error {
wh.Run(stop)
return nil
})
return wh, nil
}
func getInjectorConfigMapName(revision string) string {
name := defaultInjectorConfigMapName
if revision == "" || revision == "default" {
return name
}
return name + "-" + revision
}