Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to facilitate proxy-aware operators #71

Merged
Merged
Show file tree
Hide file tree
Changes from 5 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
33 changes: 33 additions & 0 deletions proxy/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2021 The Operator-SDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*
Package proxy implements helper functions to facilitate making operators proxy-aware.

This package assumes that proxy environment variables `HTTPS_PROXY`,
`HTTP_PROXY`, and/or `NO_PROXY` are set in the Operator environment, typically
via the Operator deployment.

Proxy-aware operators can use the ReadProxyVarsFromEnv to retrieve these values
as a slice of corev1 EnvVars. Each of the proxy variables are duplicated in
upper and lower case to support applications that use either. In their
reconcile functions, Operator authors are then responsible for setting these
variables in the Container Envs that must use the proxy, For example:

// Pods with Kubernetes < 1.22
for _, cSpec := range (myPod.Spec.Containers) {
cSpec.Env = append(defaultEnv(), ReadProxyVarsFromEnv())
}
*/
package proxy
47 changes: 47 additions & 0 deletions proxy/proxy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2021 The Operator-SDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package proxy

import (
"os"
"strings"

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

// ProxyEnvNames are standard environment variables for proxies
var ProxyEnvNames = []string{"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY"}

// ReadProxyVarsFromEnv retrieves the standard proxy-related environment
// variables from the running environment and returns a slice of corev1 EnvVar
// containing upper and lower case versions of those variables.
func ReadProxyVarsFromEnv() []corev1.EnvVar {
envVars := []corev1.EnvVar{}
for _, s := range ProxyEnvNames {
value, isSet := os.LookupEnv(s)
if isSet {
envVars = append(envVars, corev1.EnvVar{
Name: s,
Value: value,
})
// Duplicate values for upper and lower case
envVars = append(envVars, corev1.EnvVar{
Name: strings.ToLower(s),
Value: value,
})
asmacdo marked this conversation as resolved.
Show resolved Hide resolved
}
}
return envVars
}
27 changes: 27 additions & 0 deletions proxy/proxy_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2021 The Operator-SDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package proxy_test

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestProxy(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Proxy Suite")
}
71 changes: 71 additions & 0 deletions proxy/proxy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2021 The Operator-SDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package proxy

import (
"errors"
"os"
"strings"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
)

func checkValueFromEnvObj(name string, envVars []corev1.EnvVar) (string, error) {
for i := range envVars {
if envVars[i].Name == name {
return envVars[i].Value, nil
}
}
return "", errors.New("empty name")

}

var _ = Describe("Retrieving", func() {
Describe("proxy environment variables", func() {
It("returns a slice of environment variables that were set", func() {
os.Setenv("HTTPS_PROXY", "https_proxy_test")
os.Setenv("HTTP_PROXY", "http_proxy_test")
os.Setenv("NO_PROXY", "no_proxy_test")
envVars := ReadProxyVarsFromEnv()
Expect(len(envVars)).To(Equal(6))
})
It("does not return unset variables", func() {
envVars := ReadProxyVarsFromEnv()
Expect(len(envVars)).To(Equal(0))
})

It("creates upper and lower case environment variables with the same value", func() {
os.Setenv("HTTPS_PROXY", "https_proxy_test")
os.Setenv("HTTP_PROXY", "http_proxy_test")
os.Setenv("NO_PROXY", "no_proxy_test")
envVars := ReadProxyVarsFromEnv()

for _, envName := range ProxyEnvNames {
upperValue, err := checkValueFromEnvObj(envName, envVars)
Expect(err).To(BeNil())
lowerValue, err := checkValueFromEnvObj(strings.ToLower(envName), envVars)
Expect(err).To(BeNil())
Expect(upperValue).To(Equal(lowerValue))
}
})
AfterEach(func() {
_ = os.Unsetenv("HTTPS_PROXY")
_ = os.Unsetenv("HTTP_PROXY")
_ = os.Unsetenv("NO_PROXY")
})
})
})