Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions config/operator/operator_role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ rules:
- apiGroups:
- config.openshift.io
resources:
- apiservers
- proxies
verbs:
- get
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ require (
gopkg.in/evanphx/json-patch.v4 v4.12.0
)

require github.com/openshift/client-go v0.0.0-20251015124057-db0dee36e235

require (
4d63.com/gochecknoglobals v0.2.2 // indirect
cel.dev/expr v0.24.0 // indirect
Expand Down Expand Up @@ -297,6 +299,7 @@ require (
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jgautheron/goconst v1.7.1 // indirect
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
Expand Down Expand Up @@ -345,7 +348,6 @@ require (
github.com/nxadm/tail v1.4.8 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/openshift/client-go v0.0.0-20251015124057-db0dee36e235 // indirect
github.com/openshift/cloud-credential-operator v0.0.0-20240404165937-5e8812d64187 // indirect
github.com/ovirt/go-ovirt v0.0.0-20210809163552-d4276e35d3db // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
Expand All @@ -358,6 +360,7 @@ require (
github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
github.com/raeperd/recvcheck v0.2.0 // indirect
github.com/robfig/cron v1.2.0 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/ryancurrah/gomodguard v1.3.5 // indirect
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,8 @@ github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSo
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
Expand Down Expand Up @@ -921,6 +923,8 @@ github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtz
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
Expand Down
1 change: 1 addition & 0 deletions hack/app-sre/saas-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12413,6 +12413,7 @@ objects:
- apiGroups:
- config.openshift.io
resources:
- apiservers
- proxies
verbs:
- get
Expand Down
2 changes: 2 additions & 0 deletions pkg/operator/hive/dynamicclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ func (r *ReconcileHiveConfig) clientFor(blankObj runtime.Object, namespace strin
c = dc.Resource(corev1.SchemeGroupVersion.WithResource("namespaces"))
case *configv1.ProxyList, *configv1.Proxy:
c = dc.Resource(configv1.SchemeGroupVersion.WithResource("proxies"))
case *configv1.APIServerList, *configv1.APIServer:
c = dc.Resource(configv1.SchemeGroupVersion.WithResource("apiservers"))
case *corev1.SecretList, *corev1.Secret:
c = dc.Resource(corev1.SchemeGroupVersion.WithResource("secrets"))
case *corev1.ServiceAccountList, *corev1.ServiceAccount:
Expand Down
11 changes: 11 additions & 0 deletions pkg/operator/hive/hive_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func newReconciler(mgr manager.Manager) reconcile.Reconciler {
}
}

// TODO: I would think we could get `src` from `T`, no?
func mapToHiveConfig[T client.Object](r reconcile.Reconciler, src string) func(context.Context, T) []reconcile.Request {
return func(ctx context.Context, _ T) []reconcile.Request {
retval := []reconcile.Request{}
Expand Down Expand Up @@ -288,6 +289,16 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
return err
}

// APIServer is an OpenShift Kind
if r.(*ReconcileHiveConfig).isOpenShift {
// Watch the APIServer for TLS config changes
err = c.Watch(source.Kind(mgr.GetCache(), &configv1.APIServer{},
handler.TypedEnqueueRequestsFromMapFunc(mapToHiveConfig[*configv1.APIServer](r, "APIServer"))))
if err != nil {
return err
}
}

// Fetch some common configuration from the hive-operator. All hive components should all be
// using the same image, pull policy, and other common shared configurations.
operatorDeployment := &appsv1.Deployment{}
Expand Down
99 changes: 99 additions & 0 deletions pkg/operator/hive/hiveadmission.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package hive
import (
"context"
"fmt"
"strings"

"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
Expand All @@ -12,13 +13,22 @@ import (
controllerutils "github.com/openshift/hive/pkg/controller/utils"
"github.com/openshift/hive/pkg/operator/assets"
"github.com/openshift/hive/pkg/resource"
logrusutil "github.com/openshift/hive/pkg/util/logrus"

configv1 "github.com/openshift/api/config/v1"
configlistersv1 "github.com/openshift/client-go/config/listers/config/v1"
"github.com/openshift/library-go/pkg/operator/configobserver/apiserver"
"github.com/openshift/library-go/pkg/operator/resource/resourceread"
"github.com/openshift/library-go/pkg/operator/resourcesynccontroller"

admregv1 "k8s.io/api/admissionregistration/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/tools/cache"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
)

Expand Down Expand Up @@ -150,6 +160,10 @@ func (r *ReconcileHiveConfig) deployHiveAdmission(hLog log.FieldLogger, h resour
addConfigVolume(&hiveAdmDeployment.Spec.Template.Spec, r.supportedContractsConfigMapInfo(hLog), hiveAdmContainer)
addReleaseImageVerificationConfigMapEnv(hiveAdmContainer, instance)

if err := r.populateTLSConfig(hiveAdmContainer, hLog); err != nil {
return err
}

validatingWebhooks := make([]*admregv1.ValidatingWebhookConfiguration, len(webhookAssets))
for i, yaml := range webhookAssets {
validatingWebhooks[i] = readRuntimeObjectOrDie[*admregv1.ValidatingWebhookConfiguration](
Expand Down Expand Up @@ -215,6 +229,91 @@ func (r *ReconcileHiveConfig) deployHiveAdmission(hLog log.FieldLogger, h resour
return nil
}

// directAPIServerLister implements apiserver.APIServerLister by making direct API calls
type directAPIServerLister struct {
reconciler *ReconcileHiveConfig
}

// PreRunHasSynced implements configobserver.Listers, minimally, because we're not caching.
func (d *directAPIServerLister) PreRunHasSynced() []cache.InformerSynced {
return []cache.InformerSynced{}
}

// ResourceSyncer implements configobserver.Listers, but not really, because we're not caching.
func (d *directAPIServerLister) ResourceSyncer() resourcesynccontroller.ResourceSyncer {
return nil
}

func (d *directAPIServerLister) APIServerLister() configlistersv1.APIServerLister {
return &directLister{reconciler: d.reconciler}
}

// directLister implements configlistersv1.APIServerLister with direct API calls via reconciler
type directLister struct {
reconciler *ReconcileHiveConfig
}

func (d *directLister) List(selector labels.Selector) ([]*configv1.APIServer, error) {
list := &configv1.APIServerList{}
if err := d.reconciler.List(context.TODO(), list, "", metav1.ListOptions{}); err != nil {
return nil, err
}
result := make([]*configv1.APIServer, len(list.Items))
for i := range list.Items {
result[i] = &list.Items[i]
}
return result, nil
}

func (d *directLister) Get(name string) (*configv1.APIServer, error) {
apiServer := &configv1.APIServer{}
if err := d.reconciler.Get(context.TODO(), types.NamespacedName{Name: name}, apiServer); err != nil {
return nil, err
}
return apiServer, nil
}

func (r *ReconcileHiveConfig) populateTLSConfig(hiveAdmContainer *corev1.Container, hLog log.FieldLogger) error {
if !r.isOpenShift {
return nil
}
observedConfig, errs := apiserver.ObserveTLSSecurityProfileToArguments(
&directAPIServerLister{reconciler: r},
logrusutil.NewLoggingEventRecorder(hLog, "hiveadmission-tls-config"),
map[string]interface{}{})

if len(errs) > 0 {
return errors.Wrap(utilerrors.NewAggregate(errs), "failed to discover global TLS config from APIServer cluster")
}

hLog.WithField("config", observedConfig).Debug("observed TLS config")

if len(observedConfig) == 0 {
return errors.New("observed TLS config was empty")
}

asa, tlsmvk, tlscsk := "apiServerArguments", "tls-min-version", "tls-cipher-suites"

tlsmv, found, err := unstructured.NestedString(observedConfig, asa, tlsmvk)
if !found || err != nil {
return errors.Wrapf(err, "could not find %s.%s in observed TLS config %v", asa, tlsmvk, observedConfig)
}
tlscs, found, err := unstructured.NestedStringSlice(observedConfig, asa, tlscsk)
if !found || err != nil {
return errors.Wrapf(err, "could not find %s.%s in observed TLS config %v", asa, tlscsk, observedConfig)
}

// NOTE: These arguments (--tls-min-version, --tls-cipher-suites) are expected to be *absent*
// from the container we're given.
hiveAdmContainer.Command = append(
hiveAdmContainer.Command,
fmt.Sprintf("--%s=%s", tlsmvk, tlsmv),
fmt.Sprintf("--%s=%s", tlscsk, strings.Join(tlscs, ",")),
)

return nil
}

// Modern OpenShift injects two ConfigMaps into every namespace. One contains the service CA cert;
// the other the kube root CA cert.
func (r *ReconcileHiveConfig) getCACertsOpenShift(hLog log.FieldLogger, hiveNSName string) ([]byte, []byte, error) {
Expand Down
62 changes: 62 additions & 0 deletions pkg/util/logrus/eventrecorder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package logrus

import (
"context"
"fmt"

"github.com/openshift/library-go/pkg/operator/events"
log "github.com/sirupsen/logrus"
)

// loggingEventRecorder implements events.Recorder by logging to a logrus.FieldLogger
type loggingEventRecorder struct {
logger log.FieldLogger
component string
}

// NewLoggingEventRecorder creates an event recorder that logs events via logrus
func NewLoggingEventRecorder(logger log.FieldLogger, component string) events.Recorder {
return &loggingEventRecorder{
logger: logger,
component: component,
}
}

func (r *loggingEventRecorder) ComponentName() string {
return r.component
}

func (r *loggingEventRecorder) ForComponent(component string) events.Recorder {
// Return a new recorder with a modified logger and component
return &loggingEventRecorder{
logger: r.logger.WithField("component", component),
component: component,
}
}

func (r *loggingEventRecorder) WithContext(ctx context.Context) events.Recorder {
// Context doesn't affect logging, just return self
return r
}

func (r *loggingEventRecorder) WithComponentSuffix(suffix string) events.Recorder {
return r.ForComponent(fmt.Sprintf("%s-%s", r.component, suffix))
}

func (r *loggingEventRecorder) Shutdown() {}

func (r *loggingEventRecorder) Event(reason, message string) {
r.logger.WithField("reason", reason).Debug(message)
}

func (r *loggingEventRecorder) Eventf(reason, messageFmt string, args ...interface{}) {
r.Event(reason, fmt.Sprintf(messageFmt, args...))
}

func (r *loggingEventRecorder) Warning(reason, message string) {
r.logger.WithField("reason", reason).Warning(message)
}

func (r *loggingEventRecorder) Warningf(reason, messageFmt string, args ...interface{}) {
r.Warning(reason, fmt.Sprintf(messageFmt, args...))
}

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

33 changes: 33 additions & 0 deletions vendor/github.com/imdario/mergo/.gitignore

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

12 changes: 12 additions & 0 deletions vendor/github.com/imdario/mergo/.travis.yml

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

Loading