Merge "prodvider: fix build after k8s update, add to CI presubmit"
diff --git a/ci_presubmit.sh b/ci_presubmit.sh
index 5abaf10..1739e5d 100755
--- a/ci_presubmit.sh
+++ b/ci_presubmit.sh
@@ -19,3 +19,6 @@
 kubecfg version
 prodaccess --help 2>/dev/null
 bazel run //cluster/clustercfg smoketest
+
+# Test critical services.
+bazel build //cluster/prodvider
diff --git a/cluster/prodvider/hspki.go b/cluster/prodvider/hspki.go
index e747889..fabf84d 100644
--- a/cluster/prodvider/hspki.go
+++ b/cluster/prodvider/hspki.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"context"
 	"encoding/pem"
 	"fmt"
 	"time"
@@ -17,7 +18,7 @@
 
 // hspkiSigner returns a cfssl signer (CA) for HSPKI, by loading the CA
 // cert/key from Kubernetes.
-func (p *prodvider) hspkiSigner() (*local.Signer, error) {
+func (p *prodvider) hspkiSigner(ctx context.Context) (*local.Signer, error) {
 	policy := &config.Signing{
 		Profiles: map[string]*config.SigningProfile{
 			"client-server": &config.SigningProfile{
@@ -28,7 +29,7 @@
 		Default: config.DefaultConfig(),
 	}
 
-	secret, err := p.k8s.CoreV1().Secrets("cert-manager").Get("pki-selfsigned-cert", metav1.GetOptions{})
+	secret, err := p.k8s.CoreV1().Secrets("cert-manager").Get(ctx, "pki-selfsigned-cert", metav1.GetOptions{})
 	if err != nil {
 		return nil, fmt.Errorf("hspki secret get failed: %w", err)
 	}
@@ -48,10 +49,10 @@
 
 // hspkiCreds returns a HSPKI certificate/key for an SSO user. The returned
 // certificate is valida for both server and client usage.
-func (p *prodvider) hspkiCreds(username string) (*pb.HSPKIKeys, error) {
+func (p *prodvider) hspkiCreds(ctx context.Context, username string) (*pb.HSPKIKeys, error) {
 	principal := fmt.Sprintf("%s.sso.hswaw.net", username)
 
-	s, err := p.hspkiSigner()
+	s, err := p.hspkiSigner(ctx)
 	if err != nil {
 		return nil, fmt.Errorf("hspkiSigner: %w", err)
 	}
diff --git a/cluster/prodvider/kubernetes.go b/cluster/prodvider/kubernetes.go
index 3386625..d7ad535 100644
--- a/cluster/prodvider/kubernetes.go
+++ b/cluster/prodvider/kubernetes.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"context"
 	"encoding/pem"
 	"fmt"
 	"time"
@@ -93,23 +94,23 @@
 //    system:admin-namespace to the user within their personal namespace
 //  - have a sso:<username>:global clusterrolebinding that binds
 //    system:viewer to the user at cluster level
-func (p *prodvider) kubernetesSetupUser(username string) error {
+func (p *prodvider) kubernetesSetupUser(ctx context.Context, username string) error {
 	namespace := "personal-" + username
-	if err := p.ensureNamespace(namespace); err != nil {
+	if err := p.ensureNamespace(ctx, namespace); err != nil {
 		return err
 	}
-	if err := p.ensureRoleBindingPersonal(namespace, username); err != nil {
+	if err := p.ensureRoleBindingPersonal(ctx, namespace, username); err != nil {
 		return err
 	}
-	if err := p.ensureClusterRoleBindingGlobal(username); err != nil {
+	if err := p.ensureClusterRoleBindingGlobal(ctx, username); err != nil {
 		return err
 	}
 
 	return nil
 }
 
-func (p *prodvider) ensureNamespace(name string) error {
-	_, err := p.k8s.CoreV1().Namespaces().Get(name, metav1.GetOptions{})
+func (p *prodvider) ensureNamespace(ctx context.Context, name string) error {
+	_, err := p.k8s.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{})
 	switch {
 	case err == nil:
 		// Already exists, nothing to do
@@ -125,11 +126,11 @@
 			Name: name,
 		},
 	}
-	_, err = p.k8s.CoreV1().Namespaces().Create(ns)
+	_, err = p.k8s.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{})
 	return err
 }
 
-func (p *prodvider) ensureRoleBindingPersonal(namespace, username string) error {
+func (p *prodvider) ensureRoleBindingPersonal(ctx context.Context, namespace, username string) error {
 	name := "sso:" + username + ":personal"
 	rb := &rbacv1.RoleBinding{
 		ObjectMeta: metav1.ObjectMeta{
@@ -151,15 +152,15 @@
 	}
 
 	rbs := p.k8s.RbacV1().RoleBindings(namespace)
-	_, err := rbs.Get(name, metav1.GetOptions{})
+	_, err := rbs.Get(ctx, name, metav1.GetOptions{})
 	switch {
 	case err == nil:
 		// Already exists, update.
-		_, err = rbs.Update(rb)
+		_, err = rbs.Update(ctx, rb, metav1.UpdateOptions{})
 		return err
 	case errors.IsNotFound(err):
 		// Create.
-		_, err = rbs.Create(rb)
+		_, err = rbs.Create(ctx, rb, metav1.CreateOptions{})
 		return err
 	default:
 		// Something went wrong.
@@ -167,7 +168,7 @@
 	}
 }
 
-func (p *prodvider) ensureClusterRoleBindingGlobal(username string) error {
+func (p *prodvider) ensureClusterRoleBindingGlobal(ctx context.Context, username string) error {
 	name := "sso:" + username + ":global"
 	rb := &rbacv1.ClusterRoleBinding{
 		ObjectMeta: metav1.ObjectMeta{
@@ -188,15 +189,15 @@
 	}
 
 	crbs := p.k8s.RbacV1().ClusterRoleBindings()
-	_, err := crbs.Get(name, metav1.GetOptions{})
+	_, err := crbs.Get(ctx, name, metav1.GetOptions{})
 	switch {
 	case err == nil:
 		// Already exists, update.
-		_, err = crbs.Update(rb)
+		_, err = crbs.Update(ctx, rb, metav1.UpdateOptions{})
 		return err
 	case errors.IsNotFound(err):
 		// Create.
-		_, err = crbs.Create(rb)
+		_, err = crbs.Create(ctx, rb, metav1.CreateOptions{})
 		return err
 	default:
 		// Something went wrong.
diff --git a/cluster/prodvider/service.go b/cluster/prodvider/service.go
index 17dfe6e..160f260 100644
--- a/cluster/prodvider/service.go
+++ b/cluster/prodvider/service.go
@@ -63,7 +63,7 @@
 		return nil, status.Error(codes.PermissionDenied, "not part of staff or kubernetes-users")
 	}
 
-	err = p.kubernetesSetupUser(username)
+	err = p.kubernetesSetupUser(ctx, username)
 	if err != nil {
 		glog.Errorf("kubernetesSetupUser(%v): %v", username, err)
 		return nil, status.Error(codes.Unavailable, "could not set up objects in Kubernetes")
@@ -75,7 +75,7 @@
 		return nil, status.Error(codes.Unavailable, "could not generate k8s keys")
 	}
 
-	hspkiKeys, err := p.hspkiCreds(username)
+	hspkiKeys, err := p.hspkiCreds(ctx, username)
 	if err != nil {
 		glog.Errorf("hspkiCreds(%q): %v", username, err)
 		return nil, status.Error(codes.Unavailable, "could not generate hspki keys")