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
Initial codebase #1
Conversation
Signed-off-by: Jake Sanders <i@am.so-aweso.me>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Submitting now before I loose everything 😅
type GoogleCASIssuerSpec struct { | ||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster | ||
// Important: Run "make" to regenerate code after modifying this file | ||
|
||
// Project is the Google Cloud Project ID | ||
Project string `json:"project,omitempty"` | ||
|
||
// Location is the Google Cloud Project Location | ||
Location string `json:"location,omitempty"` | ||
|
||
// CertificateAuthorityID is The ID of the Google Private certificate authority that will sign certificates | ||
CertificateAuthorityID string `json:"certificateAuthorityID,omitempty"` | ||
|
||
// Credentials is a reference to a Kubernetes Secret Key that contains Google Service Account Credentials | ||
// +optional | ||
Credentials SecretKeySelector `json:"credentials,omitempty"` | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we can use the same Spec struct for both cluster and non cluster scoped Issuers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the secret namespace is set on a flag, they become identical
import ( | ||
"bytes" | ||
"context" | ||
"errors" | ||
"fmt" | ||
"github.com/go-logr/logr" | ||
apiutil "github.com/jetstack/cert-manager/pkg/api/util" | ||
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1" | ||
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1" | ||
api "github.com/jetstack/google-cas-issuer/api/v1alpha1" | ||
"github.com/jetstack/google-cas-issuer/util/cas" | ||
core "k8s.io/api/core/v1" | ||
apierrors "k8s.io/apimachinery/pkg/api/errors" | ||
"k8s.io/apimachinery/pkg/types" | ||
"k8s.io/client-go/tools/record" | ||
"math/rand" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Break out imports into blocks;
local
external
internal
if err := r.Client.Get(ctx, req.NamespacedName, cr); err != nil { | ||
if apierrors.IsNotFound(err) { | ||
return ctrl.Result{}, nil | ||
} | ||
|
||
log.Error(err, "failed to retrieve CertificateRequest resource") | ||
return ctrl.Result{}, err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I prefer the err blocks to be two distinct blocks, rather than in the same if: https://github.com/jetstack/cert-manager/blob/d4c9a7beb4ab7c734c84f2f3a46b9613997e6172/pkg/controller/certificaterequests/sync.go#L74
main.go
Outdated
import ( | ||
"flag" | ||
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1" | ||
"os" | ||
|
||
"k8s.io/apimachinery/pkg/runtime" | ||
clientgoscheme "k8s.io/client-go/kubernetes/scheme" | ||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/log/zap" | ||
|
||
issuersv1alpha1 "github.com/jetstack/google-cas-issuer/api/v1alpha1" | ||
"github.com/jetstack/google-cas-issuer/controllers" | ||
// +kubebuilder:scaffold:imports | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: imports
// +kubebuilder:scaffold:scheme | ||
} | ||
|
||
func main() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: move business logic into /cmd/app or something similar. main should contain the bare minimum to execute an app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made a few more comments, let me know if it doesn't make sense!
/assign @jakexks
) | ||
|
||
// ClusterIssuers is a store for reconciled ClusterIssuers | ||
var ClusterIssuers *sync.Map |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sync.Map is slow. Can we safely use a map[string]struct{} instead?
r.setStatusCondition(ctx, log, &issuer, issuersv1alpha1.IssuerConditionReady, issuersv1alpha1.ConditionFalse, "CASError", "Cas error: "+err.Error()) | ||
return ctrl.Result{}, err | ||
} | ||
ClusterIssuers.Store(req.NamespacedName, casClient) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these client keeping a long lived connection for the entire issue lifecycle? What happens if the client looses connection?
I'm not against having long lived for the entire lifecycle, but we should be able to properly handle loosing connection etc., and mark the issuer as not ready.
func (r *GoogleCASIssuerReconciler) setStatusCondition(ctx context.Context, | ||
log logr.Logger, | ||
issuer *issuersv1alpha1.GoogleCASIssuer, | ||
conditionType issuersv1alpha1.GoogleCASIssuerConditionType, | ||
status issuersv1alpha1.ConditionStatus, | ||
reason string, | ||
message string) { | ||
newCondition := issuersv1alpha1.GoogleCASIssuerCondition{ | ||
Type: conditionType, | ||
Status: status, | ||
Reason: reason, | ||
Message: message, | ||
} | ||
nowTime := metav1.NewTime(time.Now()) | ||
newCondition.LastTransitionTime = &nowTime | ||
// Search through existing conditions | ||
for i, cond := range issuer.Status.Conditions { | ||
// Skip unrelated conditions | ||
if cond.Type != conditionType { | ||
continue | ||
} | ||
|
||
// If this update doesn't contain a state transition, we don't update | ||
// the conditions LastTransitionTime to Now() | ||
if cond.Status == status { | ||
newCondition.LastTransitionTime = cond.LastTransitionTime | ||
} else { | ||
log.Info("Updating last transition time for issuer "+issuer.Name, "condition", conditionType, "old_status", cond.Status, "new_status", status, "time", nowTime.Time) | ||
} | ||
|
||
// Overwrite the existing condition | ||
issuer.Status.Conditions[i] = newCondition | ||
if err := r.Client.Status().Update(ctx, issuer); err != nil { | ||
log.Info("Couldn't update issuer condition:", "err", err) | ||
} | ||
return | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to see some table tests for these condition settings.
main.go
Outdated
|
||
ctrl.SetLogger(zap.New(zap.UseDevMode(true))) | ||
|
||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we exposing flags for the kube client config?
util/cas/certificateauthority.go
Outdated
// CreateCA creates a new certificate authority | ||
func (c *casClient) CreateCA(options *CreateCAOptions) error { | ||
// TODO: should the timeout be configurable? | ||
timeout, cancel := context.WithTimeout(context.Background(), 30*time.Second) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
timeout -> ctx
util/cas/certificateauthority.go
Outdated
if err != nil { | ||
return err | ||
} | ||
_, err = operation.Wait(timeout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_, err = operation.Wait(timeout); if err != nil
Can you add a comment to what this is doing? It seems like it is waiting for either a success/fail of the call, or the timeout context to expire, but this timeout has already been passed to the previous call.
It would make sense to change the CreateCertificateAuthority to pass in the original context, and then create a "timeout" context, just for this Wait call.
util/cas/certificateauthority.go
Outdated
} | ||
|
||
// ListCA returns a list of all certificate authorities we have access to | ||
func (c *casClient) ListCA(options *ListCAOptions) ([]string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass in context
util/cas/certificate.go
Outdated
|
||
// CreateCertificate Signs a certificate | ||
func (c *casClient) CreateCertificate(options *CreateCertificateOptions) (string, []string, error) { | ||
timeout, cancel := context.WithTimeout(context.Background(), 30*time.Second) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass in context to this func. Not sure a timeout is really required here.
main.go
Outdated
// +kubebuilder:scaffold:builder | ||
|
||
setupLog.Info("starting manager") | ||
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should create a context here based upon the signal handler, this can then be passed and wrapped to all other recievers.
Signed-off-by: Jake Sanders <i@am.so-aweso.me>
Merging so we can make this public, we can make changes later. /lgtm |
No description provided.