Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 1 addition & 49 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pod/origin-ca-issuer-1234568-abcdw 1/1 Running 0 1m

*** Adding an OriginIssuer
**** API Token
Origin CA Issuer can use an API token that contains the "Zone / SSL and Certificates / Edit" permission, which can be scoped to specific accounts or zones. Both [[https://developers.cloudflare.com/fundamentals/api/get-started/create-token/][user API tokens]] and [[https://developers.cloudflare.com/fundamentals/api/get-started/account-owned-tokens/][Account owned tokens]] are supported.
Origin CA Issuer can use an API token that contains the "Zone / SSL and Certificates / Edit" permission, which can be scoped to specific accounts or zones. Both [[https://developers.cloudflare.com/fundamentals/api/get-started/create-token/][User API tokens]] and [[https://developers.cloudflare.com/fundamentals/api/get-started/account-owned-tokens/][Account API tokens]] are supported. However, *Account API tokens are strongly recommended* to ensure that your infrastructure continues working even if a user is removed from an account.

#+BEGIN_SRC sh :file ./deploy/example/cfapi-token.secret.yaml :results silent file :exports code
kubectl create secret generic \
Expand Down Expand Up @@ -86,54 +86,6 @@ $ kubectl get originissuer.cert-manager.k8s.cloudflare.com prod-issuer -o json |
]
#+END_EXAMPLE

**** Origin CA Service Key
The [[https://developers.cloudflare.com/fundamentals/api/get-started/ca-keys/][Origin CA Key]] is supported but discouraged in favor of API tokens. This key will begin with "v1.0-" and is different from the legacy "Global API Key".

#+BEGIN_SRC sh :file ./deploy/example/service-key.secret.yaml :results silent file :exports code
kubectl create secret generic \
--dry-run \
-n default service-key \
--from-literal key=v1.0-FFFFFFF-FFFFFFFF -oyaml
#+END_SRC

Then create an OriginIssuer referencing the secret created above.

#+BEGIN_SRC yaml :tangle ./deploy/example/service-key.issuer.yaml :comments link
apiVersion: cert-manager.k8s.cloudflare.com/v1
kind: OriginIssuer
metadata:
name: prod-issuer
namespace: default
spec:
requestType: OriginECC
auth:
serviceKeyRef:
name: service-key
key: key
#+END_SRC

#+BEGIN_EXAMPLE
$ kubectl apply -f service-key.secret.yaml -f issuer.yaml
originissuer.cert-manager.k8s.cloudflare.com/prod-issuer created
secret/service-key created
#+END_EXAMPLE

The status conditions of the OriginIssuer resource will be updated once the Origin CA Issuer is ready.

#+BEGIN_EXAMPLE
$ kubectl get originissuer.cert-manager.k8s.cloudflare.com prod-issuer -o json | jq .status.conditions
[
{
"lastTransitionTime": "2020-10-07T00:05:00Z",
"message": "Succeeded checking the issuer",
"reason": "Checked",
"observedGeneration": 1,
"status": "True",
"type": "Ready"
}
]
#+END_EXAMPLE

*** Creating our first certificate

We can create a cert-manager managed certificate, which will be automatically rotated by cert-manager before expiration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,6 @@ spec:
description: Auth configures how to authenticate with the Cloudflare
API.
properties:
serviceKeyRef:
description: ServiceKeyRef authenticates with an API Service Key
(the "Origin CA Key").
properties:
key:
description: Key of the secret to select from. Must be a valid
secret key.
type: string
name:
description: |-
Name of the secret in the issuer's namespace to select. If a cluster-scoped
issuer, the secret is selected from the "cluster resource namespace" configured
on the controller.
type: string
required:
- key
- name
type: object
tokenRef:
description: TokenRef authenticates with an API Token.
properties:
Expand All @@ -81,12 +63,9 @@ spec:
- key
- name
type: object
required:
- tokenRef
type: object
x-kubernetes-validations:
- message: exactly one of the fields in [serviceKeyRef tokenRef] must
be set
rule: '[has(self.serviceKeyRef),has(self.tokenRef)].filter(x,x==true).size()
== 1'
requestType:
description: RequestType is the signature algorithm Cloudflare should
use to sign the certificate.
Expand Down
25 changes: 2 additions & 23 deletions deploy/crds/cert-manager.k8s.cloudflare.com_originissuers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,6 @@ spec:
description: Auth configures how to authenticate with the Cloudflare
API.
properties:
serviceKeyRef:
description: ServiceKeyRef authenticates with an API Service Key
(the "Origin CA Key").
properties:
key:
description: Key of the secret to select from. Must be a valid
secret key.
type: string
name:
description: |-
Name of the secret in the issuer's namespace to select. If a cluster-scoped
issuer, the secret is selected from the "cluster resource namespace" configured
on the controller.
type: string
required:
- key
- name
type: object
tokenRef:
description: TokenRef authenticates with an API Token.
properties:
Expand All @@ -81,12 +63,9 @@ spec:
- key
- name
type: object
required:
- tokenRef
type: object
x-kubernetes-validations:
- message: exactly one of the fields in [serviceKeyRef tokenRef] must
be set
rule: '[has(self.serviceKeyRef),has(self.tokenRef)].filter(x,x==true).size()
== 1'
requestType:
description: RequestType is the signature algorithm Cloudflare should
use to sign the certificate.
Expand Down
8 changes: 0 additions & 8 deletions deploy/example/secvice-key.secret.yaml

This file was deleted.

13 changes: 0 additions & 13 deletions deploy/example/service-key.issuer.yaml

This file was deleted.

22 changes: 6 additions & 16 deletions internal/cfapi/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,14 @@ import (
)

type Builder struct {
hc *http.Client
serviceKey []byte
token []byte
hc *http.Client
token []byte
}

func NewBuilder() *Builder {
return &Builder{}
}

func (b *Builder) WithServiceKey(key []byte) *Builder {
b.serviceKey = key
return b
}

func (b *Builder) WithToken(token []byte) *Builder {
b.token = token
return b
Expand All @@ -31,18 +25,14 @@ func (b *Builder) WithClient(hc *http.Client) *Builder {

func (b *Builder) Clone() *Builder {
return &Builder{
hc: b.hc,
serviceKey: b.serviceKey,
hc: b.hc,
token: b.token,
}
}

func (b *Builder) Build() *Client {
switch {
case b.serviceKey != nil:
return New(WithServiceKey(b.serviceKey), WithClient(b.hc))
case b.token != nil:
if b.token != nil {
return New(WithToken(b.token), WithClient(b.hc))
default:
return nil
}
return nil
}
16 changes: 3 additions & 13 deletions internal/cfapi/cfapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ type Interface interface {
}

type Client struct {
serviceKey []byte
token []byte
client *http.Client
endpoint string
token []byte
client *http.Client
endpoint string
}

func New(options ...Options) *Client {
Expand All @@ -38,12 +37,6 @@ func New(options ...Options) *Client {

type Options func(c *Client)

func WithServiceKey(key []byte) Options {
return func(c *Client) {
c.serviceKey = key
}
}

func WithToken(token []byte) Options {
return func(c *Client) {
c.token = token
Expand Down Expand Up @@ -125,9 +118,6 @@ func (c *Client) Sign(ctx context.Context, req *SignRequest) (*SignResponse, err

r.Header.Add("User-Agent", "origin-ca-issuer/"+version.Version())

if c.serviceKey != nil {
r.Header.Add("X-Auth-User-Service-Key", string(c.serviceKey))
}
if c.token != nil {
r.Header.Add("Authorization", "Bearer "+string(c.token))
}
Expand Down
2 changes: 1 addition & 1 deletion internal/cfapi/cfapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func TestSign(t *testing.T) {
defer ts.Close()

client := New(
WithServiceKey([]byte("v1.0-FFFF-FFFF")),
WithToken([]byte("test-api-token")),
WithClient(ts.Client()),
Must(WithEndpoint(ts.URL)),
)
Expand Down
21 changes: 5 additions & 16 deletions pkgs/apis/v1/issuers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import (
type AuthType int

const (
AuthTypeUnknown AuthType = 0
AuthTypeServiceKey AuthType = 1
AuthTypeAPIToken AuthType = 2
AuthTypeUnknown AuthType = 0
AuthTypeAPIToken AuthType = 2
)

var _ issuerv1alpha1.Issuer = (*OriginIssuer)(nil)
Expand Down Expand Up @@ -57,22 +56,12 @@ func (iss *ClusterOriginIssuer) GetRequestType() RequestType {
}

func (a OriginIssuerAuthentication) GetSecretKeySelector() *SecretKeySelector {
switch {
case a.ServiceKeyRef != nil:
return a.ServiceKeyRef
case a.TokenRef != nil:
return a.TokenRef
}
return nil
return a.TokenRef
}

func (a OriginIssuerAuthentication) GetType() AuthType {
switch {
case a.ServiceKeyRef != nil:
return AuthTypeServiceKey
case a.TokenRef != nil:
if a.TokenRef != nil {
return AuthTypeAPIToken
default:
return AuthTypeUnknown
}
return AuthTypeUnknown
}
10 changes: 1 addition & 9 deletions pkgs/apis/v1/types_originissuer.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,9 @@ type OriginIssuerSpec struct {
}

// OriginIssuerAuthentication defines how to authenticate with the Cloudflare API.
// Only one of `serviceKeyRef` may be specified.
//
// +kubebuilder:validation:ExactlyOneOf=serviceKeyRef;tokenRef
type OriginIssuerAuthentication struct {
// ServiceKeyRef authenticates with an API Service Key (the "Origin CA Key").
// +optional
ServiceKeyRef *SecretKeySelector `json:"serviceKeyRef,omitempty"`

// TokenRef authenticates with an API Token.
// +optional
TokenRef *SecretKeySelector `json:"tokenRef,omitempty"`
TokenRef *SecretKeySelector `json:"tokenRef"`
}

// SecretKeySelector contains a reference to a secret.
Expand Down
5 changes: 0 additions & 5 deletions pkgs/apis/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions pkgs/controllers/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ func (s *Signer) Sign(ctx context.Context, req signer.CertificateRequestObject,

var client *cfapi.Client
switch iss.GetAuth().GetType() {
case v1.AuthTypeServiceKey:
client = s.Builder.Clone().WithServiceKey(token).Build()
case v1.AuthTypeAPIToken:
client = s.Builder.Clone().WithToken(token).Build()
default:
Expand Down
10 changes: 5 additions & 5 deletions pkgs/controllers/signer_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,20 @@ func TestOriginIssuerCertificateRequestE2E(t *testing.T) {
Spec: v1.OriginIssuerSpec{
RequestType: v1.RequestTypeOriginECC,
Auth: v1.OriginIssuerAuthentication{
ServiceKeyRef: &v1.SecretKeySelector{
Name: "issuer-service-key",
Key: "key",
TokenRef: &v1.SecretKeySelector{
Name: "issuer-token",
Key: "token",
},
},
},
}
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "issuer-service-key",
Name: "issuer-token",
Namespace: "default",
},
Data: map[string][]byte{
"key": []byte("v1.0-0x00BAB10C"),
"token": []byte("api-token"),
},
}
request := cmgen.CertificateRequest("foobar",
Expand Down
Loading