1
16
17 package v1beta1
18
19 import (
20 "errors"
21
22 authentication "k8s.io/api/authentication/v1"
23 k8serrors "k8s.io/apimachinery/pkg/api/errors"
24 "k8s.io/klog/v2"
25
26 "kubevirt.io/containerized-data-importer-api/pkg/apis/core"
27 )
28
29 const (
30
31 AnnPrePopulated = core.GroupName + "/storage.prePopulated"
32
33
34 AnnCheckStaticVolume = core.GroupName + "/storage.checkStaticVolume"
35 )
36
37
38
39 var ErrNoTokenOkay = errors.New("proceeding without token is okay under the circumstances")
40
41
42
43 func (dv *DataVolume) AuthorizeUser(requestNamespace, requestName string, proxy AuthorizationHelperProxy, userInfo authentication.UserInfo) (CloneAuthResponse, error) {
44 _, prePopulated := dv.Annotations[AnnPrePopulated]
45 _, checkStaticVolume := dv.Annotations[AnnCheckStaticVolume]
46 noTokenOkay := prePopulated || checkStaticVolume
47
48 targetNamespace, targetName := dv.Namespace, dv.Name
49 if targetNamespace == "" {
50 targetNamespace = requestNamespace
51 }
52 if targetName == "" {
53 targetName = requestName
54 }
55
56 cloneSourceHandler, err := newCloneSourceHandler(dv, proxy.GetDataSource)
57 if err != nil {
58 if k8serrors.IsNotFound(err) && noTokenOkay {
59
60 klog.V(3).Infof("DataVolume %s/%s is pre/static populated, not adding token, no datasource", targetNamespace, targetName)
61 return CloneAuthResponse{Allowed: true, Reason: "", Handler: cloneSourceHandler}, ErrNoTokenOkay
62 }
63 return CloneAuthResponse{Allowed: false, Reason: "", Handler: cloneSourceHandler}, err
64 }
65
66 if cloneSourceHandler.CloneType == noClone {
67 klog.V(3).Infof("DataVolume %s/%s not cloning", targetNamespace, targetName)
68 return CloneAuthResponse{Allowed: true, Reason: "", Handler: cloneSourceHandler}, ErrNoTokenOkay
69 }
70
71 sourceName, sourceNamespace := cloneSourceHandler.SourceName, cloneSourceHandler.SourceNamespace
72 if sourceNamespace == "" {
73 sourceNamespace = targetNamespace
74 }
75
76 _, err = proxy.GetNamespace(sourceNamespace)
77 if err != nil {
78 if k8serrors.IsNotFound(err) && noTokenOkay {
79
80 klog.V(3).Infof("DataVolume %s/%s is pre/static populated, not adding token, no source namespace", targetNamespace, targetName)
81 return CloneAuthResponse{Allowed: true, Reason: "", Handler: cloneSourceHandler}, ErrNoTokenOkay
82 }
83 return CloneAuthResponse{Allowed: false, Reason: "", Handler: cloneSourceHandler}, err
84 }
85
86 ok, reason, err := cloneSourceHandler.UserCloneAuthFunc(proxy.CreateSar, sourceNamespace, sourceName, targetNamespace, userInfo)
87 if err != nil {
88 return CloneAuthResponse{Allowed: false, Reason: reason, Handler: cloneSourceHandler}, err
89 }
90
91 if !ok {
92 if noTokenOkay {
93 klog.V(3).Infof("DataVolume %s/%s is pre/static populated, not adding token, auth failed", targetNamespace, targetName)
94 return CloneAuthResponse{Allowed: true, Reason: "", Handler: cloneSourceHandler}, ErrNoTokenOkay
95 }
96 }
97
98 return CloneAuthResponse{Allowed: ok, Reason: reason, Handler: cloneSourceHandler}, err
99 }
100
101
102
103 func (dv *DataVolume) AuthorizeSA(requestNamespace, requestName string, proxy AuthorizationHelperProxy, saNamespace, saName string) (CloneAuthResponse, error) {
104 _, prePopulated := dv.Annotations[AnnPrePopulated]
105 _, checkStaticVolume := dv.Annotations[AnnCheckStaticVolume]
106 noTokenOkay := prePopulated || checkStaticVolume
107
108 targetNamespace, targetName := dv.Namespace, dv.Name
109 if targetNamespace == "" {
110 targetNamespace = requestNamespace
111 }
112 if saNamespace == "" {
113 saNamespace = targetNamespace
114 }
115 if targetName == "" {
116 targetName = requestName
117 }
118
119 cloneSourceHandler, err := newCloneSourceHandler(dv, proxy.GetDataSource)
120 if err != nil {
121 if k8serrors.IsNotFound(err) && noTokenOkay {
122
123 klog.V(3).Infof("DataVolume %s/%s is pre/static populated, not adding token, no datasource", targetNamespace, targetName)
124 return CloneAuthResponse{Allowed: true, Reason: "", Handler: cloneSourceHandler}, ErrNoTokenOkay
125 }
126 return CloneAuthResponse{Allowed: false, Reason: "", Handler: cloneSourceHandler}, err
127 }
128
129 if cloneSourceHandler.CloneType == noClone {
130 klog.V(3).Infof("DataVolume %s/%s not cloning", targetNamespace, targetName)
131 return CloneAuthResponse{Allowed: true, Reason: "", Handler: cloneSourceHandler}, ErrNoTokenOkay
132 }
133
134 sourceName, sourceNamespace := cloneSourceHandler.SourceName, cloneSourceHandler.SourceNamespace
135 if sourceNamespace == "" {
136 sourceNamespace = targetNamespace
137 }
138
139 _, err = proxy.GetNamespace(sourceNamespace)
140 if err != nil {
141 if k8serrors.IsNotFound(err) && noTokenOkay {
142
143 klog.V(3).Infof("DataVolume %s/%s is pre/static populated, not adding token, no source namespace", targetNamespace, targetName)
144 return CloneAuthResponse{Allowed: true, Reason: "", Handler: cloneSourceHandler}, ErrNoTokenOkay
145 }
146 return CloneAuthResponse{Allowed: false, Reason: "", Handler: cloneSourceHandler}, err
147 }
148
149 ok, reason, err := cloneSourceHandler.SACloneAuthFunc(proxy.CreateSar, sourceNamespace, sourceName, saNamespace, saName)
150 if err != nil {
151 return CloneAuthResponse{Allowed: false, Reason: reason, Handler: cloneSourceHandler}, err
152 }
153
154 if !ok {
155 if noTokenOkay {
156 klog.V(3).Infof("DataVolume %s/%s is pre/static populated, not adding token, auth failed", targetNamespace, targetName)
157 return CloneAuthResponse{Allowed: true, Reason: "", Handler: cloneSourceHandler}, ErrNoTokenOkay
158 }
159 }
160
161 return CloneAuthResponse{Allowed: ok, Reason: reason, Handler: cloneSourceHandler}, err
162 }
163
View as plain text