Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 1 addition & 166 deletions cmd/ingress-operator/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,24 @@ package main

import (
"bytes"
"context"
"fmt"
"io/ioutil"
"os"

"github.com/ghodss/yaml"
"github.com/spf13/cobra"
"gopkg.in/fsnotify.v1"

"github.com/openshift/cluster-ingress-operator/pkg/dns"
awsdns "github.com/openshift/cluster-ingress-operator/pkg/dns/aws"
azuredns "github.com/openshift/cluster-ingress-operator/pkg/dns/azure"
gcpdns "github.com/openshift/cluster-ingress-operator/pkg/dns/gcp"
"github.com/openshift/cluster-ingress-operator/pkg/manifests"
"github.com/openshift/cluster-ingress-operator/pkg/operator"
operatorclient "github.com/openshift/cluster-ingress-operator/pkg/operator/client"
operatorconfig "github.com/openshift/cluster-ingress-operator/pkg/operator/config"
statuscontroller "github.com/openshift/cluster-ingress-operator/pkg/operator/controller/status"

configv1 "github.com/openshift/api/config/v1"

corev1 "k8s.io/api/core/v1"

"k8s.io/apimachinery/pkg/types"

"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/metrics"
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
)

const (
// cloudCredentialsSecretName is the name of the secret in the
// operator's namespace that will hold the credentials that the operator
// will use to authenticate with the cloud API.
cloudCredentialsSecretName = "cloud-credentials"

// defaultTrustedCABundle is the fully qualified path of the trusted CA bundle
// that is mounted from configmap openshift-ingress-operator/trusted-ca.
defaultTrustedCABundle = "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"
Expand Down Expand Up @@ -94,52 +75,23 @@ func NewStartCommand() *cobra.Command {
func start(opts *StartOptions) error {
metrics.DefaultBindAddress = opts.MetricsListenAddr

// Get a kube client.
kubeConfig, err := config.GetConfig()
if err != nil {
return fmt.Errorf("failed to get kube config: %v", err)
}
kubeClient, err := operatorclient.NewClient(kubeConfig)
if err != nil {
return fmt.Errorf("failed to create kube client: %v", err)
}

log.Info("using operator namespace", "namespace", opts.OperatorNamespace)

if opts.ReleaseVersion == statuscontroller.UnknownVersionValue {
log.Info("Warning: no release version is specified", "release version", statuscontroller.UnknownVersionValue)
}

// Retrieve the cluster infrastructure config.
infraConfig := &configv1.Infrastructure{}
err = kubeClient.Get(context.TODO(), types.NamespacedName{Name: "cluster"}, infraConfig)
if err != nil {
return fmt.Errorf("failed to get infrastructure 'config': %v", err)
}

dnsConfig := &configv1.DNS{}
err = kubeClient.Get(context.TODO(), types.NamespacedName{Name: "cluster"}, dnsConfig)
if err != nil {
return fmt.Errorf("failed to get dns 'cluster': %v", err)
}

platformStatus, err := getPlatformStatus(kubeClient, infraConfig)
if err != nil {
return fmt.Errorf("failed to get platform status: %v", err)
}

operatorConfig := operatorconfig.Config{
OperatorReleaseVersion: opts.ReleaseVersion,
Namespace: opts.OperatorNamespace,
IngressControllerImage: opts.IngressControllerImage,
}

// Set up the DNS manager.
dnsProvider, err := createDNSProvider(kubeClient, operatorConfig, dnsConfig, platformStatus)
if err != nil {
return fmt.Errorf("failed to create DNS manager: %v", err)
}

// Set up the channels for the watcher and operator.
stop := make(chan struct{})
signal := signals.SetupSignalHandler()
Expand Down Expand Up @@ -201,126 +153,9 @@ func start(opts *StartOptions) error {
}()

// Set up and start the operator.
op, err := operator.New(operatorConfig, dnsProvider, kubeConfig)
op, err := operator.New(operatorConfig, kubeConfig)
if err != nil {
return fmt.Errorf("failed to create operator: %v", err)
}
return op.Start(stop)
}

// createDNSManager creates a DNS manager compatible with the given cluster
// configuration.
func createDNSProvider(cl client.Client, operatorConfig operatorconfig.Config, dnsConfig *configv1.DNS, platformStatus *configv1.PlatformStatus) (dns.Provider, error) {
// If no DNS configuration is provided, don't try to set up provider clients.
// TODO: the provider configuration can be refactored into the provider
// implementations themselves, so this part of the code won't need to
// know anything about the provider setup beyond picking the right implementation.
// Then, it would be safe to always use the appropriate provider for the platform
// and let the provider surface configuration errors if DNS records are actually
// created to exercise the provider.
if dnsConfig.Spec.PrivateZone == nil && dnsConfig.Spec.PublicZone == nil {
log.Info("using fake DNS provider because no public or private zone is defined in the cluster DNS configuration")
return &dns.FakeProvider{}, nil
}

var dnsProvider dns.Provider
userAgent := fmt.Sprintf("OpenShift/%s (ingress-operator)", operatorConfig.OperatorReleaseVersion)

switch platformStatus.Type {
case configv1.AWSPlatformType:
creds := &corev1.Secret{}
err := cl.Get(context.TODO(), types.NamespacedName{Namespace: operatorConfig.Namespace, Name: cloudCredentialsSecretName}, creds)
if err != nil {
return nil, fmt.Errorf("failed to get cloud credentials from secret %s/%s: %v", creds.Namespace, creds.Name, err)
}
provider, err := awsdns.NewProvider(awsdns.Config{
AccessID: string(creds.Data["aws_access_key_id"]),
AccessKey: string(creds.Data["aws_secret_access_key"]),
Region: platformStatus.AWS.Region,
}, operatorConfig.OperatorReleaseVersion)
if err != nil {
return nil, fmt.Errorf("failed to create AWS DNS manager: %v", err)
}
dnsProvider = provider
case configv1.AzurePlatformType:
creds := &corev1.Secret{}
err := cl.Get(context.TODO(), types.NamespacedName{Namespace: operatorConfig.Namespace, Name: cloudCredentialsSecretName}, creds)
if err != nil {
return nil, fmt.Errorf("failed to get cloud credentials from secret %s/%s: %v", creds.Namespace, creds.Name, err)
}
provider, err := azuredns.NewProvider(azuredns.Config{
Environment: "AzurePublicCloud",
ClientID: string(creds.Data["azure_client_id"]),
ClientSecret: string(creds.Data["azure_client_secret"]),
TenantID: string(creds.Data["azure_tenant_id"]),
SubscriptionID: string(creds.Data["azure_subscription_id"]),
}, operatorConfig.OperatorReleaseVersion)
if err != nil {
return nil, fmt.Errorf("failed to create Azure DNS manager: %v", err)
}
dnsProvider = provider
case configv1.GCPPlatformType:
creds := &corev1.Secret{}
err := cl.Get(context.TODO(), types.NamespacedName{Namespace: operatorConfig.Namespace, Name: cloudCredentialsSecretName}, creds)
if err != nil {
return nil, fmt.Errorf("failed to get cloud credentials from secret %s/%s: %v", creds.Namespace, creds.Name, err)
}
provider, err := gcpdns.New(gcpdns.Config{
Project: platformStatus.GCP.ProjectID,
CredentialsJSON: creds.Data["service_account.json"],
UserAgent: userAgent,
})
if err != nil {
return nil, fmt.Errorf("failed to create GCP DNS provider: %v", err)
}
dnsProvider = provider
default:
dnsProvider = &dns.FakeProvider{}
}
return dnsProvider, nil
}

// getPlatformStatus provides a backwards-compatible way to look up platform status. AWS is the
// special case. 4.1 clusters on AWS expose the region config only through install-config. New AWS clusters
// and all other 4.2+ platforms are configured via platform status.
func getPlatformStatus(client client.Client, infra *configv1.Infrastructure) (*configv1.PlatformStatus, error) {
if status := infra.Status.PlatformStatus; status != nil {
// Only AWS needs backwards compatibility with install-config
if status.Type != configv1.AWSPlatformType {
return status, nil
}

// Check whether the cluster config is already migrated
if status.AWS != nil && len(status.AWS.Region) > 0 {
return status, nil
}
}

// Otherwise build a platform status from the deprecated install-config
type installConfig struct {
Platform struct {
AWS struct {
Region string `json:"region"`
} `json:"aws"`
} `json:"platform"`
}
clusterConfigName := types.NamespacedName{Namespace: "kube-system", Name: "cluster-config-v1"}
clusterConfig := &corev1.ConfigMap{}
if err := client.Get(context.TODO(), clusterConfigName, clusterConfig); err != nil {
return nil, fmt.Errorf("failed to get configmap %s: %v", clusterConfigName, err)
}
data, ok := clusterConfig.Data["install-config"]
if !ok {
return nil, fmt.Errorf("missing install-config in configmap")
}
var ic installConfig
if err := yaml.Unmarshal([]byte(data), &ic); err != nil {
return nil, fmt.Errorf("invalid install-config: %v\njson:\n%s", err, data)
}
return &configv1.PlatformStatus{
Type: infra.Status.Platform,
AWS: &configv1.AWSPlatformStatus{
Region: ic.Platform.AWS.Region,
},
}, nil
}
2 changes: 2 additions & 0 deletions manifests/00-cluster-role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ rules:
- apiGroups:
- config.openshift.io
resources:
- dnses
- infrastructures
- ingresses
verbs:
- list
Expand Down
8 changes: 4 additions & 4 deletions pkg/manifests/bindata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading