Skip to content

Commit

Permalink
HOSTEDCP-1000: Add user CA(s) to ocm-trusted-ca-bundle ConfigMap
Browse files Browse the repository at this point in the history
https://issues.redhat.com/browse/HOSTEDCP-1000
Adds the CA certificates for mirror registries specified by the user
to the ocm-trusted-ca-bundle injected in
openshift#2437 so that these
certificates may be used to pull images from these mirror registries.
  • Loading branch information
CrystalChun committed Jul 31, 2023
1 parent aa6878b commit d1c70ca
Showing 1 changed file with 134 additions and 4 deletions.
138 changes: 134 additions & 4 deletions hypershift-operator/main.go
Expand Up @@ -15,8 +15,11 @@ limitations under the License.
package main

import (
"bytes"
"context"
"errors"
"fmt"
"io/ioutil"
"os"
"strings"
"time"
Expand All @@ -28,10 +31,12 @@ import (

"github.com/aws/aws-sdk-go/service/s3"
"github.com/go-logr/logr"
configapi "github.com/openshift/api/config/v1"
operatorv1 "github.com/openshift/api/operator/v1"
hyperapi "github.com/openshift/hypershift/api"
hyperv1 "github.com/openshift/hypershift/api/v1beta1"
awsutil "github.com/openshift/hypershift/cmd/infra/aws/util"
"github.com/openshift/hypershift/cmd/util"
"github.com/openshift/hypershift/hypershift-operator/controllers/hostedcluster"
"github.com/openshift/hypershift/hypershift-operator/controllers/nodepool"
"github.com/openshift/hypershift/hypershift-operator/controllers/platform/aws"
Expand Down Expand Up @@ -61,6 +66,10 @@ import (
)

func main() {
ctrl.SetLogger(zap.New(zap.UseDevMode(true), zap.JSONEncoder(func(o *zapcore.EncoderConfig) {
o.EncodeTime = zapcore.RFC3339TimeEncoder
})))

cmd := &cobra.Command{
Use: "hypershift-operator",
Run: func(cmd *cobra.Command, args []string) {
Expand All @@ -72,6 +81,7 @@ func main() {
cmd.Version = version.String()

cmd.AddCommand(NewStartCommand())
cmd.AddCommand(NewInitCommand())

if err := cmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
Expand All @@ -97,10 +107,6 @@ type StartOptions struct {
}

func NewStartCommand() *cobra.Command {
ctrl.SetLogger(zap.New(zap.UseDevMode(true), zap.JSONEncoder(func(o *zapcore.EncoderConfig) {
o.EncodeTime = zapcore.RFC3339TimeEncoder
})))

cmd := &cobra.Command{
Use: "run",
Short: "Runs the Hypershift operator",
Expand Down Expand Up @@ -438,3 +444,127 @@ func run(ctx context.Context, opts *StartOptions, log logr.Logger) error {
log.Info("starting manager")
return mgr.Start(ctx)
}

func NewInitCommand() *cobra.Command {
ctrl.SetLogger(zap.New(zap.UseDevMode(true), zap.JSONEncoder(func(o *zapcore.EncoderConfig) {
o.EncodeTime = zapcore.RFC3339TimeEncoder
})))

cmd := &cobra.Command{
Use: "init",
Short: "Initializes the environment for the Hypershift Operator",
}

cmd.Run = func(cmd *cobra.Command, args []string) {
ctx, cancel := context.WithCancel(ctrl.SetupSignalHandler())
defer cancel()

if err := runInit(ctx, ctrl.Log.WithName("init")); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

return cmd
}

func runInit(ctx context.Context, log logr.Logger) error {
log.Info("Initializing environment for Hypershift Operator")
client, err := util.GetClient()
if err != nil {
return err
}
config, err := ctrl.GetConfig()
if err != nil {
return err
}
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
return fmt.Errorf("unable to get discovery client: %w", err)
}
mgmtClusterCaps, err := capabilities.DetectManagementClusterCapabilities(discoveryClient)
if err != nil {
return fmt.Errorf("unable to detect management cluster capabilities: %w", err)
}

trustedCABundle := new(bytes.Buffer)
var ocmTrustedCABundle []byte
if _, err := os.Stat("/var/run/ca-trust/tls-ca-bundle.pem"); err == nil {
ocmTrustedCABundle, err = ioutil.ReadFile("/var/run/ca-trust/tls-ca-bundle.pem")
if err != nil {
return fmt.Errorf("unable to read ocm CA trust bundle file: %w", err)
}
} else if err != nil && errors.Is(err, os.ErrNotExist) {
ocmTrustedCABundle, err = ioutil.ReadFile("/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem")
if err != nil {
return fmt.Errorf("unable to read ocm CA trust bundle file: %w", err)
}
} else {
return err
}

if _, err := trustedCABundle.Write(ocmTrustedCABundle); err != nil {
return fmt.Errorf("unable to write ocm CA trust bundle to buffer: %w", err)
}

if mgmtClusterCaps.Has(capabilities.CapabilityImage) {
// Adds user-specified image registry CA bundle to the full CA trust bundle if it exists
imageRegistryCABundle, err := getImageRegistryCABundle(ctx, client)
if err != nil {
return fmt.Errorf("unable to get CA bundle for image mirror registries: %w", err)
}
if imageRegistryCABundle != nil {
if _, err := trustedCABundle.Write(imageRegistryCABundle.Bytes()); err != nil {
return fmt.Errorf("unable to write image registry CA to buffer: %w", err)
}
}
}

if err := ioutil.WriteFile("/trust-bundle/tls-ca-bundle.pem", trustedCABundle.Bytes(), 0644); err != nil {
return err
}

log.Info("Finished initializing environment for Hypershift Operator")
return nil
}

// getMgmtClusterCapabilities initializes the ManagementClusterCabilities object
// to determine if the management cluster has the listed capabilities
func getMgmtClusterCapabilities() (*capabilities.ManagementClusterCapabilities, error) {
config, err := util.GetConfig()
if err != nil {
return nil, fmt.Errorf("unable to get kubernetes config: %w", err)
}
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
return nil, fmt.Errorf("unable to get discovery client: %w", err)
}
return capabilities.DetectManagementClusterCapabilities(discoveryClient)
}

// getImageRegistryCABundle retrieves the image registry CAs listed under image.config.openshift.io
// and merges them into one CA bundle
func getImageRegistryCABundle(ctx context.Context, client crclient.Client) (*bytes.Buffer, error) {
img := &configapi.Image{}
if err := client.Get(ctx, types.NamespacedName{Name: "cluster"}, img); err != nil {
return nil, err
}
if img == nil || img.Spec.AdditionalTrustedCA.Name == "" {
return nil, nil
}
configmap := &corev1.ConfigMap{}
if err := client.Get(ctx, types.NamespacedName{Name: img.Spec.AdditionalTrustedCA.Name, Namespace: "openshift-config"}, configmap); err != nil {
return nil, err
}
if configmap.Data != nil {
// Merge all registry CA certificates together into one bundle
var buf bytes.Buffer
for _, crt := range configmap.Data {
buf.WriteString(crt)
}
if buf.Len() > 0 {
return &buf, nil
}
}
return nil, nil
}

0 comments on commit d1c70ca

Please sign in to comment.