Commit 3cc3089a authored by André Carvalho's avatar André Carvalho

enable serving single tls certificate/key pair

parent 136e35c9
......@@ -24,6 +24,8 @@ type NginxSpec struct {
Image string `json:"image"`
// Reference to the nginx config object.
Config *ConfigRef `json:"configRef"`
// References to a secret containing tls certificate and key pairs.
TLSSecret *TLSSecret `json:"tlsSecret"`
}
type NginxStatus struct {
......@@ -67,6 +69,26 @@ const (
ConfigKindInline = ConfigKind("Inline")
)
// TLSSecret is a reference to tls certificate and key pairs stored in a secret.
type TLSSecret struct {
// Name of the Secret holding the certificate and key.
SecretName string
// Secret field that contains the key.
// Defaults to tls.key
KeyField string
// Secret field that contains the certificate.
// Defaults to tls.crt
CertificateField string
// Path where the key should be stored inside the nginx container.
// Relative to /etc/nginx/certs/.
// Defaults to <KeyName>
KeyPath string
// Path where the certificate should be stored inside the nginx container.
// Relative to /etc/nginx/certs/.
// Defaults to <CertificateName>
CertificatePath string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type NginxList struct {
......
......@@ -66,12 +66,13 @@ func NewDeployment(n *v1alpha1.Nginx) *appv1.Deployment {
},
}
setupConfig(n.Spec.Config, &deployment)
setupTLS(n.Spec.TLSSecret, &deployment)
return &deployment
}
// NewService assembles the ClusterIP service for the Nginx
func NewService(n *v1alpha1.Nginx) *corev1.Service {
return &corev1.Service{
service := corev1.Service{
TypeMeta: metav1.TypeMeta{
Kind: "Service",
APIVersion: "v1",
......@@ -101,6 +102,15 @@ func NewService(n *v1alpha1.Nginx) *corev1.Service {
Type: corev1.ServiceTypeClusterIP,
},
}
if n.Spec.TLSSecret != nil {
service.Spec.Ports = append(service.Spec.Ports, corev1.ServicePort{
Name: "https",
Protocol: corev1.ProtocolTCP,
TargetPort: intstr.FromString("https"),
Port: int32(443),
})
}
return &service
}
// LabelsForNginx returns the labels for a Nginx CR with the given name
......@@ -115,47 +125,81 @@ func setupConfig(conf *v1alpha1.ConfigRef, dep *appv1.Deployment) {
if conf == nil {
return
}
dep.Spec.Template.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{
{
Name: "nginx-config",
MountPath: "/etc/nginx",
},
}
dep.Spec.Template.Spec.Containers[0].VolumeMounts = append(dep.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
Name: "nginx-config",
MountPath: "/etc/nginx",
})
switch conf.Kind {
case v1alpha1.ConfigKindConfigMap:
dep.Spec.Template.Spec.Volumes = []corev1.Volume{
{
Name: "nginx-config",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: conf.Name,
},
dep.Spec.Template.Spec.Volumes = append(dep.Spec.Template.Spec.Volumes, corev1.Volume{
Name: "nginx-config",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: conf.Name,
},
},
},
}
})
case v1alpha1.ConfigKindInline:
if dep.Spec.Template.Annotations == nil {
dep.Spec.Template.Annotations = make(map[string]string)
}
dep.Spec.Template.Annotations[conf.Name] = conf.Value
dep.Spec.Template.Spec.Volumes = []corev1.Volume{
{
Name: "nginx-config",
VolumeSource: corev1.VolumeSource{
DownwardAPI: &corev1.DownwardAPIVolumeSource{
Items: []corev1.DownwardAPIVolumeFile{
{
Path: "nginx.conf",
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: fmt.Sprintf("metadata.annotations['%s']", conf.Name),
},
dep.Spec.Template.Spec.Volumes = append(dep.Spec.Template.Spec.Volumes, corev1.Volume{
Name: "nginx-config",
VolumeSource: corev1.VolumeSource{
DownwardAPI: &corev1.DownwardAPIVolumeSource{
Items: []corev1.DownwardAPIVolumeFile{
{
Path: "nginx.conf",
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: fmt.Sprintf("metadata.annotations['%s']", conf.Name),
},
},
},
},
},
}
})
}
}
// setupTLS appends an https port if TLS secrets are specified
func setupTLS(secret *v1alpha1.TLSSecret, dep *appv1.Deployment) {
if secret == nil {
return
}
dep.Spec.Template.Spec.Containers[0].Ports = append(dep.Spec.Template.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "https",
ContainerPort: int32(443),
Protocol: corev1.ProtocolTCP,
})
dep.Spec.Template.Spec.Containers[0].VolumeMounts = append(dep.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
Name: "nginx-certs",
MountPath: "/etc/nginx/certs",
})
if secret.KeyField == "" {
secret.KeyField = "tls.key"
}
if secret.CertificateField == "" {
secret.CertificateField = "tls.crt"
}
if secret.KeyPath == "" {
secret.KeyPath = secret.KeyField
}
if secret.CertificatePath == "" {
secret.CertificatePath = secret.CertificateField
}
dep.Spec.Template.Spec.Volumes = append(dep.Spec.Template.Spec.Volumes, corev1.Volume{
Name: "nginx-certs",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: secret.SecretName,
Items: []corev1.KeyToPath{
{Key: secret.KeyField, Path: secret.KeyPath},
{Key: secret.CertificateField, Path: secret.CertificatePath},
},
},
},
})
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment