Add Order and Challenge API types

Signed-off-by: James Munnelly <james@munnelly.eu>
This commit is contained in:
James Munnelly 2018-09-13 17:59:07 +01:00
parent 620395511a
commit bfd8ac7eab
5 changed files with 263 additions and 72 deletions

View File

@ -59,17 +59,6 @@ func ConfigForDomain(cfgs []DomainSolverConfig, domain string) *DomainSolverConf
return &DomainSolverConfig{}
}
func (c *CertificateStatus) ACMEStatus() *CertificateACMEStatus {
// this is an edge case, but this will prevent panics
if c == nil {
return &CertificateACMEStatus{}
}
if c.ACME == nil {
c.ACME = &CertificateACMEStatus{}
}
return c.ACME
}
func (iss *Issuer) HasCondition(condition IssuerCondition) bool {
// this is an edge case, but this will prevent panics
if iss == nil {

View File

@ -55,6 +55,10 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&IssuerList{},
&ClusterIssuer{},
&ClusterIssuerList{},
&Order{},
&OrderList{},
&Challenge{},
&ChallengeList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil

View File

@ -99,29 +99,10 @@ type ACMECertificateConfig struct {
Config []DomainSolverConfig `json:"config"`
}
type DomainSolverConfig struct {
Domains []string `json:"domains"`
SolverConfig `json:",inline"`
}
type SolverConfig struct {
HTTP01 *HTTP01SolverConfig `json:"http01,omitempty"`
DNS01 *DNS01SolverConfig `json:"dns01,omitempty"`
}
type HTTP01SolverConfig struct {
Ingress string `json:"ingress"`
IngressClass *string `json:"ingressClass,omitempty"`
}
type DNS01SolverConfig struct {
Provider string `json:"provider"`
}
// CertificateStatus defines the observed state of Certificate
type CertificateStatus struct {
Conditions []CertificateCondition `json:"conditions,omitempty"`
ACME *CertificateACMEStatus `json:"acme,omitempty"`
Conditions []CertificateCondition `json:"conditions,omitempty"`
LastFailureTime *metav1.Time `json:"lastFailureTime,omitempty"`
}
// CertificateCondition contains condition information for an Certificate.
@ -159,43 +140,3 @@ const (
// validation was attempted.
CertificateConditionValidationFailed CertificateConditionType = "ValidateFailed"
)
// CertificateACMEStatus holds the status for an ACME issuer
type CertificateACMEStatus struct {
// Order contains details about the current in-progress ACME Order.
Order ACMEOrderStatus `json:"order,omitempty"`
}
type ACMEOrderStatus struct {
// The URL that can be used to get information about the ACME order.
URL string `json:"url"`
Challenges []ACMEOrderChallenge `json:"challenges,omitempty"`
}
type ACMEOrderChallenge struct {
// The URL that can be used to get information about the ACME challenge.
URL string `json:"url"`
// The URL that can be used to get information about the ACME authorization
// associated with the challenge.
AuthzURL string `json:"authzURL"`
// Type of ACME challenge
// Either http-01 or dns-01
Type string `json:"type"`
// Domain this challenge corresponds to
Domain string `json:"domain"`
// Challenge token for this challenge
Token string `json:"token"`
// Challenge key for this challenge
Key string `json:"key"`
// Set to true if this challenge is for a wildcard domain
Wildcard bool `json:"wildcard"`
// Configuration used to present this challenge
SolverConfig `json:",inline"`
}

View File

@ -0,0 +1,73 @@
/*
Copyright 2018 The Jetstack cert-manager contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// TODO: these types should be moved into their own API group once we have a loose
// coupling between ACME Issuers and their solver configurations (see: Solver proposal)
// +genclient
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:path=challenges
type Challenge struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec ChallengeSpec `json:"spec"`
Status ChallengeStatus `json:"status"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ChallengeList is a list of Challenges
type ChallengeList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []Challenge `json:"items"`
}
type ChallengeSpec struct {
AuthzURL string `json:"authzURL"`
Type string `json:"type"`
URL string `json:"url"`
DNSName string `json:"dnsName"`
Token string `json:"token"`
Key string `json:"key"`
Wildcard bool `json:"wildcard"`
// Config specifies the solver configuration for this challenge.
Config SolverConfig `json:"config"`
// IssuerRef references a properly configured ACME-type Issuer which should
// be used to create this Challenge.
// If the Issuer does not exist, processing will be retried.
// If the Issuer is not an 'ACME' Issuer, an error will be returned and the
// Challenge will be marked as failed.
IssuerRef ObjectReference `json:"issuerRef"`
}
type ChallengeStatus struct {
Presented bool `json:"presented"`
Reason string `json:"reason"`
State State `json:"state"`
}

View File

@ -0,0 +1,184 @@
/*
Copyright 2018 The Jetstack cert-manager contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// TODO: these types should be moved into their own API group once we have a loose
// coupling between ACME Issuers and their solver configurations (see: Solver proposal)
// +genclient
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:path=orders
type Order struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec OrderSpec `json:"spec"`
Status OrderStatus `json:"status"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// OrderList is a list of Orders
type OrderList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []Order `json:"items"`
}
type OrderSpec struct {
// Certificate signing request bytes in DER encoding.
// This will be used when finalizing the order.
// This field must be set on the order.
CSR []byte `json:"csr"`
// IssuerRef references a properly configured ACME-type Issuer which should
// be used to create this Order.
// If the Issuer does not exist, processing will be retried.
// If the Issuer is not an 'ACME' Issuer, an error will be returned and the
// Order will be marked as failed.
IssuerRef ObjectReference `json:"issuerRef"`
// CommonName is the common name as specified on the DER encoded CSR.
// If CommonName is not specified, the first DNSName specified will be used
// as the CommonName.
// At least on of CommonName or a DNSName must be set.
// This field must match the corresponding field on the DER encoded CSR.
CommonName string `json:"commonName,omitempty"`
// DNSNames is a list of DNS names that should be included as part of the Order
// validation process.
// If CommonName is not specified, the first DNSName specified will be used
// as the CommonName.
// At least on of CommonName or a DNSName must be set.
// This field must match the corresponding field on the DER encoded CSR.
DNSNames []string `json:"dnsNames,omitempty"`
// Config specifies a mapping from DNS identifiers to how those identifiers
// should be solved when performing ACME challenges.
// A config entry must exist for each domain listed in DNSNames and CommonName.
Config []DomainSolverConfig `json:"config"`
}
type OrderStatus struct {
// URL of the Order.
// This will initially be empty when the resource is first created.
// The Order controller will populate this field when the Order is first processed.
// This field will be immutable after it is initially set.
URL string `json:"url"`
// FinalizeURL of the Order.
// This is used to obtain certificates for this order once it has been completed.
FinalizeURL string `json:"finalizeURL"`
// CertificateURL is a URL that can be used to retrieve a copy of the signed
// TLS certificate for this order.
// It will be populated automatically once the order has completed successfully
// and the certificate is available for retrieval.
// +optional
CertificateURL string `json:"certificateURL,omitempty"`
// State contains the current state of this Order resource.
// States 'success' and 'expired' are 'final'
State State `json:"state"`
// Reason optionally provides more information about a why the order is in
// the current state.
Reason string `json:"reason"`
// Challenges is a list of ChallengeSpecs for Challenges that must be created
// in order to complete this Order.
Challenges []ChallengeSpec `json:"challenges,omitempty"`
// FailureTime stores the time that this order failed.
// This is used to influence garbage collection and back-off.
// The order resource will be automatically deleted after 30 minutes has
// passed since the failure time.
// +optional
FailureTime *metav1.Time `json:"failureTime,omitempty"`
}
// State represents the state of an ACME resource, such as an Order.
// The possible options here map to the corresponding values in the
// ACME specification.
// Full details of these values can be found there.
// Clients utilising this type **must** also gracefully handle unknown
// values, as the contents of this enumeration may be added to over time.
type State string
const (
// Unknown is not a real state as part of the ACME spec.
// It is used to represent an unrecognised value.
Unknown State = ""
// Valid signifies that an ACME resource is in a valid state.
// If an Order is marked 'valid', all validations on that Order
// have been completed successfully.
// This is a transient state as of ACME draft-12
Valid State = "valid"
// Ready signifies that an ACME resource is in a ready state.
// If an Order is marked 'Ready', the corresponding certificate
// is ready and can be obtained.
// This is a final state.
Ready State = "ready"
// Pending signifies that an ACME resource is still pending and is not yet ready.
// If an Order is marked 'Pending', the validations for that Order are still in progress.
// This is a transient state.
Pending State = "pending"
// Processing signifies that an ACME resource is being processed by the server.
// If an Order is marked 'Processing', the validations for that Order are currently being processed.
// This is a transient state.
Processing State = "processing"
// Invalid signifies that an ACME resource is invalid for some reason.
// If an Order is marked 'invalid', one of its validations be have invalid for some reason.
// This is a final state.
Invalid State = "invalid"
// Expired signifies that an ACME resource has expired.
// If an Order is marked 'Expired', one of its validations may have expired or the Order itself.
// This is a final state.
Expired State = "expired"
)
type SolverConfig struct {
HTTP01 *HTTP01SolverConfig `json:"http01,omitempty"`
DNS01 *DNS01SolverConfig `json:"dns01,omitempty"`
}
type HTTP01SolverConfig struct {
Ingress string `json:"ingress"`
IngressClass *string `json:"ingressClass,omitempty"`
}
type DNS01SolverConfig struct {
Provider string `json:"provider"`
}
type DomainSolverConfig struct {
Domains []string `json:"domains"`
SolverConfig `json:",inline"`
}