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

Feature/multi pull secrets #83

Closed
wants to merge 22 commits into from

Conversation

steelion
Copy link

@steelion steelion commented May 6, 2022

adds the feature to use multiple pull-secrets from the k8s pods
additionally there is a possibility to specify a particular pull secret that is used in case all pull secrets from the pods are failing (the global custom pull secret must be in the same namespace as the sbom-operator itself)

@github-actions github-actions bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label May 6, 2022
@steelion
Copy link
Author

steelion commented May 6, 2022

@derkoe can you also please take a look at my implementation
it at least works in our OCP Clusters

Copy link
Owner

@ckotzbauer ckotzbauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your PR @steelion, much appreciated.
This fits the needs for my proposed solution of #76 (comment).

The main topics about my comments:

  • The name of the parameter
  • The structure of the ContainerImage struct.
  • The iteration through the secrets: The struct always has to be "valid", so no nil and empty states should be there before the iteration through the secrets has started.
  • The reason for this: The "Job-Image"-Feature from the 0.10.0 release must not break. (see the job package and the job-images folder for details) There are two possibilities:
    • The serialized job-config still only use the first secret
    • The imageConfig struct has to be changed to hold multiple secrets, which also needs changes to the vcn and cas job-image entrypoint.sh files.

For now: We should be fine with the first option for the job-feature.

If you need help, please contact me, I can support you by integrating this PR 😉

README.md Outdated Show resolved Hide resolved
internal/kubernetes/kubernetes.go Show resolved Hide resolved
internal/kubernetes/kubernetes.go Outdated Show resolved Hide resolved
sbomOperatorNamespace, _, err = kubeConfig.Namespace()
if err != nil {
logrus.WithError(err).Fatal("namespace could not be read!")
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if the namespace of the in-cluster kubeconfig is always correct here.
Please use the POD_NAMESPACE environment variable here (as already used in the job-package).
With this the job package can be refactored a bit, as the namespace is than already known from the kubernetes package and the parameter from CreateJob and CreateJobSecret could be removed.

The POD_NAMESPACE env-variable is than mandatory for the manifests and th helm-chart.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sbom-operator is now using only the POD_NAMESPACE env variable for fetching the fallback secret
but i tried it to be no breaking change. in case POD_NAMESPACES is not set, the fallbacksecret will not be read, and a debug message tells the user every time that this env-var should be set too.
unfortunately i had no time yet to check where to get the own namespace reliably.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log-message is good, but please use Debug instead of Info.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just saw the Debug message below in the logic, please remove one of them and use Debug level for the other.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kept the debug message in LoadImageInfos function, because only at this point the variable is really needed

internal/kubernetes/kubernetes.go Outdated Show resolved Hide resolved
internal/kubernetes/kubernetes.go Outdated Show resolved Hide resolved
internal/syft/syft.go Outdated Show resolved Hide resolved
- refactor the ContainerImage struct.
- refactor secrets iteration
@steelion
Copy link
Author

steelion commented May 9, 2022

I refactored the code a bit to not break the job-images and to make sure to meet your criteria (at least i hope so) 😉
learned a lot about go in the last few days 😆

Copy link
Owner

@ckotzbauer ckotzbauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @steelion,
sorry for the delay. I have another bunch of comments for you. The logic in general looks is good, but there are some circumstances which need further improvements.

README.md Show resolved Hide resolved
@@ -21,4 +21,5 @@ var (
ConfigKeyJobImage = "job-image"
ConfigKeyJobImagePullSecret = "job-image-pull-secret"
ConfigKeyJobTimeout = "job-timeout"
ConfigKeyCustomGlobalPullSecret = "custom-global-pull-secret"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has to be renamed too.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure - missed that with the previous commit :(

sbomOperatorNamespace, _, err = kubeConfig.Namespace()
if err != nil {
logrus.WithError(err).Fatal("namespace could not be read!")
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log-message is good, but please use Debug instead of Info.

@@ -88,6 +100,7 @@ func (client *KubeClient) listPods(namespace, labelSelector string) ([]corev1.Po
func (client *KubeClient) LoadImageInfos(namespaces []corev1.Namespace, podLabelSelector string) (map[string]ContainerImage, []ContainerImage) {
images := map[string]ContainerImage{}
allImages := []ContainerImage{}
allImageCreds := []KubeCreds{}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this is declared outside the loop?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved inside the loop

sbomOperatorNamespace, _, err = kubeConfig.Namespace()
if err != nil {
logrus.WithError(err).Fatal("namespace could not be read!")
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just saw the Debug message below in the logic, please remove one of them and use Debug level for the other.

main.go Outdated
@@ -62,6 +62,7 @@ func init() {
rootCmd.PersistentFlags().String(internal.ConfigKeyKubernetesClusterId, "default", "Kubernetes Cluster ID")
rootCmd.PersistentFlags().String(internal.ConfigKeyJobImage, "", "Custom Job-Image")
rootCmd.PersistentFlags().String(internal.ConfigKeyJobImagePullSecret, "", "Custom Job-Image-Pull-Secret")
rootCmd.PersistentFlags().String(internal.ConfigKeyCustomGlobalPullSecret, "", "Custom Global-Pull-Secret")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename the display-name.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure - missed that with the previous commit :(

if len(image.Auth) > 0 {
cfg, err := ResolveAuthConfig(image)
empty := types.AuthConfig{}
for pullSecretIndex, pullSecret := range image.PullSecrets {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is good in general, except the fact that it assumes, that there is always at least one pull-secret. That's wrong. The pull-secrets are always optional.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah - you are right
made some changes to the pullSecret iteration handling

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one commit is still missing (returning error instead of nil when necessary)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done
the pullsecret handling should work now and i added some tests

return err
}
if len(pullSecret.SecretCredsData) > 0 {
cfg, err := ResolveAuthConfigWithPullSecretIndex(image, pullSecretIndex)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please directly use the pullSecret here instead of accessing it with the index.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made some changes to the pullSecret iteration handling


func ResolveAuthConfig(image kubernetes.ContainerImage) (types.AuthConfig, error) {
// to not break JobImages this function needs to redirect to the actual resolve-function
return ResolveAuthConfigWithPullSecretIndex(image, 0)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have to return an empty types.AuthConfig, if there are no pull-secrets the ResolveAuthConfigWithPullSecretIndex will panic.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -55,7 +55,8 @@ func marshalCyclonedx(t *testing.T, x interface{}) string {
func testJsonSbom(t *testing.T, name, imageID string) {
format := "json"
s := syft.New(format).WithVersion("v9.9.9")
sbom, err := s.ExecuteSyft(kubernetes.ContainerImage{ImageID: imageID, Auth: []byte{}})
sbom, err := s.ExecuteSyft(kubernetes.ContainerImage{ImageID: imageID, PullSecrets: []kubernetes.KubeCreds{{SecretName: "syft-test-creds", SecretCredsData: []byte{}}}})

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use an empty PullSecrets slice for at least one test-case.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

always return allImageCreds
removed unnecessary error message from log-message
removed unnecessary info message
@ckotzbauer ckotzbauer added the kind/feature Categorizes issue or PR as related to a new feature. label May 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants