@@ -24,6 +24,7 @@ import (
2424 "fmt"
2525 "io"
2626 "net/http"
27+ "net/url"
2728 "os"
2829 "path/filepath"
2930 "regexp"
@@ -437,7 +438,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
437438 conditions .GetObservedGeneration (obj , sourcev1 .SourceVerifiedCondition ) != obj .Generation ||
438439 conditions .IsFalse (obj , sourcev1 .SourceVerifiedCondition ) {
439440
440- result , err := r .verifySignature (ctx , obj , ref , keychain , auth , opts ... )
441+ result , err := r .verifySignature (ctx , obj , ref , keychain , auth , transport , opts ... )
441442 if err != nil {
442443 provider := obj .Spec .Verify .Provider
443444 if obj .Spec .Verify .SecretRef == nil && obj .Spec .Verify .Provider == "cosign" {
@@ -623,7 +624,10 @@ func (r *OCIRepositoryReconciler) digestFromRevision(revision string) string {
623624// If not, when using cosign it falls back to a keyless approach for verification.
624625// When notation is used, a trust policy is required to verify the image.
625626// The verification result is returned as a VerificationResult and any error encountered.
626- func (r * OCIRepositoryReconciler ) verifySignature (ctx context.Context , obj * ociv1.OCIRepository , ref name.Reference , keychain authn.Keychain , auth authn.Authenticator , opt ... remote.Option ) (soci.VerificationResult , error ) {
627+ func (r * OCIRepositoryReconciler ) verifySignature (ctx context.Context , obj * ociv1.OCIRepository ,
628+ ref name.Reference , keychain authn.Keychain , auth authn.Authenticator ,
629+ transport * http.Transport , opt ... remote.Option ) (soci.VerificationResult , error ) {
630+
627631 ctxTimeout , cancel := context .WithTimeout (ctx , obj .Spec .Timeout .Duration )
628632 defer cancel ()
629633
@@ -753,6 +757,7 @@ func (r *OCIRepositoryReconciler) verifySignature(ctx context.Context, obj *ociv
753757 notation .WithInsecureRegistry (obj .Spec .Insecure ),
754758 notation .WithLogger (ctrl .LoggerFrom (ctx )),
755759 notation .WithRootCertificates (certs ),
760+ notation .WithTransport (transport ),
756761 }
757762
758763 verifier , err := notation .NewNotationVerifier (defaultNotationOciOpts ... )
@@ -920,16 +925,40 @@ func (r *OCIRepositoryReconciler) keychain(ctx context.Context, obj *ociv1.OCIRe
920925
921926// transport clones the default transport from remote and when a certSecretRef is specified,
922927// the returned transport will include the TLS client and/or CA certificates.
928+ // If the insecure flag is set, the transport will skip the verification of the server's certificate.
929+ // Additionally, if a proxy is specified, transport will use it.
923930func (r * OCIRepositoryReconciler ) transport (ctx context.Context , obj * ociv1.OCIRepository ) (* http.Transport , error ) {
924931 transport := remote .DefaultTransport .(* http.Transport ).Clone ()
925932
933+ tlsConfig , err := r .getTLSConfig (ctx , obj )
934+ if err != nil {
935+ return nil , err
936+ }
937+ if tlsConfig != nil {
938+ transport .TLSClientConfig = tlsConfig
939+ }
940+
941+ proxyURL , err := r .getProxyURL (ctx , obj )
942+ if err != nil {
943+ return nil , err
944+ }
945+ if proxyURL != nil {
946+ transport .Proxy = http .ProxyURL (proxyURL )
947+ }
948+
949+ return transport , nil
950+ }
951+
952+ // getTLSConfig gets the TLS configuration for the transport based on the
953+ // specified secret reference in the OCIRepository object, or the insecure flag.
954+ func (r * OCIRepositoryReconciler ) getTLSConfig (ctx context.Context , obj * ociv1.OCIRepository ) (* cryptotls.Config , error ) {
926955 if obj .Spec .CertSecretRef == nil || obj .Spec .CertSecretRef .Name == "" {
927956 if obj .Spec .Insecure {
928- transport . TLSClientConfig = & cryptotls.Config {
957+ return & cryptotls.Config {
929958 InsecureSkipVerify : true ,
930- }
959+ }, nil
931960 }
932- return transport , nil
961+ return nil , nil
933962 }
934963
935964 certSecretName := types.NamespacedName {
@@ -955,9 +984,42 @@ func (r *OCIRepositoryReconciler) transport(ctx context.Context, obj *ociv1.OCIR
955984 Info ("warning: specifying TLS auth data via `certFile`/`keyFile`/`caFile` is deprecated, please use `tls.crt`/`tls.key`/`ca.crt` instead" )
956985 }
957986 }
958- transport .TLSClientConfig = tlsConfig
959987
960- return transport , nil
988+ return tlsConfig , nil
989+ }
990+
991+ // getProxyURL gets the proxy configuration for the transport based on the
992+ // specified proxy secret reference in the OCIRepository object.
993+ func (r * OCIRepositoryReconciler ) getProxyURL (ctx context.Context , obj * ociv1.OCIRepository ) (* url.URL , error ) {
994+ if obj .Spec .ProxySecretRef == nil || obj .Spec .ProxySecretRef .Name == "" {
995+ return nil , nil
996+ }
997+
998+ proxySecretName := types.NamespacedName {
999+ Namespace : obj .Namespace ,
1000+ Name : obj .Spec .ProxySecretRef .Name ,
1001+ }
1002+ var proxySecret corev1.Secret
1003+ if err := r .Get (ctx , proxySecretName , & proxySecret ); err != nil {
1004+ return nil , err
1005+ }
1006+
1007+ proxyData := proxySecret .Data
1008+ address , ok := proxyData ["address" ]
1009+ if ! ok {
1010+ return nil , fmt .Errorf ("invalid proxy secret '%s/%s': key 'address' is missing" ,
1011+ obj .Namespace , obj .Spec .ProxySecretRef .Name )
1012+ }
1013+ proxyURL , err := url .Parse (string (address ))
1014+ if err != nil {
1015+ return nil , fmt .Errorf ("failed to parse proxy address '%s': %w" , address , err )
1016+ }
1017+ user , hasUser := proxyData ["username" ]
1018+ password , hasPassword := proxyData ["password" ]
1019+ if hasUser || hasPassword {
1020+ proxyURL .User = url .UserPassword (string (user ), string (password ))
1021+ }
1022+ return proxyURL , nil
9611023}
9621024
9631025// reconcileStorage ensures the current state of the storage matches the
0 commit comments