refreshCredsLocked executes the plugin and reads the credentials from stdout. It must be called while holding the Authenticator's mutex.
(r *clientauthentication.Response)
| 280 | // refreshCredsLocked executes the plugin and reads the credentials from |
| 281 | // stdout. It must be called while holding the Authenticator's mutex. |
| 282 | func (a *Authenticator) refreshCredsLocked(r *clientauthentication.Response) error { |
| 283 | cred := &clientauthentication.ExecCredential{ |
| 284 | Spec: clientauthentication.ExecCredentialSpec{ |
| 285 | Response: r, |
| 286 | Interactive: a.interactive, |
| 287 | }, |
| 288 | } |
| 289 | |
| 290 | env := append(a.environ(), a.env...) |
| 291 | if a.group == v1alpha1.SchemeGroupVersion { |
| 292 | // Input spec disabled for beta due to lack of use. Possibly re-enable this later if |
| 293 | // someone wants it back. |
| 294 | // |
| 295 | // See: https://github.com/kubernetes/kubernetes/issues/61796 |
| 296 | data, err := runtime.Encode(codecs.LegacyCodec(a.group), cred) |
| 297 | if err != nil { |
| 298 | return fmt.Errorf("encode ExecCredentials: %v", err) |
| 299 | } |
| 300 | env = append(env, fmt.Sprintf("%s=%s", execInfoEnv, data)) |
| 301 | } |
| 302 | |
| 303 | stdout := &bytes.Buffer{} |
| 304 | cmd := exec.Command(a.cmd, a.args...) |
| 305 | cmd.Env = env |
| 306 | cmd.Stderr = a.stderr |
| 307 | cmd.Stdout = stdout |
| 308 | if a.interactive { |
| 309 | cmd.Stdin = a.stdin |
| 310 | } |
| 311 | |
| 312 | if err := cmd.Run(); err != nil { |
| 313 | return fmt.Errorf("exec: %v", err) |
| 314 | } |
| 315 | |
| 316 | _, gvk, err := codecs.UniversalDecoder(a.group).Decode(stdout.Bytes(), nil, cred) |
| 317 | if err != nil { |
| 318 | return fmt.Errorf("decoding stdout: %v", err) |
| 319 | } |
| 320 | if gvk.Group != a.group.Group || gvk.Version != a.group.Version { |
| 321 | return fmt.Errorf("exec plugin is configured to use API version %s, plugin returned version %s", |
| 322 | a.group, schema.GroupVersion{Group: gvk.Group, Version: gvk.Version}) |
| 323 | } |
| 324 | |
| 325 | if cred.Status == nil { |
| 326 | return fmt.Errorf("exec plugin didn't return a status field") |
| 327 | } |
| 328 | if cred.Status.Token == "" && cred.Status.ClientCertificateData == "" && cred.Status.ClientKeyData == "" { |
| 329 | return fmt.Errorf("exec plugin didn't return a token or cert/key pair") |
| 330 | } |
| 331 | if (cred.Status.ClientCertificateData == "") != (cred.Status.ClientKeyData == "") { |
| 332 | return fmt.Errorf("exec plugin returned only certificate or key, not both") |
| 333 | } |
| 334 | |
| 335 | if cred.Status.ExpirationTimestamp != nil { |
| 336 | a.exp = cred.Status.ExpirationTimestamp.Time |
| 337 | } else { |
| 338 | a.exp = time.Time{} |
| 339 | } |