-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added valImage to monitor image vulnerabilities #1175
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Copyright 2019 The Knative Authors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
FROM golang:1.12.1 | ||
RUN apt-get update | ||
|
||
ENV TEMP_REPO_DIR /go/src/knative.dev/test-infra | ||
ENV TOOL_NAME validate-image | ||
|
||
# Temporarily add test-infra to the image to build custom tools | ||
ADD ./ $TEMP_REPO_DIR | ||
|
||
RUN make -C $TEMP_REPO_DIR/tools/$TOOL_NAME/ | ||
RUN cp $TEMP_REPO_DIR/tools/$TOOL_NAME/$TOOL_NAME /$TOOL_NAME | ||
|
||
# Remove test-infra from the container | ||
RUN rm -fr $TEMP_REPO_DIR | ||
|
||
ENTRYPOINT ["/validate-image"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Copyright 2019 The Knative Authors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
IMAGE_NAME = validate-image | ||
include ../../shared/Makefile.simple-image |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Copyright 2019 The Knative Authors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
all: | ||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build . |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# Copyright 2019 The Knative Authors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
apiVersion: v1 | ||
kind: Namespace | ||
metadata: | ||
name: validate-image | ||
--- | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: validate-image-service | ||
namespace: validate-image | ||
labels: | ||
app: validate-image | ||
spec: | ||
type: LoadBalancer | ||
ports: | ||
- port: 80 | ||
targetPort: http-server | ||
selector: | ||
app: validate-image | ||
--- | ||
apiVersion: extensions/v1beta1 | ||
kind: Deployment | ||
metadata: | ||
name: validate-image-app | ||
namespace: validate-image | ||
labels: | ||
app: validate-image | ||
spec: | ||
template: | ||
metadata: | ||
labels: | ||
app: validate-image | ||
spec: | ||
containers: | ||
- name: validate-image-app | ||
image: gcr.io/knative-tests/test-infra/validate-image:latest | ||
command: ["/validate-image"] | ||
env: | ||
- name: GOOGLE_APPLICATION_CREDENTIALS | ||
value: /secrets/google-app-credential/knative-monitoring-credential.json | ||
imagePullPolicy: Always | ||
ports: | ||
- name: http-server | ||
containerPort: 8080 | ||
volumeMounts: | ||
- name: sender-email-credentials | ||
mountPath: /secrets/sender-email | ||
readOnly: true | ||
- name: google-app-credentials | ||
mountPath: /secrets/google-app-credential/ | ||
readOnly: true | ||
volumes: | ||
- name: sender-email-credentials | ||
secret: | ||
secretName: sender-email-credentials | ||
- name: google-app-credentials | ||
secret: | ||
secretName: google-app-credentials |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,62 @@ | ||||||
// Copyright 2019 The Knative Authors | ||||||
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
// you may not use this file except in compliance with the License. | ||||||
// You may obtain a copy of the License at | ||||||
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|
||||||
// Unless required by applicable law or agreed to in writing, software | ||||||
// distributed under the License is distributed on an "AS IS" BASIS, | ||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
// See the License for the specific language governing permissions and | ||||||
// limitations under the License. | ||||||
|
||||||
package main | ||||||
|
||||||
import ( | ||||||
"flag" | ||||||
"fmt" | ||||||
"log" | ||||||
"net/http" | ||||||
"os" | ||||||
|
||||||
"knative.dev/test-infra/tools/monitoring/mail" | ||||||
) | ||||||
|
||||||
func main() { | ||||||
mailAddrSF := flag.String("sender-email", "/secrets/sender-email/mail", "Alert sender email address file") | ||||||
mailPassSF := flag.String("sender-password", "/secrets/sender-email/password", "Alert sender email password file") | ||||||
flag.Parse() | ||||||
|
||||||
mailConfig, err := mail.NewMailConfig(*mailAddrSF, *mailPassSF) | ||||||
if err != nil { | ||||||
log.Fatal(err) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
imageClient, err := NewValidateImageClient(mailConfig) | ||||||
if err != nil { | ||||||
log.Fatalf("Failed to create ValidateImageClient. Error: %v\n", err) | ||||||
} | ||||||
imageClient.Run() | ||||||
|
||||||
// use PORT environment variable, or default to 8080 | ||||||
port := "8080" | ||||||
if fromEnv := os.Getenv("PORT"); fromEnv != "" { | ||||||
port = fromEnv | ||||||
} | ||||||
|
||||||
// register hello function to handle all requests | ||||||
server := http.NewServeMux() | ||||||
server.HandleFunc("/validate-image", validateImage) | ||||||
|
||||||
// start the web server on port and accept requests | ||||||
log.Printf("Server listening on port %s", port) | ||||||
log.Fatal(http.ListenAndServe(":"+port, server)) | ||||||
} | ||||||
|
||||||
func validateImage(w http.ResponseWriter, r *http.Request) { | ||||||
log.Printf("Serving request: %s", r.URL.Path) | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove blank line |
||||||
fmt.Fprintf(w, "Last validate-image alert sent: %v\n", lastSent) | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// Copyright 2019 The Knative Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package main | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"cloud.google.com/go/pubsub" | ||
"knative.dev/test-infra/tools/monitoring/mail" | ||
"knative.dev/test-infra/tools/monitoring/subscriber" | ||
) | ||
|
||
var ( | ||
// monitoringSubs is a list of subscriptions to subscribe for image vulnerabilities | ||
monitoringSubs = [...]string{ | ||
"sub-container-analysis-notes-v1beta1", | ||
"sub-container-analysis-occurrences-v1beta1", | ||
} | ||
recipients = []string{"[email protected]"} | ||
|
||
// alertFreq is the minimum wait time before sending another image vulnerability alert | ||
alertFreq = 24 * time.Hour | ||
|
||
// Cache the last alert time in memory to prevent multiple image | ||
// vulnerability alerts sent in a short duration of time. | ||
lastSent = time.Time{} | ||
) | ||
|
||
// Client holds resources for monitoring image vulnerabilities | ||
type Client struct { | ||
subClients []*subscriber.Client | ||
mailClient *mail.Config | ||
} | ||
|
||
// NewValidateImageClient initialize all the resources for monitoring image vulnerabilities | ||
func NewValidateImageClient(mconfig *mail.Config) (*Client, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add unit test |
||
var subClients = make([]*subscriber.Client, 0) | ||
|
||
for _, sub := range monitoringSubs { | ||
log.Printf("Appending sub: %v\n", sub) | ||
subc, err := subscriber.NewSubscriberClient(sub) | ||
if err != nil { | ||
return nil, err | ||
} | ||
subClients = append(subClients, subc) | ||
log.Printf("subclients: %v\n", subClients) | ||
} | ||
|
||
return &Client{ | ||
subClients: subClients, | ||
mailClient: mconfig, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should validate mConfig != nil |
||
}, nil | ||
} | ||
|
||
// Run start a background process that listens to the message | ||
func (c *Client) Run() { | ||
log.Println("Starting image vulnerabilities monitoring") | ||
for _, sub := range c.subClients { | ||
c.listen(sub) | ||
} | ||
} | ||
|
||
func (c *Client) listen(subClient *subscriber.Client) { | ||
go func() { | ||
err := subClient.Receive(context.Background(), func(ctx context.Context, msg *pubsub.Message) { | ||
log.Printf("Message: %v\n", string(msg.Data)) | ||
log.Printf("Pubsub Message: %v\n", msg) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. whats the point of logging both? This will log the data as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The one logged with I'd like to keep the pubsub message for debugging purposes in case there's additional attributes that gets added to the image vulnerabilities message.
|
||
|
||
if time.Now().Sub(lastSent) > alertFreq { | ||
err := c.mailClient.Send(recipients, "Image Vulnerabilities Detected", toMailContent(msg)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. combine if |
||
if err != nil { | ||
log.Printf("Failed to send alert message %v\n", err) | ||
} else { | ||
lastSent = time.Now() | ||
} | ||
} else { | ||
log.Println("Message not sent because an alert is sent recently.") | ||
} | ||
msg.Ack() | ||
}) | ||
if err != nil { | ||
log.Printf("Failed to receive messages due to: %v\n", err) | ||
} | ||
}() | ||
} | ||
|
||
func toMailContent(msg *pubsub.Message) string { | ||
c := fmt.Sprintf("Message Data: %v\n", string(msg.Data)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we logging message and then the data from the message as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From the alert receiver's perspective, the pubsub message is probably not useful. I'll update the mail content to only print out the human readable message. |
||
if b, err := json.MarshalIndent(msg, "", "\t"); err == nil { | ||
c += fmt.Sprintf("\nPubsub Message: %v\n", string(b)) | ||
} | ||
c += fmt.Sprintf("\nRaw Message: %+v\n", msg) | ||
log.Printf("Mail Content:\n %v\n", c) | ||
return c | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FROM golang:latest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't know this was an option. Will try this out :)