Skip to content

Commit

Permalink
Add support for blocking HTTP connections
Browse files Browse the repository at this point in the history
Signed-off-by: Gunish Matta <[email protected]>
  • Loading branch information
gunishmatta committed Nov 14, 2022
1 parent 921ebc0 commit f81a866
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 3 deletions.
70 changes: 69 additions & 1 deletion controllers/event_handling_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"

Expand Down Expand Up @@ -52,7 +53,69 @@ func TestEventHandler(t *testing.T) {
t.Fatalf("failed to create memory storage")
}

eventServer := server.NewEventServer("127.0.0.1:56789", logf.Log, k8sClient, true)
httpScheme := "http"

eventServerTests := []struct {
name string
isHttpEnabled bool
url string
}{
{
name: "http scheme is enabled",
isHttpEnabled: true,
}, {
name: "http scheme is disabled",
isHttpEnabled: false,
},
}
for _, eventServerTest := range eventServerTests {
t.Run(eventServerTest.name, func(t *testing.T) {

eventServer := server.NewEventServer("127.0.0.1:56789", logf.Log, k8sClient, true, eventServerTest.isHttpEnabled)

stopCh := make(chan struct{})
go eventServer.ListenAndServe(stopCh, eventMdlw, store)
requestsReceived := 0
rcvServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requestsReceived = requestsReceived + 1
req = r
w.WriteHeader(200)
}))
defer rcvServer.Close()
defer close(stopCh)

providerKey := types.NamespacedName{
Name: fmt.Sprintf("provider-%s", randStringRunes(5)),
Namespace: namespace,
}
provider = &notifyv1.Provider{
ObjectMeta: metav1.ObjectMeta{
Name: providerKey.Name,
Namespace: providerKey.Namespace,
},
Spec: notifyv1.ProviderSpec{
Type: "generic",
Address: rcvServer.URL,
},
}

webhook_url, err := url.Parse(provider.Spec.Address)

g.Expect(err).ToNot(HaveOccurred())

if eventServerTest.isHttpEnabled {
g.Expect(webhook_url.Scheme).To(Equal(httpScheme))
g.Expect(requestsReceived).To(Equal(1))
} else {
g.Expect(webhook_url.Scheme).ToNot(Equal(httpScheme))
g.Expect(requestsReceived).To(Equal(0))
}

})
}

eventServer := server.NewEventServer("127.0.0.1:56789", logf.Log, k8sClient, true, true)

stopCh := make(chan struct{})
go eventServer.ListenAndServe(stopCh, eventMdlw, store)

Expand All @@ -77,6 +140,9 @@ func TestEventHandler(t *testing.T) {
Address: rcvServer.URL,
},
}

g.Expect(err).ToNot(HaveOccurred())

g.Expect(k8sClient.Create(context.Background(), provider)).To(Succeed())
g.Eventually(func() bool {
var obj notifyv1.Provider
Expand Down Expand Up @@ -173,6 +239,7 @@ func TestEventHandler(t *testing.T) {
res, err := http.Post("http://localhost:56789/", "application/json", buf)
g.Expect(err).ToNot(HaveOccurred())
g.Expect(res.StatusCode).To(Equal(202)) // event_server responds with 202 Accepted

}

testForwarded := func() {
Expand Down Expand Up @@ -294,4 +361,5 @@ func TestEventHandler(t *testing.T) {
req = nil
})
}

}
17 changes: 17 additions & 0 deletions internal/server/event_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"regexp"
"strings"
"time"
Expand Down Expand Up @@ -243,6 +244,22 @@ func (s *EventServer) handleEvent() func(w http.ResponseWriter, r *http.Request)
continue
}

webhookUrl, err := url.Parse(webhook)
if err != nil {
s.logger.Error(nil, "Error parsing webhook url",
"reconciler kind", v1beta1.ProviderKind,
"name", providerName.Name,
"namespace", providerName.Namespace)
continue
}

if !s.supportHttpScheme && webhookUrl.Scheme == "http" {
s.logger.Error(nil, "http scheme is blocked",
"reconciler kind", v1beta1.ProviderKind,
"name", providerName.Name,
"namespace", providerName.Namespace)
continue
}
factory := notifier.NewFactory(webhook, proxy, username, provider.Spec.Channel, token, headers, certPool, password)
sender, err := factory.Notifier(provider.Spec.Type)
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion internal/server/event_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,17 @@ type EventServer struct {
logger logr.Logger
kubeClient client.Client
noCrossNamespaceRefs bool
supportHttpScheme bool
}

// NewEventServer returns an HTTP server that handles events
func NewEventServer(port string, logger logr.Logger, kubeClient client.Client, noCrossNamespaceRefs bool) *EventServer {
func NewEventServer(port string, logger logr.Logger, kubeClient client.Client, noCrossNamespaceRefs bool, supportHttpScheme bool) *EventServer {
return &EventServer{
port: port,
logger: logger.WithName("event-server"),
kubeClient: kubeClient,
noCrossNamespaceRefs: noCrossNamespaceRefs,
supportHttpScheme: supportHttpScheme,
}
}

Expand Down
4 changes: 3 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func main() {
leaderElectionOptions leaderelection.Options
aclOptions acl.Options
rateLimiterOptions helper.RateLimiterOptions
insecureAllowHTTP bool
)

flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
Expand All @@ -82,6 +83,7 @@ func main() {
flag.BoolVar(&watchAllNamespaces, "watch-all-namespaces", true,
"Watch for custom resources in all namespaces, if set to false it will only watch the runtime namespace.")
flag.DurationVar(&rateLimitInterval, "rate-limit-interval", 5*time.Minute, "Interval in which rate limit has effect.")
flag.BoolVar(&insecureAllowHTTP, "insecure-allow-http", true, "Enable the use of HTTP Scheme (no HTTPS) across all controller level objects. This is not recommended for production environments")
clientOptions.BindFlags(flag.CommandLine)
logOptions.BindFlags(flag.CommandLine)
leaderElectionOptions.BindFlags(flag.CommandLine)
Expand Down Expand Up @@ -169,7 +171,7 @@ func main() {
Registry: crtlmetrics.Registry,
}),
})
eventServer := server.NewEventServer(eventsAddr, log, mgr.GetClient(), aclOptions.NoCrossNamespaceRefs)
eventServer := server.NewEventServer(eventsAddr, log, mgr.GetClient(), aclOptions.NoCrossNamespaceRefs, insecureAllowHTTP)
go eventServer.ListenAndServe(ctx.Done(), eventMdlw, store)

setupLog.Info("starting webhook receiver server", "addr", receiverAddr)
Expand Down

0 comments on commit f81a866

Please sign in to comment.