-
Notifications
You must be signed in to change notification settings - Fork 1.8k
pkg/tlsutil: add support for custom CA #470
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ import ( | |
framework "github.com/operator-framework/operator-sdk/test/e2e/framework" | ||
|
||
"k8s.io/api/core/v1" | ||
apiErrors "k8s.io/apimachinery/pkg/api/errors" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
) | ||
|
@@ -121,7 +122,10 @@ func TestBothAppAndCATLSAssetsExist(t *testing.T) { | |
} | ||
} | ||
|
||
// TestOnlyAppSecretExist tests a case where the application TLS asset exists but its correspoding CA asset doesn't. In this case, CertGenerator can't genereate a new CA because it won't verify the existing application TLS cert. Therefore, CertGenerator can't proceed and returns an error to the caller. | ||
// TestOnlyAppSecretExist tests a case where the application TLS asset exists but its | ||
// correspoding CA asset doesn't. In this case, CertGenerator can't genereate a new CA because | ||
// it won't verify the existing application TLS cert. Therefore, CertGenerator can't proceed | ||
// and returns an error to the caller. | ||
func TestOnlyAppSecretExist(t *testing.T) { | ||
f := framework.Global | ||
ctx := f.NewTestCtx(t) | ||
|
@@ -146,7 +150,7 @@ func TestOnlyAppSecretExist(t *testing.T) { | |
} | ||
} | ||
|
||
// TestOnlyCAExist ensures that at the case where only the CA exists in the cluster; | ||
// TestOnlyCAExist tests the case where only the CA exists in the cluster; | ||
// GenerateCert can retrieve the CA and uses it to create a new application secret. | ||
func TestOnlyCAExist(t *testing.T) { | ||
f := framework.Global | ||
|
@@ -197,6 +201,44 @@ func TestNoneOfCaAndAppSecretExist(t *testing.T) { | |
verifyCASecret(t, caSecret, namespace) | ||
} | ||
|
||
// TestCustomCA ensures that if a user provides a custom Key and Cert and the CA and Application TLS assets | ||
// do not exist, the GenerateCert method can use the custom CA to generate the TLS assest. | ||
func TestCustomCA(t *testing.T) { | ||
f := framework.Global | ||
ctx := f.NewTestCtx(t) | ||
defer ctx.Cleanup(t) | ||
namespace, err := ctx.GetNamespace() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
cg := tlsutil.NewSDKCertGenerator(f.KubeClient) | ||
|
||
customConfig := &tlsutil.CertConfig{ | ||
CertName: certName, | ||
CAKey: "testdata/ca.key", | ||
CACert: "testdata/ca.crt", | ||
} | ||
appSecret, _, _, err := cg.GenerateCert(newDummyCR(namespace), newAppSvc(namespace), customConfig) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
verifyAppSecret(t, appSecret, namespace) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to check that no ca is being put into k8s cluster. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean that we should explicitly try to 'GET' the ca secret and Configmap with the given name and ensure nothing is returned? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, that's correct. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
// ensure caConfigMap does not exist in k8s cluster. | ||
_, err = framework.Global.KubeClient.CoreV1().Secrets(namespace).Get(caConfigMapAndSecretName, metav1.GetOptions{}) | ||
if !apiErrors.IsNotFound(err) { | ||
t.Fatal(err) | ||
} | ||
|
||
// ensure caConfigMap does not exist in k8s cluster. | ||
_, err = framework.Global.KubeClient.CoreV1().Secrets(namespace).Get(caConfigMapAndSecretName, metav1.GetOptions{}) | ||
if !apiErrors.IsNotFound(err) { | ||
t.Fatal(err) | ||
} | ||
} | ||
|
||
func verifyCASecret(t *testing.T, caSecret *v1.Secret, namespace string) { | ||
// check if caConfigMap has the correct fields. | ||
if caConfigMapAndSecretName != caSecret.Name { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can have a boolean value
hasPassedInCA := config.CAKey != "" && config.CACert != ""
.And we only call
getCASecretAndConfigMapInCluster
ifhasPassedInCA
is false. e.gThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesnt really matter cause if
getCASecretAndConfigMapInCluster
is called before and no configMap exists the values of caSecret & caConfigMap will be nil. Then in theif config.CAKey != "" && config.CACert != "" {
block the values get updatedThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this makes sense if I was using a generated cert but now have a custom CA I would expect that to take precedence.
I could see us making the change @fanminshi suggested only if we are worried about two extra get calls to the API server that we know will fail/don't care about. I personally believe that the way it is more readable and would like to keep it the way it is, but I could see a reason to change if we are worried about too many calls to the api server.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rithujohn191 your code is correct. My suggestion is just an optimization because
getCASecretAndConfigMapInCluster
makes calls to k8s cluster which is unnecessary if custom ca is passed.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had the same thought process, I think code readability is better the way it is right now and 2 GET calls from the api server is not heavy weight at all. I think the way the code is currently written makes it more clear that the custom CA takes preference. But if you insist I could change it. Either way its not much of a difference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rithujohn191 let's just keep the code as it is for readability. we can revisit the code if we want to optimize it.