Skip to content

Commit

Permalink
Added ingress support
Browse files Browse the repository at this point in the history
  • Loading branch information
abhishekdwivedi3060 committed Oct 19, 2021
1 parent 0ab15e1 commit b8bd5c0
Show file tree
Hide file tree
Showing 27 changed files with 921 additions and 10 deletions.
2 changes: 2 additions & 0 deletions apis/v1alpha1/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ go_library(
"@com_github_cockroachdb_errors//:go_default_library",
"@io_k8s_api//apps/v1:go_default_library",
"@io_k8s_api//core/v1:go_default_library",
"@io_k8s_api//networking/v1beta1:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_apimachinery//pkg/runtime:go_default_library",
"@io_k8s_apimachinery//pkg/runtime/schema:go_default_library",
"@io_k8s_apimachinery//pkg/util/errors:go_default_library",
"@io_k8s_sigs_controller_runtime//:go_default_library",
"@io_k8s_sigs_controller_runtime//pkg/log:go_default_library",
"@io_k8s_sigs_controller_runtime//pkg/scheme:go_default_library",
Expand Down
2 changes: 2 additions & 0 deletions apis/v1alpha1/action_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,6 @@ const (
PartitionedUpdateAction ActionType = "PartitionedUpdate"
//UnknownAction string
UnknownAction ActionType = "Unknown"
// ExposeIngressAction string
ExposeIngressAction ActionType = "ExposeIngressAction"
)
44 changes: 44 additions & 0 deletions apis/v1alpha1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package v1alpha1

import (
corev1 "k8s.io/api/core/v1"
v1beta1 "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -122,6 +123,10 @@ type CrdbClusterSpec struct {
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Map of nodeSelectors to match when scheduling pods on nodes"
// +optional
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
// (Optional) Ingress defines the Ingress configuration used to expose the services using Ingress
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Cockroach Database Ingress"
// +optional
Ingress *IngressConfig `json:"ingress,omitempty"`
}

// +k8s:openapi-gen=true
Expand Down Expand Up @@ -240,6 +245,45 @@ type Volume struct {
SupportsAutoResize bool `json:"supportsAutoResize"`
}

// +k8s:openapi-gen=true
// +kubebuilder:object:generate=true
// +k8s:deepcopy-gen=true

// IngressConfig defines the configuration required to create ingress resource
type IngressConfig struct {
// (Optional) IngressClassName to be used by ingress resource
// +optional
IngressClassName string `json:"ingressClassName,omitempty"`
// (Optional) Annotations related to ingress resource
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
// (Optional) Annotations resource related annotations
// +optional
TLS []v1beta1.IngressTLS `json:"tls,omitempty"`
// (Optional) HTTP port (UI) to be exposed via ingress
// +optional
HTTP *IngressService `json:"http,omitempty"`
// (Optional) GRPC port to be exposed via ingress
// +optional
GRPC *IngressService `json:"grpc,omitempty"`
// (Optional) SQL port to be exposed via ingress
// +optional
SQL *IngressService `json:"sql,omitempty"`
}

// +kubebuilder:object:generate=true
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=true

// IngressService defines the service to be exposed via ingress
type IngressService struct {
// +required
Enabled bool `json:"enabled"`
// host is host to be used for exposing service
// +required
Host string `json:"host"`
}

// +kubebuilder:object:generate=true
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=true
Expand Down
2 changes: 2 additions & 0 deletions apis/v1alpha1/condition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const (
DecommissionCondition ClusterConditionType = "Decommission"
//CrdbInitializedCondition string
CrdbInitializedCondition ClusterConditionType = "Initialized"
// CrdbIngressExposedCondition string
CrdbIngressExposedCondition ClusterConditionType = "IngressExposed"
//ClusterRestartCondition string
ClusterRestartCondition ClusterConditionType = "RestartedCluster"
)
49 changes: 49 additions & 0 deletions apis/v1alpha1/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ limitations under the License.
package v1alpha1

import (
"fmt"

v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
kerrors "k8s.io/apimachinery/pkg/util/errors"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
Expand Down Expand Up @@ -82,13 +85,34 @@ func (r *CrdbCluster) Default() {
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
func (r *CrdbCluster) ValidateCreate() error {
webhookLog.Info("validate create", "name", r.Name)
var errors []error
if r.Spec.Ingress != nil {
if err := r.ValidateIngress(); err != nil {
errors = append(errors, err...)
}
}

if len(errors) != 0 {
return kerrors.NewAggregate(errors)
}

return nil
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
func (r *CrdbCluster) ValidateUpdate(old runtime.Object) error {
webhookLog.Info("validate update", "name", r.Name)
var errors []error

if r.Spec.Ingress != nil {
if err := r.ValidateIngress(); err != nil {
errors = append(errors, err...)
}
}

if len(errors) != 0 {
return kerrors.NewAggregate(errors)
}

return nil
}
Expand All @@ -100,3 +124,28 @@ func (r *CrdbCluster) ValidateDelete() error {
// we're not validating anything on delete. This is just a placeholder for now to satisfy the Validator interface
return nil
}

// ValidateIngress validates the ingress configuration used to create ingress resource
func (r *CrdbCluster) ValidateIngress() []error {
webhookLog.Info("validate ingress", "name", r.Name)

if r.Spec.Ingress.HTTP == nil && r.Spec.Ingress.SQL == nil && r.Spec.Ingress.GRPC == nil {
return []error{fmt.Errorf("atleast one of http, grpc and sql should be enabled when ingress is set")}
}

var errors []error

if r.Spec.Ingress.HTTP != nil && r.Spec.Ingress.HTTP.Enabled && r.Spec.Ingress.HTTP.Host == "" {
errors = append(errors, fmt.Errorf("host required for http"))
}

if r.Spec.Ingress.GRPC != nil && r.Spec.Ingress.GRPC.Enabled && r.Spec.Ingress.GRPC.Host == "" {
errors = append(errors, fmt.Errorf("host required for grpc"))
}

if r.Spec.Ingress.SQL != nil && r.Spec.Ingress.SQL.Enabled && r.Spec.Ingress.SQL.Host == "" {
errors = append(errors, fmt.Errorf("host required for sql"))
}

return errors
}
55 changes: 55 additions & 0 deletions apis/v1alpha1/webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1_test

import (
"fmt"
"testing"

. "github.com/cockroachdb/cockroach-operator/apis/v1alpha1"
Expand All @@ -40,3 +41,57 @@ func TestCrdbClusterDefault(t *testing.T) {
cluster.Default()
require.Equal(t, expected, cluster.Spec)
}

func TestValidateIngress(t *testing.T) {

tests := []struct {
name string
cluster *CrdbCluster
expected []error
}{
{
name: "ingress config with http host missing",
cluster: &CrdbCluster{
Spec: CrdbClusterSpec{
Ingress: &IngressConfig{HTTP: &IngressService{Enabled: true}},
},
},
expected: []error{fmt.Errorf("host required for http")},
},
{
name: "ingress config with grpc host missing",
cluster: &CrdbCluster{
Spec: CrdbClusterSpec{
Ingress: &IngressConfig{GRPC: &IngressService{Enabled: true}},
},
},
expected: []error{fmt.Errorf("host required for grpc")},
},
{
name: "ingress config with http host missing",
cluster: &CrdbCluster{
Spec: CrdbClusterSpec{
Ingress: &IngressConfig{SQL: &IngressService{Enabled: true}},
},
},
expected: []error{fmt.Errorf("host required for sql")},
},
{
name: "ingress config with nil http, grpc and sql",
cluster: &CrdbCluster{
Spec: CrdbClusterSpec{
Ingress: &IngressConfig{},
},
},
expected: []error{fmt.Errorf("atleast one of http, grpc and sql should be enabled when ingress is set")},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

require.Equal(t, tt.expected, tt.cluster.ValidateIngress())
})

}
}
67 changes: 67 additions & 0 deletions apis/v1alpha1/zz_generated.deepcopy.go

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

Loading

0 comments on commit b8bd5c0

Please sign in to comment.