Skip to content

Commit

Permalink
add support for fetching annotations from external source to render c…
Browse files Browse the repository at this point in the history
…onfig templates
  • Loading branch information
rudrakhp committed Dec 19, 2023
1 parent 3a79d8d commit a36e5dd
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 1 deletion.
94 changes: 94 additions & 0 deletions pkg/extdataservice/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package extdataservice

import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
v1 "k8s.io/api/admission/v1"
"net"
"net/http"
"net/url"
"strings"
)

const (
Endpoint = "/"
)

type ExtDataClient struct {
client *http.Client
url *url.URL
}

func NewClient(apiUrl string, tlsConfig *tls.Config) (*ExtDataClient, error) {
parsedApiUrl, err := url.Parse(apiUrl)
if err != nil {
return nil, err
}
// Code path won't execute for localhost/sidecar call
if needsTLS(parsedApiUrl) && tlsConfig != nil {
return &ExtDataClient{client: &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
TLSNextProto: nil,
}}, url: parsedApiUrl}, nil
}
return &ExtDataClient{client: &http.Client{}, url: parsedApiUrl}, nil
}

type ExtDataResponse struct {
Annotations map[string]string
}

type ExtDataRequest struct {
AdmissionReview v1.AdmissionReview
}

func (c *ExtDataClient) FetchExtData(request *ExtDataRequest) (*ExtDataResponse, error) {
requestBody, err := json.Marshal(request)
if err != nil {
return nil, fmt.Errorf("error encoding request payload: %v", err)
}
req, err := http.NewRequest("GET", c.url.String()+Endpoint, bytes.NewBuffer(requestBody))
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
}
resp, err := c.client.Do(req)
if err != nil {
return nil, fmt.Errorf("error sending request: %v", err.Error())
}

defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("error failed with status code %v", resp.StatusCode)
}
var extAnnotationResponse ExtDataResponse
err = json.NewDecoder(resp.Body).Decode(&extAnnotationResponse)
if err != nil {
return nil, fmt.Errorf("error decoding response: %v", err)
}
return &extAnnotationResponse, nil
}

func needsTLS(apiUrl *url.URL) bool {
if !isLocalhost(apiUrl) {
return true
}
return false
}

func isLocalhost(u *url.URL) bool {
// Split the Host into host and port
host, _, err := net.SplitHostPort(u.Host)
if err != nil {
// If SplitHostPort fails, it might not have a port
host = u.Host
}

// Convert host to lowercase for case-insensitive comparison
host = strings.ToLower(host)

// Check if it's localhost or an IP loopback address
return host == "localhost" || host == "127.0.0.1" || host == "::1"
}
1 change: 1 addition & 0 deletions pkg/injectionwebhook/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type WebhookConfig struct {
CaFilePath string `long:"ca-file-path" required:"false" description:"file containing the CA cert"`
SidecarConfigFile string `long:"sidecar-config-file" required:"true" description:"file containing the sidecar container configuration"`
MutationConfigFile string `long:"mutation-config-file" required:"true" description:"file containing the mutation configuration"`
ExtDataUrl string `long:"ext-annotation-gen" required:"false" description:"url for fetching external data"`
BuildInfoLabels string `long:"build-info-labels" required:"false" description:"additional build info metric labels"`

// Flag to permit fallback to old, insecure TLS configurations.
Expand Down
34 changes: 33 additions & 1 deletion pkg/injectionwebhook/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"crypto/x509"
"encoding/json"
"fmt"
"github.com/salesforce/generic-sidecar-injector/pkg/extdataservice"
"io/ioutil"
"net/http"
"strings"
Expand Down Expand Up @@ -88,6 +89,7 @@ type WebhookServer struct {
sidecarConfigTemplate *template.Template
mutatingConfig *mutationconfig.MutationConfigs
certificateReloader util.CertificateReloader
extDataClient *extdataservice.ExtDataClient
}

// NewWebhookServer is a constructor for webhookServer
Expand Down Expand Up @@ -122,9 +124,30 @@ func (whsvr *WebhookServer) mutate(ar *v1.AdmissionReview) (admissionResponse *v
glog.Errorf("api=mutate, message=new AdmissionReview, Kind=%v, Namespace=%v, Name=%v (%v), UID=%v, patchOperation=%v, UserInfo=%v",
req.Kind, req.Namespace, req.Name, pod.Name, req.UID, req.Operation, req.UserInfo)

renderTemplateAnnotations := make(map[string]string)
for k, v := range pod.Annotations {
renderTemplateAnnotations[k] = v
}
if whsvr.extDataClient != nil {
extDataResponse, err := whsvr.extDataClient.FetchExtData(&extdataservice.ExtDataRequest{AdmissionReview: *ar})
if err != nil {
glog.Errorf("api=mutate, reason=extAnnotationClient, message=error fetching ext annotations, err=%v", err)
return &v1.AdmissionResponse{
Result: &metav1.Status{
Message: err.Error(),
},
}, nil
}
// Will override actual pod annotation if exists with same key
for k, v := range extDataResponse.Annotations {
renderTemplateAnnotations[k] = v
}
}

sidecarConfig, err := sidecarconfig.RenderTemplate(corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: pod.Annotations,
Labels: pod.Labels,
Annotations: renderTemplateAnnotations,
},
Spec: corev1.PodSpec{
ServiceAccountName: pod.Spec.ServiceAccountName,
Expand Down Expand Up @@ -313,6 +336,15 @@ func (whsvr *WebhookServer) Start() (chan bool, chan bool, error) {
}
whsvr.tlsServer.Handler = router

if whsvr.config.ExtDataUrl != "" {
extDataClient, err := extdataservice.NewClient(whsvr.config.ExtDataUrl, tlsConfig)
if err != nil {
glog.Errorf("api=Start, reason=extdataservice.NewClient, url=%v, err=%v", whsvr.config.ExtDataUrl, err)
return nil, nil, errors.Errorf("api=Start, reason=extdataservice.NewClient, url=%v, err=%v", whsvr.config.ExtDataUrl, err)
}
whsvr.extDataClient = extDataClient
}

// Channel to indicate when the server stopped listening for some reason
doneListeningTLSChannel := make(chan bool)

Expand Down
Binary file modified sidecarinjector
Binary file not shown.

0 comments on commit a36e5dd

Please sign in to comment.