Skip to content

Commit

Permalink
Update code documentation (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
ciroque authored Apr 11, 2023
1 parent 063e073 commit 28879f6
Show file tree
Hide file tree
Showing 22 changed files with 354 additions and 46 deletions.
19 changes: 18 additions & 1 deletion internal/application/application_constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,24 @@

package application

// These constants are intended for use in the Annotations field of the Service definition.
// They determine which Border Server client will be used.
// To use these values, add the following annotation to the Service definition:
//
// annotations:
// nginxinc.io/nkl-<upstream name>: <value>
//
// where <upstream name> is the name of the upstream in the NGINX Plus configuration and <value> is one of the constants below.
//
// Note, this is an extensibility point. To add a Border Server client...
// 1. Create a module that implements the BorderClient interface;
// 2. Add a new constant to this group that acts as a key for selecting the client;
// 3. Update the NewBorderClient factory method in border_client.go that returns the client;
const (
ClientTypeTcp = "tcp"

// ClientTypeTcp creates a TcpBorderClient that uses the Stream* methods of the NGINX Plus client.
ClientTypeTcp = "tcp"

// ClientTypeHttp creates an HttpBorderClient that uses the HTTP* methods of the NGINX Plus client.
ClientTypeHttp = "http"
)
13 changes: 10 additions & 3 deletions internal/application/border_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,30 @@ import (
"github.com/sirupsen/logrus"
)

// Interface defines the functions required to implement a Border Client.
type Interface interface {
Update(*core.ServerUpdateEvent) error
Delete(*core.ServerUpdateEvent) error
}

// BorderClient defines any state need by the Border Client.
type BorderClient struct {
}

// NewBorderClient Returns a NullBorderClient if the type is unknown, this avoids panics due to nil pointer dereferences.
// NewBorderClient is the Factory function for creating a Border Client.
//
// Note, this is an extensibility point. To add a Border Server client...
// 1. Create a module that implements the BorderClient interface;
// 2. Add a new constant in application_constants.go that acts as a key for selecting the client;
// 3. Update the NewBorderClient factory method in border_client.go that returns the client;
func NewBorderClient(clientType string, borderClient interface{}) (Interface, error) {
logrus.Debugf(`NewBorderClient for type: %s`, clientType)

switch clientType {
case "tcp":
case ClientTypeTcp:
return NewTcpBorderClient(borderClient)

case "http":
case ClientTypeHttp:
return NewHttpBorderClient(borderClient)

default:
Expand Down
22 changes: 18 additions & 4 deletions internal/application/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,28 @@
/*
Package application includes support for applying updates to the Border servers.
"Border TcpServers" are the servers that are exposed to the outside world and direct traffic into the cluster.
At this time the only supported Border TcpServers are NGINX Plus servers. The BorderClient module defines
an interface that can be implemented to support other Border Server types.
"Border Servers" are servers that are exposed to the outside world and direct traffic into the cluster.
The BorderClient module defines an interface that can be implemented to support other Border Server types.
To add a Border Server client...
1. Create a module that implements the BorderClient interface;
2. Add a new constant in application_constants.go that acts as a key for selecting the client;
3. Update the NewBorderClient factory method in border_client.go that returns the client;
At this time the only supported Border Servers are NGINX Plus servers.
The two Border Server clients for NGINX Plus are:
- HttpBorderClient: updates NGINX Plus servers using HTTP Upstream methods on the NGINX Plus API.
- TcpBorderClient: updates NGINX Plus servers using Stream Upstream methods on the NGINX Plus API.
Selection of the appropriate client is based on the Annotations present on the NodePort Service definition.
Both of these implementations use the NGINX Plus client module to communicate with the NGINX Plus server.
Selection of the appropriate client is based on the Annotations present on the Service definition, e.g.:
annotations:
nginxinc.io/nkl-<upstream name>: <value>
where <upstream name> is the name of the upstream in the NGINX Plus configuration and <value> is one of the constants in application_constants.go.
*/

package application
6 changes: 6 additions & 0 deletions internal/application/http_border_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import (
nginxClient "github.com/nginxinc/nginx-plus-go-client/client"
)

// HttpBorderClient implements the BorderClient interface for HTTP upstreams.
type HttpBorderClient struct {
BorderClient
nginxClient NginxClientInterface
}

// NewHttpBorderClient is the Factory function for creating an HttpBorderClient.
func NewHttpBorderClient(client interface{}) (Interface, error) {
ngxClient, ok := client.(NginxClientInterface)
if !ok {
Expand All @@ -27,6 +29,7 @@ func NewHttpBorderClient(client interface{}) (Interface, error) {
}, nil
}

// Update manages the Upstream servers for the Upstream Name given in the ServerUpdateEvent.
func (hbc *HttpBorderClient) Update(event *core.ServerUpdateEvent) error {
httpUpstreamServers := asNginxHttpUpstreamServers(event.UpstreamServers)
_, _, _, err := hbc.nginxClient.UpdateHTTPServers(event.UpstreamName, httpUpstreamServers)
Expand All @@ -37,6 +40,7 @@ func (hbc *HttpBorderClient) Update(event *core.ServerUpdateEvent) error {
return nil
}

// Delete deletes the Upstream server for the Upstream Name given in the ServerUpdateEvent.
func (hbc *HttpBorderClient) Delete(event *core.ServerUpdateEvent) error {
err := hbc.nginxClient.DeleteHTTPServer(event.UpstreamName, event.UpstreamServers[0].Host)
if err != nil {
Expand All @@ -46,12 +50,14 @@ func (hbc *HttpBorderClient) Delete(event *core.ServerUpdateEvent) error {
return nil
}

// asNginxHttpUpstreamServer converts a core.UpstreamServer to a nginxClient.UpstreamServer.
func asNginxHttpUpstreamServer(server *core.UpstreamServer) nginxClient.UpstreamServer {
return nginxClient.UpstreamServer{
Server: server.Host,
}
}

// asNginxHttpUpstreamServers converts a core.UpstreamServers to a []nginxClient.UpstreamServer.
func asNginxHttpUpstreamServers(servers core.UpstreamServers) []nginxClient.UpstreamServer {
var upstreamServers []nginxClient.UpstreamServer

Expand Down
7 changes: 7 additions & 0 deletions internal/application/nginx_client_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ package application

import nginxClient "github.com/nginxinc/nginx-plus-go-client/client"

// NginxClientInterface defines the functions used on the NGINX Plus client, abstracting away the full details of that client.
type NginxClientInterface interface {
// DeleteStreamServer is used by the TcpBorderClient.
DeleteStreamServer(upstream string, server string) error

// UpdateStreamServers is used by the TcpBorderClient.
UpdateStreamServers(upstream string, servers []nginxClient.StreamUpstreamServer) ([]nginxClient.StreamUpstreamServer, []nginxClient.StreamUpstreamServer, []nginxClient.StreamUpstreamServer, error)

// DeleteHTTPServer is used by the HttpBorderClient.
DeleteHTTPServer(upstream string, server string) error

// UpdateHTTPServers is used by the HttpBorderClient.
UpdateHTTPServers(upstream string, servers []nginxClient.UpstreamServer) ([]nginxClient.UpstreamServer, []nginxClient.UpstreamServer, []nginxClient.UpstreamServer, error)
}
5 changes: 5 additions & 0 deletions internal/application/null_border_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,23 @@ import (
"github.com/sirupsen/logrus"
)

// NullBorderClient is a BorderClient that does nothing.
// / It serves only to prevent a panic if the BorderClient is not set correctly and errors from the factory methods are ignored.
type NullBorderClient struct {
}

// NewNullBorderClient is the Factory function for creating a NullBorderClient
func NewNullBorderClient() (Interface, error) {
return &NullBorderClient{}, nil
}

// Update logs a Warning. It is, after all, a NullObject Pattern implementation.
func (nbc *NullBorderClient) Update(_ *core.ServerUpdateEvent) error {
logrus.Warn("NullBorderClient.Update called")
return nil
}

// Delete logs a Warning. It is, after all, a NullObject Pattern implementation.
func (nbc *NullBorderClient) Delete(_ *core.ServerUpdateEvent) error {
logrus.Warn("NullBorderClient.Delete called")
return nil
Expand Down
4 changes: 4 additions & 0 deletions internal/application/tcp_border_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import (
nginxClient "github.com/nginxinc/nginx-plus-go-client/client"
)

// TcpBorderClient implements the BorderClient interface for TCP upstreams.
type TcpBorderClient struct {
BorderClient
nginxClient NginxClientInterface
}

// NewTcpBorderClient is the Factory function for creating an TcpBorderClient.
func NewTcpBorderClient(client interface{}) (Interface, error) {
ngxClient, ok := client.(NginxClientInterface)
if !ok {
Expand All @@ -27,6 +29,7 @@ func NewTcpBorderClient(client interface{}) (Interface, error) {
}, nil
}

// Update manages the Upstream servers for the Upstream Name given in the ServerUpdateEvent.
func (tbc *TcpBorderClient) Update(event *core.ServerUpdateEvent) error {
streamUpstreamServers := asNginxStreamUpstreamServers(event.UpstreamServers)
_, _, _, err := tbc.nginxClient.UpdateStreamServers(event.UpstreamName, streamUpstreamServers)
Expand All @@ -37,6 +40,7 @@ func (tbc *TcpBorderClient) Update(event *core.ServerUpdateEvent) error {
return nil
}

// Delete deletes the Upstream server for the Upstream Name given in the ServerUpdateEvent.
func (tbc *TcpBorderClient) Delete(event *core.ServerUpdateEvent) error {
err := tbc.nginxClient.DeleteStreamServer(event.UpstreamName, event.UpstreamServers[0].Host)
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions internal/communication/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import (
"time"
)

// NewHttpClient is a factory method to create a new Http Client with a default configuration.
// RoundTripper is a wrapper around the default net/communication Transport to add additional headers, in this case,
// the Headers are configured for JSON.
func NewHttpClient() (*netHttp.Client, error) {
headers := NewHeaders()
tlsConfig := NewTlsConfig()
Expand All @@ -25,17 +28,21 @@ func NewHttpClient() (*netHttp.Client, error) {
}, nil
}

// NewHeaders is a factory method to create a new basic Http Headers slice.
func NewHeaders() []string {
return []string{
"Content-Type: application/json",
"Accept: application/json",
}
}

// NewTlsConfig is a factory method to create a new basic Tls Config.
// More attention should be given to the use of `InsecureSkipVerify: true`, as it is not recommended for production use.
func NewTlsConfig() *tls.Config {
return &tls.Config{InsecureSkipVerify: true}
}

// NewTransport is a factory method to create a new basic Http Transport.
func NewTransport(config *tls.Config) *netHttp.Transport {
transport := netHttp.DefaultTransport.(*netHttp.Transport)
transport.TLSClientConfig = config
Expand Down
4 changes: 3 additions & 1 deletion internal/communication/roundtripper.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ import (
"strings"
)

// RoundTripper is a simple type that wraps the default net/communication RoundTripper to add additional headers.
type RoundTripper struct {
Headers []string
RoundTripper http.RoundTripper
}

// NewRoundTripper is a factory method to create a new RoundTripper.
func NewRoundTripper(headers []string, transport *netHttp.Transport) *RoundTripper {
return &RoundTripper{
Headers: headers,
RoundTripper: transport,
}
}

// RoundTrip Merge Headers
// RoundTrip This simply adds our default headers to the request before passing it on to the default RoundTripper.
func (roundTripper *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
newRequest := new(http.Request)
*newRequest = *req
Expand Down
2 changes: 1 addition & 1 deletion internal/configuration/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

/*
Package config, application configuration.
Package config includes application configuration.
*/

package configuration
Loading

0 comments on commit 28879f6

Please sign in to comment.