mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Merge pull request #20142 from bprashanth/ing_tls
Auto commit by PR queue bot
This commit is contained in:
commit
6b20879a7f
@ -3616,6 +3616,13 @@
|
||||
"$ref": "v1beta1.IngressBackend",
|
||||
"description": "A default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default."
|
||||
},
|
||||
"tls": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "v1beta1.IngressTLS"
|
||||
},
|
||||
"description": "TLS configuration. Currently the Ingress only supports a single TLS port, 443, and assumes TLS termination. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension."
|
||||
},
|
||||
"rules": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -3643,6 +3650,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.IngressTLS": {
|
||||
"id": "v1beta1.IngressTLS",
|
||||
"description": "IngressTLS describes the transport layer security associated with an Ingress.",
|
||||
"properties": {
|
||||
"hosts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified."
|
||||
},
|
||||
"secretName": {
|
||||
"type": "string",
|
||||
"description": "SecretName is the name of the secret used to terminate SSL traffic on 443. Field is left optional to allow SSL routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.IngressRule": {
|
||||
"id": "v1beta1.IngressRule",
|
||||
"description": "IngressRule represents the rules mapping the paths under a specified host to the related backend services. Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.",
|
||||
|
@ -726,6 +726,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">tls</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">TLS configuration. Currently the Ingress only supports a single TLS port, 443, and assumes TLS termination. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1beta1_ingresstls">v1beta1.IngressTLS</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">rules</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
@ -2631,6 +2638,40 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_flockervolumesource">v1.FlockerVolumeSource</h3>
|
||||
<div class="paragraph">
|
||||
<p>Represents a Flocker volume mounted by the Flocker agent. Flocker volumes do not support ownership management or SELinux relabeling.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">datasetName</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Required: the volume name. This is going to be store on metadata → name on the payload for Flocker</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_awselasticblockstorevolumesource">v1.AWSElasticBlockStoreVolumeSource</h3>
|
||||
@ -2730,40 +2771,6 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_flockervolumesource">v1.FlockerVolumeSource</h3>
|
||||
<div class="paragraph">
|
||||
<p>Represents a Flocker volume mounted by the Flocker agent. Flocker volumes do not support ownership management or SELinux relabeling.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">datasetName</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Required: the volume name. This is going to be store on metadata → name on the payload for Flocker</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_unversioned_listmeta">unversioned.ListMeta</h3>
|
||||
@ -4612,6 +4619,47 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_ingresstls">v1beta1.IngressTLS</h3>
|
||||
<div class="paragraph">
|
||||
<p>IngressTLS describes the transport layer security associated with an Ingress.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hosts</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">secretName</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">SecretName is the name of the secret used to terminate SSL traffic on 443. Field is left optional to allow SSL routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_subresourcereference">v1beta1.SubresourceReference</h3>
|
||||
@ -4886,7 +4934,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2016-02-05 16:19:07 UTC
|
||||
Last updated 2016-02-05 18:58:44 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -2241,6 +2241,21 @@ const (
|
||||
|
||||
// SSHAuthPrivateKey is the key of the required SSH private key for SecretTypeSSHAuth secrets
|
||||
SSHAuthPrivateKey = "ssh-privatekey"
|
||||
|
||||
// SecretTypeTLS contains information about a TLS client or server secret. It
|
||||
// is primarily used with TLS termination of the Ingress resource, but may be
|
||||
// used in other types.
|
||||
//
|
||||
// Required fields:
|
||||
// - Secret.Data["tls.key"] - TLS private key.
|
||||
// Secret.Data["tls.crt"] - TLS certificate.
|
||||
// TODO: Consider supporting different formats, specifying CA/destinationCA.
|
||||
SecretTypeTLS SecretType = "kubernetes.io/tls"
|
||||
|
||||
// TLSCertKey is the key for tls certificates in a TLS secert.
|
||||
TLSCertKey = "tls.crt"
|
||||
// TLSPrivateKeyKey is the key for the private key field in a TLS secret.
|
||||
TLSPrivateKeyKey = "tls.key"
|
||||
)
|
||||
|
||||
type SecretList struct {
|
||||
|
@ -2653,6 +2653,21 @@ const (
|
||||
|
||||
// DockerConfigKey is the key of the required data for SecretTypeDockercfg secrets
|
||||
DockerConfigKey = ".dockercfg"
|
||||
|
||||
// SecretTypeTLS contains information about a TLS client or server secret. It
|
||||
// is primarily used with TLS termination of the Ingress resource, but may be
|
||||
// used in other types.
|
||||
//
|
||||
// Required fields:
|
||||
// - Secret.Data["tls.key"] - TLS private key.
|
||||
// Secret.Data["tls.crt"] - TLS certificate.
|
||||
// TODO: Consider supporting different formats, specifying CA/destinationCA.
|
||||
SecretTypeTLS SecretType = "kubernetes.io/tls"
|
||||
|
||||
// TLSCertKey is the key for tls certificates in a TLS secert.
|
||||
TLSCertKey = "tls.crt"
|
||||
// TLSPrivateKeyKey is the key for the private key field in a TLS secret.
|
||||
TLSPrivateKeyKey = "tls.key"
|
||||
)
|
||||
|
||||
// SecretList is a list of Secret.
|
||||
|
@ -2083,6 +2083,14 @@ func ValidateSecret(secret *api.Secret) field.ErrorList {
|
||||
break
|
||||
}
|
||||
|
||||
case api.SecretTypeTLS:
|
||||
if _, exists := secret.Data[api.TLSCertKey]; !exists {
|
||||
allErrs = append(allErrs, field.Required(dataPath.Key(api.TLSCertKey), ""))
|
||||
}
|
||||
if _, exists := secret.Data[api.TLSPrivateKeyKey]; !exists {
|
||||
allErrs = append(allErrs, field.Required(dataPath.Key(api.TLSPrivateKeyKey), ""))
|
||||
}
|
||||
// TODO: Verify that the key matches the cert.
|
||||
default:
|
||||
// no-op
|
||||
}
|
||||
|
@ -4583,6 +4583,52 @@ func TestValidateEndpoints(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateTLSSecret(t *testing.T) {
|
||||
successCases := map[string]api.Secret{
|
||||
"emtpy certificate chain": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "tls-cert", Namespace: "namespace"},
|
||||
Data: map[string][]byte{
|
||||
api.TLSCertKey: []byte("public key"),
|
||||
api.TLSPrivateKeyKey: []byte("private key"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, v := range successCases {
|
||||
if errs := ValidateSecret(&v); len(errs) != 0 {
|
||||
t.Errorf("Expected success for %s, got %v", k, errs)
|
||||
}
|
||||
}
|
||||
errorCases := map[string]struct {
|
||||
secrets api.Secret
|
||||
errorType field.ErrorType
|
||||
errorDetail string
|
||||
}{
|
||||
"missing public key": {
|
||||
secrets: api.Secret{
|
||||
ObjectMeta: api.ObjectMeta{Name: "tls-cert"},
|
||||
Data: map[string][]byte{
|
||||
api.TLSCertKey: []byte("public key"),
|
||||
},
|
||||
},
|
||||
errorType: "FieldValueRequired",
|
||||
},
|
||||
"missing private key": {
|
||||
secrets: api.Secret{
|
||||
ObjectMeta: api.ObjectMeta{Name: "tls-cert"},
|
||||
Data: map[string][]byte{
|
||||
api.TLSCertKey: []byte("public key"),
|
||||
},
|
||||
},
|
||||
errorType: "FieldValueRequired",
|
||||
},
|
||||
}
|
||||
for k, v := range errorCases {
|
||||
if errs := ValidateSecret(&v.secrets); len(errs) == 0 || errs[0].Type != v.errorType || !strings.Contains(errs[0].Detail, v.errorDetail) {
|
||||
t.Errorf("[%s] Expected error type %s with detail %q, got %v", k, v.errorType, v.errorDetail, errs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateSecurityContext(t *testing.T) {
|
||||
priv := false
|
||||
var runAsUser int64 = 1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -643,12 +643,35 @@ type IngressSpec struct {
|
||||
// is optional to allow the loadbalancer controller or defaulting logic to
|
||||
// specify a global default.
|
||||
Backend *IngressBackend `json:"backend,omitempty"`
|
||||
|
||||
// TLS is the TLS configuration. Currently the Ingress only supports a single TLS
|
||||
// port, 443, and assumes TLS termination. If multiple members of this
|
||||
// list specify different hosts, they will be multiplexed on the same
|
||||
// port according to the hostname specified through the SNI TLS extension.
|
||||
TLS []IngressTLS `json:"tls,omitempty"`
|
||||
|
||||
// A list of host rules used to configure the Ingress. If unspecified, or
|
||||
// no rule matches, all traffic is sent to the default backend.
|
||||
Rules []IngressRule `json:"rules,omitempty"`
|
||||
// TODO: Add the ability to specify load-balancer IP through claims
|
||||
}
|
||||
|
||||
// IngressTLS describes the transport layer security associated with an Ingress.
|
||||
type IngressTLS struct {
|
||||
// Hosts are a list of hosts included in the TLS certificate. The values in
|
||||
// this list must match the name/s used in the tlsSecret. Defaults to the
|
||||
// wildcard host setting for the loadbalancer controller fulfilling this
|
||||
// Ingress, if left unspecified.
|
||||
Hosts []string `json:"hosts,omitempty"`
|
||||
// SecretName is the name of the secret used to terminate SSL traffic on 443.
|
||||
// Field is left optional to allow SSL routing based on SNI hostname alone.
|
||||
// If the SNI host in a listener conflicts with the "Host" header field used
|
||||
// by an IngressRule, the SNI host is used for termination and value of the
|
||||
// Host header is used for routing.
|
||||
SecretName string `json:"secretName,omitempty"`
|
||||
// TODO: Consider specifying different modes of termination, protocols etc.
|
||||
}
|
||||
|
||||
// IngressStatus describe the current state of the Ingress.
|
||||
type IngressStatus struct {
|
||||
// LoadBalancer contains the current status of the load-balancer.
|
||||
|
@ -3167,6 +3167,16 @@ func autoConvert_extensions_IngressSpec_To_v1beta1_IngressSpec(in *extensions.In
|
||||
} else {
|
||||
out.Backend = nil
|
||||
}
|
||||
if in.TLS != nil {
|
||||
out.TLS = make([]IngressTLS, len(in.TLS))
|
||||
for i := range in.TLS {
|
||||
if err := Convert_extensions_IngressTLS_To_v1beta1_IngressTLS(&in.TLS[i], &out.TLS[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.TLS = nil
|
||||
}
|
||||
if in.Rules != nil {
|
||||
out.Rules = make([]IngressRule, len(in.Rules))
|
||||
for i := range in.Rules {
|
||||
@ -3198,6 +3208,26 @@ func Convert_extensions_IngressStatus_To_v1beta1_IngressStatus(in *extensions.In
|
||||
return autoConvert_extensions_IngressStatus_To_v1beta1_IngressStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_IngressTLS_To_v1beta1_IngressTLS(in *extensions.IngressTLS, out *IngressTLS, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.IngressTLS))(in)
|
||||
}
|
||||
if in.Hosts != nil {
|
||||
out.Hosts = make([]string, len(in.Hosts))
|
||||
for i := range in.Hosts {
|
||||
out.Hosts[i] = in.Hosts[i]
|
||||
}
|
||||
} else {
|
||||
out.Hosts = nil
|
||||
}
|
||||
out.SecretName = in.SecretName
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_IngressTLS_To_v1beta1_IngressTLS(in *extensions.IngressTLS, out *IngressTLS, s conversion.Scope) error {
|
||||
return autoConvert_extensions_IngressTLS_To_v1beta1_IngressTLS(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_Job_To_v1beta1_Job(in *extensions.Job, out *Job, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.Job))(in)
|
||||
@ -4438,6 +4468,16 @@ func autoConvert_v1beta1_IngressSpec_To_extensions_IngressSpec(in *IngressSpec,
|
||||
} else {
|
||||
out.Backend = nil
|
||||
}
|
||||
if in.TLS != nil {
|
||||
out.TLS = make([]extensions.IngressTLS, len(in.TLS))
|
||||
for i := range in.TLS {
|
||||
if err := Convert_v1beta1_IngressTLS_To_extensions_IngressTLS(&in.TLS[i], &out.TLS[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.TLS = nil
|
||||
}
|
||||
if in.Rules != nil {
|
||||
out.Rules = make([]extensions.IngressRule, len(in.Rules))
|
||||
for i := range in.Rules {
|
||||
@ -4469,6 +4509,26 @@ func Convert_v1beta1_IngressStatus_To_extensions_IngressStatus(in *IngressStatus
|
||||
return autoConvert_v1beta1_IngressStatus_To_extensions_IngressStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_IngressTLS_To_extensions_IngressTLS(in *IngressTLS, out *extensions.IngressTLS, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*IngressTLS))(in)
|
||||
}
|
||||
if in.Hosts != nil {
|
||||
out.Hosts = make([]string, len(in.Hosts))
|
||||
for i := range in.Hosts {
|
||||
out.Hosts[i] = in.Hosts[i]
|
||||
}
|
||||
} else {
|
||||
out.Hosts = nil
|
||||
}
|
||||
out.SecretName = in.SecretName
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_IngressTLS_To_extensions_IngressTLS(in *IngressTLS, out *extensions.IngressTLS, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_IngressTLS_To_extensions_IngressTLS(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_Job_To_extensions_Job(in *Job, out *extensions.Job, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*Job))(in)
|
||||
@ -5234,6 +5294,7 @@ func init() {
|
||||
autoConvert_extensions_IngressRule_To_v1beta1_IngressRule,
|
||||
autoConvert_extensions_IngressSpec_To_v1beta1_IngressSpec,
|
||||
autoConvert_extensions_IngressStatus_To_v1beta1_IngressStatus,
|
||||
autoConvert_extensions_IngressTLS_To_v1beta1_IngressTLS,
|
||||
autoConvert_extensions_Ingress_To_v1beta1_Ingress,
|
||||
autoConvert_extensions_JobCondition_To_v1beta1_JobCondition,
|
||||
autoConvert_extensions_JobList_To_v1beta1_JobList,
|
||||
@ -5338,6 +5399,7 @@ func init() {
|
||||
autoConvert_v1beta1_IngressRule_To_extensions_IngressRule,
|
||||
autoConvert_v1beta1_IngressSpec_To_extensions_IngressSpec,
|
||||
autoConvert_v1beta1_IngressStatus_To_extensions_IngressStatus,
|
||||
autoConvert_v1beta1_IngressTLS_To_extensions_IngressTLS,
|
||||
autoConvert_v1beta1_Ingress_To_extensions_Ingress,
|
||||
autoConvert_v1beta1_JobCondition_To_extensions_JobCondition,
|
||||
autoConvert_v1beta1_JobList_To_extensions_JobList,
|
||||
|
@ -1420,6 +1420,16 @@ func deepCopy_v1beta1_IngressSpec(in IngressSpec, out *IngressSpec, c *conversio
|
||||
} else {
|
||||
out.Backend = nil
|
||||
}
|
||||
if in.TLS != nil {
|
||||
out.TLS = make([]IngressTLS, len(in.TLS))
|
||||
for i := range in.TLS {
|
||||
if err := deepCopy_v1beta1_IngressTLS(in.TLS[i], &out.TLS[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.TLS = nil
|
||||
}
|
||||
if in.Rules != nil {
|
||||
out.Rules = make([]IngressRule, len(in.Rules))
|
||||
for i := range in.Rules {
|
||||
@ -1440,6 +1450,19 @@ func deepCopy_v1beta1_IngressStatus(in IngressStatus, out *IngressStatus, c *con
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_IngressTLS(in IngressTLS, out *IngressTLS, c *conversion.Cloner) error {
|
||||
if in.Hosts != nil {
|
||||
out.Hosts = make([]string, len(in.Hosts))
|
||||
for i := range in.Hosts {
|
||||
out.Hosts[i] = in.Hosts[i]
|
||||
}
|
||||
} else {
|
||||
out.Hosts = nil
|
||||
}
|
||||
out.SecretName = in.SecretName
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_Job(in Job, out *Job, c *conversion.Cloner) error {
|
||||
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
@ -2040,6 +2063,7 @@ func init() {
|
||||
deepCopy_v1beta1_IngressRuleValue,
|
||||
deepCopy_v1beta1_IngressSpec,
|
||||
deepCopy_v1beta1_IngressStatus,
|
||||
deepCopy_v1beta1_IngressTLS,
|
||||
deepCopy_v1beta1_Job,
|
||||
deepCopy_v1beta1_JobCondition,
|
||||
deepCopy_v1beta1_JobList,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -639,12 +639,35 @@ type IngressSpec struct {
|
||||
// is optional to allow the loadbalancer controller or defaulting logic to
|
||||
// specify a global default.
|
||||
Backend *IngressBackend `json:"backend,omitempty"`
|
||||
|
||||
// TLS configuration. Currently the Ingress only supports a single TLS
|
||||
// port, 443, and assumes TLS termination. If multiple members of this
|
||||
// list specify different hosts, they will be multiplexed on the same
|
||||
// port according to the hostname specified through the SNI TLS extension.
|
||||
TLS []IngressTLS `json:"tls,omitempty"`
|
||||
|
||||
// A list of host rules used to configure the Ingress. If unspecified, or
|
||||
// no rule matches, all traffic is sent to the default backend.
|
||||
Rules []IngressRule `json:"rules,omitempty"`
|
||||
// TODO: Add the ability to specify load-balancer IP through claims
|
||||
}
|
||||
|
||||
// IngressTLS describes the transport layer security associated with an Ingress.
|
||||
type IngressTLS struct {
|
||||
// Hosts are a list of hosts included in the TLS certificate. The values in
|
||||
// this list must match the name/s used in the tlsSecret. Defaults to the
|
||||
// wildcard host setting for the loadbalancer controller fulfilling this
|
||||
// Ingress, if left unspecified.
|
||||
Hosts []string `json:"hosts,omitempty"`
|
||||
// SecretName is the name of the secret used to terminate SSL traffic on 443.
|
||||
// Field is left optional to allow SSL routing based on SNI hostname alone.
|
||||
// If the SNI host in a listener conflicts with the "Host" header field used
|
||||
// by an IngressRule, the SNI host is used for termination and value of the
|
||||
// Host header is used for routing.
|
||||
SecretName string `json:"secretName,omitempty"`
|
||||
// TODO: Consider specifying different modes of termination, protocols etc.
|
||||
}
|
||||
|
||||
// IngressStatus describe the current state of the Ingress.
|
||||
type IngressStatus struct {
|
||||
// LoadBalancer contains the current status of the load-balancer.
|
||||
|
@ -363,6 +363,7 @@ func (IngressRuleValue) SwaggerDoc() map[string]string {
|
||||
var map_IngressSpec = map[string]string{
|
||||
"": "IngressSpec describes the Ingress the user wishes to exist.",
|
||||
"backend": "A default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default.",
|
||||
"tls": "TLS configuration. Currently the Ingress only supports a single TLS port, 443, and assumes TLS termination. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension.",
|
||||
"rules": "A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.",
|
||||
}
|
||||
|
||||
@ -379,6 +380,16 @@ func (IngressStatus) SwaggerDoc() map[string]string {
|
||||
return map_IngressStatus
|
||||
}
|
||||
|
||||
var map_IngressTLS = map[string]string{
|
||||
"": "IngressTLS describes the transport layer security associated with an Ingress.",
|
||||
"hosts": "Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.",
|
||||
"secretName": "SecretName is the name of the secret used to terminate SSL traffic on 443. Field is left optional to allow SSL routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.",
|
||||
}
|
||||
|
||||
func (IngressTLS) SwaggerDoc() map[string]string {
|
||||
return map_IngressTLS
|
||||
}
|
||||
|
||||
var map_Job = map[string]string{
|
||||
"": "Job represents the configuration of a single job.",
|
||||
"metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata",
|
||||
|
@ -459,6 +459,20 @@ func ValidateIngressName(name string, prefix bool) (bool, string) {
|
||||
return apivalidation.NameIsDNSSubdomain(name, prefix)
|
||||
}
|
||||
|
||||
func validateIngressTLS(spec *extensions.IngressSpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
// Currently the Ingress only supports HTTP(S), so a secretName is required.
|
||||
// This will not be the case if we support SSL routing at L4 via SNI.
|
||||
for i, t := range spec.TLS {
|
||||
if t.SecretName == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Index(i).Child("secretName"), spec.TLS[i].SecretName))
|
||||
}
|
||||
}
|
||||
// TODO: Perform a more thorough validation of spec.TLS.Hosts that takes
|
||||
// the wildcard spec from RFC 6125 into account.
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateIngressSpec tests if required fields in the IngressSpec are set.
|
||||
func ValidateIngressSpec(spec *extensions.IngressSpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
@ -471,6 +485,9 @@ func ValidateIngressSpec(spec *extensions.IngressSpec, fldPath *field.Path) fiel
|
||||
if len(spec.Rules) > 0 {
|
||||
allErrs = append(allErrs, validateIngressRules(spec.Rules, fldPath.Child("rules"))...)
|
||||
}
|
||||
if len(spec.TLS) > 0 {
|
||||
allErrs = append(allErrs, validateIngressTLS(spec, fldPath.Child("tls"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
|
@ -1211,6 +1211,8 @@ func TestValidateIngress(t *testing.T) {
|
||||
badHostIP := newValid()
|
||||
badHostIP.Spec.Rules[0].Host = hostIP
|
||||
badHostIPErr := fmt.Sprintf("spec.rules[0].host: Invalid value: '%v'", hostIP)
|
||||
noSecretName := newValid()
|
||||
noSecretName.Spec.TLS = []extensions.IngressTLS{{SecretName: ""}}
|
||||
|
||||
errorCases := map[string]extensions.Ingress{
|
||||
"spec.backend.serviceName: Required value": servicelessBackend,
|
||||
@ -1219,6 +1221,7 @@ func TestValidateIngress(t *testing.T) {
|
||||
"spec.rules[0].host: Invalid value": badHost,
|
||||
"spec.rules[0].http.paths: Required value": noPaths,
|
||||
"spec.rules[0].http.paths[0].path: Invalid value": noForwardSlashPath,
|
||||
"spec.tls[0].secretName: Required value": noSecretName,
|
||||
}
|
||||
errorCases[badPathErr] = badRegexPath
|
||||
errorCases[badHostIPErr] = badHostIP
|
||||
|
@ -1084,6 +1084,9 @@ func (i *IngressDescriber) describeIngress(ing *extensions.Ingress) (string, err
|
||||
ns = api.NamespaceSystem
|
||||
}
|
||||
fmt.Fprintf(out, "Default backend:\t%s (%s)\n", backendStringer(def), i.describeBackend(ns, def))
|
||||
if len(ing.Spec.TLS) != 0 {
|
||||
describeIngressTLS(out, ing.Spec.TLS)
|
||||
}
|
||||
fmt.Fprint(out, "Rules:\n Host\tPath\tBackends\n")
|
||||
fmt.Fprint(out, " ----\t----\t--------\n")
|
||||
for _, rules := range ing.Spec.Rules {
|
||||
@ -1105,6 +1108,14 @@ func (i *IngressDescriber) describeIngress(ing *extensions.Ingress) (string, err
|
||||
})
|
||||
}
|
||||
|
||||
func describeIngressTLS(out io.Writer, ingTLS []extensions.IngressTLS) {
|
||||
fmt.Fprintf(out, "TLS:\n")
|
||||
for _, t := range ingTLS {
|
||||
fmt.Fprintf(out, " %v terminates %v\n", t.SecretName, strings.Join(t.Hosts, ","))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: Move from annotations into Ingress status.
|
||||
func describeIngressAnnotations(out io.Writer, annotations map[string]string) {
|
||||
fmt.Fprintf(out, "Annotations:\n")
|
||||
|
@ -45,6 +45,9 @@ var (
|
||||
defaultLoadBalancer = "127.0.0.1"
|
||||
defaultPath = "/foo"
|
||||
defaultPathMap = map[string]string{defaultPath: defaultBackendName}
|
||||
defaultTLS = []extensions.IngressTLS{
|
||||
{Hosts: []string{"foo.bar.com", "*.bar.com"}, SecretName: "fooSecret"},
|
||||
}
|
||||
)
|
||||
|
||||
type IngressRuleValues map[string]string
|
||||
@ -92,6 +95,7 @@ func newIngress(pathMap map[string]string) *extensions.Ingress {
|
||||
Rules: toIngressRules(map[string]IngressRuleValues{
|
||||
defaultHostname: pathMap,
|
||||
}),
|
||||
TLS: defaultTLS,
|
||||
},
|
||||
Status: extensions.IngressStatus{
|
||||
LoadBalancer: api.LoadBalancerStatus{
|
||||
@ -139,6 +143,10 @@ func TestUpdate(t *testing.T) {
|
||||
object.Spec.Rules = toIngressRules(map[string]IngressRuleValues{
|
||||
"bar.foo.com": {"/bar": defaultBackendName},
|
||||
})
|
||||
object.Spec.TLS = append(object.Spec.TLS, extensions.IngressTLS{
|
||||
Hosts: []string{"*.google.com"},
|
||||
SecretName: "googleSecret",
|
||||
})
|
||||
return object
|
||||
},
|
||||
// invalid updateFunc: ObjeceMeta is not to be tampered with.
|
||||
@ -160,6 +168,15 @@ func TestUpdate(t *testing.T) {
|
||||
"foo.bar.com": {"/invalid[": "svc"}})
|
||||
return object
|
||||
},
|
||||
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*extensions.Ingress)
|
||||
object.Spec.TLS = append(object.Spec.TLS, extensions.IngressTLS{
|
||||
Hosts: []string{"foo.bar.com"},
|
||||
SecretName: "",
|
||||
})
|
||||
return object
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user