Skip to content

Commit

Permalink
proxy configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
tkashem committed Jul 12, 2019
1 parent 098d064 commit e95bb78
Show file tree
Hide file tree
Showing 85 changed files with 5,632 additions and 24 deletions.
7 changes: 7 additions & 0 deletions cmd/olm/main.go
Expand Up @@ -9,6 +9,7 @@ import (
"strings"
"time"

configclientset "github.com/openshift/client-go/config/clientset/versioned"
configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -155,6 +156,11 @@ func main() {
if err != nil {
log.Fatalf("error configuring client: %s", err.Error())
}
versionedConfigClient, err := configclientset.NewForConfig(config)
if err != nil {
err = fmt.Errorf("error configuring OpenShift Proxy client: %v", err)
return
}
configClient, err := configv1client.NewForConfig(config)
if err != nil {
log.Fatalf("error configuring client: %s", err.Error())
Expand All @@ -174,6 +180,7 @@ func main() {
olm.WithExternalClient(crClient),
olm.WithOperatorClient(opClient),
olm.WithRestConfig(config),
olm.WithConfigClient(versionedConfigClient),
)
if err != nil {
log.Fatalf("error configuring operator: %s", err.Error())
Expand Down
5 changes: 0 additions & 5 deletions go.sum
Expand Up @@ -204,15 +204,10 @@ github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/openshift/api v3.9.1-0.20190508214137-81d064c11ff2+incompatible h1:aZWnhm/gKLlEv4O7TRAig8MnSEKOi1q/feLnuThkk8c=
github.com/openshift/api v3.9.1-0.20190508214137-81d064c11ff2+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
github.com/openshift/api v3.9.1-0.20190710192740-0a705005be4f+incompatible h1:64VxMC9j1FJNNo/NiASMnzYni2xhj7eIoYFRTDSGEFs=
github.com/openshift/api v3.9.1-0.20190710192740-0a705005be4f+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
github.com/openshift/api v3.9.1-0.20190711201425-35c8395fe70d+incompatible h1:DryQs351pxwirONLqXVsRTr77vBpOxUVhmifAq92MlY=
github.com/openshift/api v3.9.1-0.20190711201425-35c8395fe70d+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
github.com/openshift/client-go v0.0.0-20190627172412-c44a8b61b9f4 h1:IXjGgJIWgUiN6KOqHHRwPepxM0c0sKtfQc2hX5rjLMM=
github.com/openshift/client-go v0.0.0-20190627172412-c44a8b61b9f4/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk=
github.com/openshift/client-go v3.9.0+incompatible h1:13k3Ok0B7TA2hA3bQW2aFqn6y04JaJWdk7ITTyg+Ek0=
github.com/operator-framework/go-appr v0.0.0-20180917210448-f2aef88446f2/go.mod h1:YNzwUx1i6C4dXWcffyq3yaIb0rh/K8/OvQ4vG0SNlSw=
github.com/operator-framework/operator-lifecycle-manager v0.0.0-20181023032605-e838f7fb2186/go.mod h1:Ma5ZXd4S1vmMyewWlF7aO8CZiokR7Sd8dhSfkGkNU4U=
github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190105193533-81104ffdc4fb/go.mod h1:XMyE4n2opUK4N6L45YGQkXXi8F9fD7XDYFv/CsS6V5I=
Expand Down

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

51 changes: 46 additions & 5 deletions pkg/controller/install/deployment.go
Expand Up @@ -43,6 +43,7 @@ type StrategyDeploymentInstaller struct {
owner ownerutil.Owner
previousStrategy Strategy
templateAnnotations map[string]string
chain ApplyFuncChain
}

func (d *StrategyDetailsDeployment) GetStrategyName() string {
Expand All @@ -52,26 +53,55 @@ func (d *StrategyDetailsDeployment) GetStrategyName() string {
var _ Strategy = &StrategyDetailsDeployment{}
var _ StrategyInstaller = &StrategyDeploymentInstaller{}

func NewStrategyDeploymentInstaller(strategyClient wrappers.InstallStrategyDeploymentInterface, templateAnnotations map[string]string, owner ownerutil.Owner, previousStrategy Strategy) StrategyInstaller {
// ApplyFunc does...
type ApplyFunc func(deployment *appsv1.Deployment) error

type ApplyFuncChain []ApplyFunc

// Apply applies...
func (c ApplyFuncChain) Apply(deployment *appsv1.Deployment) (err error) {
for _, applyFunc := range c {
if applyFunc == nil {
continue
}

if applyErr := applyFunc(deployment); applyErr != nil {
err = applyErr
break
}
}

return
}

type ApplyFuncBuilder func(owner ownerutil.Owner) ApplyFunc

func NewStrategyDeploymentInstaller(strategyClient wrappers.InstallStrategyDeploymentInterface, templateAnnotations map[string]string, owner ownerutil.Owner, previousStrategy Strategy, chain ApplyFuncChain) StrategyInstaller {
return &StrategyDeploymentInstaller{
strategyClient: strategyClient,
owner: owner,
previousStrategy: previousStrategy,
templateAnnotations: templateAnnotations,
chain: chain,
}
}

func (i *StrategyDeploymentInstaller) installDeployments(deps []StrategyDeploymentSpec) error {
for _, d := range deps {
if _, err := i.strategyClient.CreateOrUpdateDeployment(i.deploymentForSpec(d.Name, d.Spec)); err != nil {
deployment, err := i.deploymentForSpec(d.Name, d.Spec)
if err != nil {
return err
}

if _, err := i.strategyClient.CreateOrUpdateDeployment(deployment); err != nil {
return err
}
}

return nil
}

func (i *StrategyDeploymentInstaller) deploymentForSpec(name string, spec appsv1.DeploymentSpec) *appsv1.Deployment {
func (i *StrategyDeploymentInstaller) deploymentForSpec(name string, spec appsv1.DeploymentSpec) (deployment *appsv1.Deployment, err error) {
dep := &appsv1.Deployment{Spec: spec}
dep.SetName(name)
dep.SetNamespace(i.owner.GetNamespace())
Expand All @@ -88,7 +118,14 @@ func (i *StrategyDeploymentInstaller) deploymentForSpec(name string, spec appsv1

ownerutil.AddNonBlockingOwner(dep, i.owner)
ownerutil.AddOwnerLabelsForKind(dep, i.owner, v1alpha1.ClusterServiceVersionKind)
return dep

if applyErr := i.chain.Apply(dep); applyErr != nil {
err = applyErr
return
}

deployment = dep
return
}

func (i *StrategyDeploymentInstaller) cleanupPrevious(current *StrategyDetailsDeployment, previous *StrategyDetailsDeployment) error {
Expand Down Expand Up @@ -185,7 +222,11 @@ func (i *StrategyDeploymentInstaller) checkForDeployments(deploymentSpecs []Stra
}

// check equality
calculated := i.deploymentForSpec(spec.Name, spec.Spec)
calculated, err := i.deploymentForSpec(spec.Name, spec.Spec)
if err != nil {
return err
}

if !i.equalDeployments(&calculated.Spec, &dep.Spec) {
return StrategyError{Reason: StrategyErrDeploymentUpdated, Message: fmt.Sprintf("deployment changed, rolling update with patch: %s\n%#v\n%#v", diff.ObjectDiff(dep.Spec.Template.Spec, calculated.Spec.Template.Spec), calculated.Spec.Template.Spec, dep.Spec.Template.Spec)}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/controller/install/deployment_test.go
Expand Up @@ -264,7 +264,7 @@ func TestNewStrategyDeploymentInstaller(t *testing.T) {
},
}
fakeClient := new(clientfakes.FakeInstallStrategyDeploymentInterface)
strategy := NewStrategyDeploymentInstaller(fakeClient, map[string]string{"test": "annotation"}, &mockOwner, nil)
strategy := NewStrategyDeploymentInstaller(fakeClient, map[string]string{"test": "annotation"}, &mockOwner, nil, nil)
require.Implements(t, (*StrategyInstaller)(nil), strategy)
require.Error(t, strategy.Install(&BadStrategy{}))
installed, err := strategy.CheckInstalled(&BadStrategy{})
Expand Down Expand Up @@ -302,7 +302,7 @@ func TestInstallStrategyDeploymentCheckInstallErrors(t *testing.T) {
t.Run(tt.description, func(t *testing.T) {
fakeClient := new(clientfakes.FakeInstallStrategyDeploymentInterface)
strategy := strategy(1, namespace, &mockOwner)
installer := NewStrategyDeploymentInstaller(fakeClient, map[string]string{"test": "annotation"}, &mockOwner, nil)
installer := NewStrategyDeploymentInstaller(fakeClient, map[string]string{"test": "annotation"}, &mockOwner, nil, nil)

dep := testDeployment("olm-dep-1", namespace, &mockOwner)
dep.Spec.Template.SetAnnotations(map[string]string{"test": "annotation"})
Expand Down
12 changes: 10 additions & 2 deletions pkg/controller/install/resolver.go
Expand Up @@ -28,7 +28,9 @@ type StrategyResolverInterface interface {
InstallerForStrategy(strategyName string, opClient operatorclient.ClientInterface, opLister operatorlister.OperatorLister, owner ownerutil.Owner, annotations map[string]string, previousStrategy Strategy) StrategyInstaller
}

type StrategyResolver struct{}
type StrategyResolver struct {
ProxyInjectorBuilder ApplyFuncBuilder
}

func (r *StrategyResolver) UnmarshalStrategy(s v1alpha1.NamedInstallStrategy) (strategy Strategy, err error) {
switch s.StrategyName {
Expand All @@ -47,7 +49,13 @@ func (r *StrategyResolver) InstallerForStrategy(strategyName string, opClient op
switch strategyName {
case InstallStrategyNameDeployment:
strategyClient := wrappers.NewInstallStrategyDeploymentClient(opClient, opLister, owner.GetNamespace())
return NewStrategyDeploymentInstaller(strategyClient, annotations, owner, previousStrategy)

initializers := []ApplyFunc{}
if r.ProxyInjectorBuilder != nil {
initializers = append(initializers, r.ProxyInjectorBuilder(owner))
}

return NewStrategyDeploymentInstaller(strategyClient, annotations, owner, previousStrategy, initializers)
}

// Insurance against these functions being called incorrectly (unmarshal strategy will return a valid strategy name)
Expand Down
8 changes: 8 additions & 0 deletions pkg/controller/operators/olm/config.go
Expand Up @@ -9,6 +9,7 @@ import (
utilclock "k8s.io/apimachinery/pkg/util/clock"
"k8s.io/client-go/rest"

configv1client "github.com/openshift/client-go/config/clientset/versioned"
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/internalversion"
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
Expand All @@ -32,6 +33,7 @@ type operatorConfig struct {
apiReconciler resolver.APIIntersectionReconciler
apiLabeler labeler.Labeler
restConfig *rest.Config
configClient configv1client.Interface
}

func (o *operatorConfig) apply(options []OperatorOption) {
Expand Down Expand Up @@ -160,3 +162,9 @@ func WithRestConfig(restConfig *rest.Config) OperatorOption {
config.restConfig = restConfig
}
}

func WithConfigClient(configClient configv1client.Interface) OperatorOption {
return func(config *operatorConfig) {
config.configClient = configClient
}
}
68 changes: 68 additions & 0 deletions pkg/controller/operators/olm/envvar/initializer.go
@@ -0,0 +1,68 @@
package envvar

import (
"fmt"

"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/proxy"
"github.com/sirupsen/logrus"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
)

// NewDeploymentInitializer returns a function that accepts a Deployment object
// and initializes it with env variables specified in operator configuration.
func NewDeploymentInitializer(logger *logrus.Logger, querier proxy.Querier, lister operatorlister.OperatorLister) *DeploymentInitializer {
return &DeploymentInitializer{
logger: logger,
querier: querier,
config: &operatorConfig{
lister: lister,
},
}
}

type DeploymentInitializer struct {
logger *logrus.Logger
querier proxy.Querier
config *operatorConfig
}

func (d *DeploymentInitializer) GetDeploymentInitializer(ownerCSV ownerutil.Owner) install.ApplyFunc {
return func(spec *appsv1.Deployment) error {
err := d.initialize(ownerCSV, spec)
return err
}
}

// Initialize initializes a deployment object with appropriate global cluster
// level proxy env variable(s).
func (d *DeploymentInitializer) initialize(ownerCSV ownerutil.Owner, deployment *appsv1.Deployment) error {
var podConfigEnvVar, proxyEnvVar, merged []corev1.EnvVar
var err error

podConfigEnvVar, err = d.config.GetOperatorConfig(ownerCSV)
if err != nil {
err = fmt.Errorf("failed to get subscription pod configuration - %v", err)
return err
}

if !proxy.IsOverridden(podConfigEnvVar) {
proxyEnvVar, err = d.querier.QueryProxyConfig()
if err != nil {
err = fmt.Errorf("failed to query cluster proxy configuration - %v", err)
return err
}
}

merged = append(podConfigEnvVar, proxyEnvVar...)

podSpec := deployment.Spec.Template.Spec
if err := InjectEnvIntoDeployment(&podSpec, merged); err != nil {
return fmt.Errorf("failed to inject proxy env variable(s) into deployment spec name=%s - %v", deployment.Name, err)
}

return nil
}
61 changes: 61 additions & 0 deletions pkg/controller/operators/olm/envvar/inject.go
@@ -0,0 +1,61 @@
package envvar

import (
"errors"

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

// InjectEnvIntoDeployment injects the proxy env variables specified in
// proxyEnvVar into the container(s) of the given PodSpec.
//
// If any Container in PodSpec already defines an env variable of the same name
// as any of the proxy env variables then it
func InjectEnvIntoDeployment(podSpec *corev1.PodSpec, envVars []corev1.EnvVar) error {
if podSpec == nil {
return errors.New("no pod spec provided")
}

for i := range podSpec.Containers {
container := &podSpec.Containers[i]
container.Env = merge(container.Env, envVars)
}

return nil
}

func merge(containerEnvVars []corev1.EnvVar, newEnvVars []corev1.EnvVar) (merged []corev1.EnvVar) {
merged = containerEnvVars

for _, newEnvVar := range newEnvVars {
existing, found := find(containerEnvVars, newEnvVar.Name)
if !found {
if newEnvVar.Value != "" {
merged = append(merged, corev1.EnvVar{
Name: newEnvVar.Name,
Value: newEnvVar.Value,
})
}

continue
}

existing.Value = newEnvVar.Value
}

return
}

func find(proxyEnvVar []corev1.EnvVar, name string) (envVar *corev1.EnvVar, found bool) {
for i := range proxyEnvVar {
if name == proxyEnvVar[i].Name {
// Environment variable names are case sensitive.
found = true
envVar = &proxyEnvVar[i]

break
}
}

return
}

0 comments on commit e95bb78

Please sign in to comment.