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 9f996eb commit da3c683
Show file tree
Hide file tree
Showing 59 changed files with 3,496 additions and 19 deletions.

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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
68 changes: 68 additions & 0 deletions pkg/controller/operators/olm/envvar/initializer.go
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
}
Loading

0 comments on commit da3c683

Please sign in to comment.