-
Notifications
You must be signed in to change notification settings - Fork 535
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(feat) incorporate proxy configuration support
Use case: The env variables defined in cluster scoped global proxy configuration object should be injected into deployment spec if not overridden in subscription pod configuration. Add a new proxy package that provides the following support: - Add support to check if Proxy api is available on cluster. - Add support to query the cluster for the 'cluster' Proxy object and return the env variable(s). - Provide logic to determine whether proxy env variable has been overridden in pod configuration.
- Loading branch information
Showing
48 changed files
with
2,944 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package proxy | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
|
||
"k8s.io/apimachinery/pkg/runtime/schema" | ||
apidiscovery "k8s.io/client-go/discovery" | ||
) | ||
|
||
const ( | ||
// This is the error message thrown by ServerSupportsVersion function | ||
// when an API version is not supported by the server. | ||
notSupportedErrorMessage = "server does not support API version" | ||
) | ||
|
||
// IsAPIAvailable return true if OpenShift config API is present on the cluster. | ||
// Otherwise, supported is set to false. | ||
func IsAPIAvailable(discovery apidiscovery.DiscoveryInterface) (supported bool, err error) { | ||
if discovery == nil { | ||
err = errors.New("discovery interface can not be <nil>") | ||
return | ||
} | ||
|
||
opStatusGV := schema.GroupVersion{ | ||
Group: "config.openshift.io", | ||
Version: "v1", | ||
} | ||
if discoveryErr := apidiscovery.ServerSupportsVersion(discovery, opStatusGV); discoveryErr != nil { | ||
if strings.Contains(discoveryErr.Error(), notSupportedErrorMessage) { | ||
return | ||
} | ||
|
||
err = discoveryErr | ||
return | ||
} | ||
|
||
supported = true | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package proxy | ||
|
||
import ( | ||
apiconfigv1 "github.com/openshift/api/config/v1" | ||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
const ( | ||
// HTTP_PROXY is the URL of the proxy for HTTP requests. | ||
// Empty means unset and will not result in an env var. | ||
envHTTPProxyName = "HTTP_PROXY" | ||
|
||
// HTTPS_PROXY is the URL of the proxy for HTTPS requests. | ||
// Empty means unset and will not result in an env var. | ||
envHTTPSProxyName = "HTTPS_PROXY" | ||
|
||
// NO_PROXY is the list of domains for which the proxy should not be used. | ||
// Empty means unset and will not result in an env var. | ||
envNoProxyName = "NO_PROXY" | ||
) | ||
|
||
var ( | ||
allProxyEnvVarNames = []string{ | ||
envHTTPProxyName, | ||
envHTTPSProxyName, | ||
envNoProxyName, | ||
} | ||
) | ||
|
||
// ToEnvVar accepts a config Proxy object and returns an array of all three | ||
// proxy variables with values. | ||
// | ||
// Please note that the function uses the status of the Proxy object to rea the | ||
// proxy env variables. It's because OpenShift validates the proxy variables in | ||
// spec and writes them back to status. | ||
// As a consumer we should be reading off of proxy.status. | ||
func ToEnvVar(proxy *apiconfigv1.Proxy) []corev1.EnvVar { | ||
return []corev1.EnvVar{ | ||
corev1.EnvVar{ | ||
Name: envHTTPProxyName, | ||
Value: proxy.Status.HTTPProxy, | ||
}, | ||
corev1.EnvVar{ | ||
Name: envHTTPSProxyName, | ||
Value: proxy.Status.HTTPSProxy, | ||
}, | ||
corev1.EnvVar{ | ||
Name: envNoProxyName, | ||
Value: proxy.Status.NoProxy, | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package proxy_test | ||
|
||
import ( | ||
"testing" | ||
|
||
apiconfigv1 "github.com/openshift/api/config/v1" | ||
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/proxy" | ||
"github.com/stretchr/testify/assert" | ||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
const ( | ||
envHTTPProxyName = "HTTP_PROXY" | ||
envHTTPSProxyName = "HTTPS_PROXY" | ||
envNoProxyName = "NO_PROXY" | ||
) | ||
|
||
func TestToEnvVar(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
proxy *apiconfigv1.Proxy | ||
envVarWant []corev1.EnvVar | ||
}{ | ||
{ | ||
name: "WithSet", | ||
proxy: &apiconfigv1.Proxy{ | ||
Status: apiconfigv1.ProxyStatus{ | ||
HTTPProxy: "http://", | ||
HTTPSProxy: "https://", | ||
NoProxy: "foo,bar", | ||
}, | ||
}, | ||
envVarWant: []corev1.EnvVar{ | ||
corev1.EnvVar{ | ||
Name: envHTTPProxyName, | ||
Value: "http://", | ||
}, | ||
corev1.EnvVar{ | ||
Name: envHTTPSProxyName, | ||
Value: "https://", | ||
}, | ||
corev1.EnvVar{ | ||
Name: envNoProxyName, | ||
Value: "foo,bar", | ||
}, | ||
}, | ||
}, | ||
|
||
{ | ||
name: "WithUnset", | ||
proxy: &apiconfigv1.Proxy{ | ||
Status: apiconfigv1.ProxyStatus{ | ||
HTTPProxy: "http://", | ||
HTTPSProxy: "", | ||
NoProxy: "", | ||
}, | ||
}, | ||
envVarWant: []corev1.EnvVar{ | ||
corev1.EnvVar{ | ||
Name: envHTTPProxyName, | ||
Value: "http://", | ||
}, | ||
corev1.EnvVar{ | ||
Name: envHTTPSProxyName, | ||
Value: "", | ||
}, | ||
corev1.EnvVar{ | ||
Name: envNoProxyName, | ||
Value: "", | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
envVarGot := proxy.ToEnvVar(tt.proxy) | ||
|
||
assert.NotNil(t, envVarGot) | ||
assert.Equal(t, tt.envVarWant, envVarGot) | ||
|
||
}) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package proxy | ||
|
||
import ( | ||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
// IsOverridden returns true if the given container overrides proxy env variable(s). | ||
// We apply the following rule: | ||
// If a container already defines any of the proxy env variable then it | ||
// overrides all of these. | ||
func IsOverridden(envVar []corev1.EnvVar) (overrides bool) { | ||
for _, envVarName := range allProxyEnvVarNames { | ||
_, found := find(envVar, envVarName) | ||
if found { | ||
overrides = true | ||
return | ||
} | ||
} | ||
|
||
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package proxy_test | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/proxy" | ||
|
||
"github.com/stretchr/testify/assert" | ||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
var ( | ||
globalProxyConfig = []corev1.EnvVar{ | ||
corev1.EnvVar{ | ||
Name: "HTTP_PROXY", | ||
Value: "http://foo.com:8080", | ||
}, | ||
corev1.EnvVar{ | ||
Name: "HTTPS_PROXY", | ||
Value: "https://foo.com:443", | ||
}, | ||
corev1.EnvVar{ | ||
Name: "NO_PROXY", | ||
Value: "a.com,b.com", | ||
}, | ||
} | ||
) | ||
|
||
func TestIsOverridden(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
envVar []corev1.EnvVar | ||
expected bool | ||
}{ | ||
{ | ||
name: "WithEmptyEnvVar", | ||
envVar: []corev1.EnvVar{}, | ||
expected: false, | ||
}, | ||
{ | ||
name: "WithNilEnvVar", | ||
envVar: nil, | ||
expected: false, | ||
}, | ||
{ | ||
name: "WithUnrelatedEnvVar", | ||
envVar: []corev1.EnvVar{ | ||
corev1.EnvVar{ | ||
Name: "foo", | ||
Value: "foo_value", | ||
}, | ||
}, | ||
expected: false, | ||
}, | ||
{ | ||
name: "WithHTTP_PROXY", | ||
envVar: []corev1.EnvVar{ | ||
corev1.EnvVar{ | ||
Name: envHTTPProxyName, | ||
Value: "http://", | ||
}, | ||
}, | ||
expected: true, | ||
}, | ||
{ | ||
name: "WithHTTPS_PROXY", | ||
envVar: []corev1.EnvVar{ | ||
corev1.EnvVar{ | ||
Name: envHTTPSProxyName, | ||
Value: "https://", | ||
}, | ||
}, | ||
expected: true, | ||
}, | ||
{ | ||
name: "WithNO_PROXY", | ||
envVar: []corev1.EnvVar{ | ||
corev1.EnvVar{ | ||
Name: envNoProxyName, | ||
Value: "https://", | ||
}, | ||
}, | ||
expected: true, | ||
}, | ||
{ | ||
name: "WithCaseSensitive", | ||
envVar: []corev1.EnvVar{ | ||
corev1.EnvVar{ | ||
Name: strings.ToLower(envHTTPSProxyName), | ||
Value: "http://", | ||
}, | ||
}, | ||
expected: false, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
actual := proxy.IsOverridden(tt.envVar) | ||
|
||
assert.Equal(t, tt.expected, actual) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package proxy | ||
|
||
import ( | ||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
// DefaultQuerier does... | ||
func DefaultQuerier() Querier { | ||
return &defaultQuerier{} | ||
} | ||
|
||
// Querier is an interface that wraps the QueryProxyConfig method. | ||
// | ||
// QueryProxyConfig returns the global cluster level proxy env variable(s). | ||
type Querier interface { | ||
QueryProxyConfig() (proxy []corev1.EnvVar, err error) | ||
} | ||
|
||
type defaultQuerier struct { | ||
} | ||
|
||
// QueryProxyConfig returns no env variable(s), err is set to nil to indicate | ||
// that the cluster has no global proxy configuration. | ||
func (*defaultQuerier) QueryProxyConfig() (proxy []corev1.EnvVar, err error) { | ||
return | ||
} |
Oops, something went wrong.