This repository has been archived by the owner on Dec 9, 2022. It is now read-only.
forked from simon3z/image-inspector
-
Notifications
You must be signed in to change notification settings - Fork 29
factor out image serving #39
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package api | ||
|
||
import ( | ||
docker "github.com/fsouza/go-dockerclient" | ||
"time" | ||
) | ||
|
||
// OpenSCAPStatus is the status of openscap scan | ||
type OpenSCAPStatus string | ||
|
||
const ( | ||
StatusNotRequested OpenSCAPStatus = "NotRequested" | ||
StatusSuccess OpenSCAPStatus = "Success" | ||
StatusError OpenSCAPStatus = "Error" | ||
) | ||
|
||
type OpenSCAPMetadata struct { | ||
Status OpenSCAPStatus // Status of the OpenSCAP scan report | ||
ErrorMessage string // Error message from the openscap | ||
ContentTimeStamp string // Timestamp for this data | ||
} | ||
|
||
func (osm *OpenSCAPMetadata) SetError(err error) { | ||
osm.Status = StatusError | ||
osm.ErrorMessage = err.Error() | ||
osm.ContentTimeStamp = string(time.Now().Format(time.RFC850)) | ||
} | ||
|
||
var ( | ||
ScanOptions = []string{"openscap"} | ||
) | ||
|
||
// InspectorMetadata is the metadata type with information about image-inspector's operation | ||
type InspectorMetadata struct { | ||
docker.Image // Metadata about the inspected image | ||
// OpenSCAP describes the state of the OpenSCAP scan | ||
OpenSCAP *OpenSCAPMetadata | ||
} | ||
|
||
// APIVersions holds a slice of supported API versions. | ||
type APIVersions struct { | ||
// Versions is the supported API versions | ||
Versions []string `json:"versions"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package imageserver | ||
|
||
import ( | ||
iiapi "github.com/openshift/image-inspector/pkg/api" | ||
) | ||
|
||
// ImageServer abstracts the serving of image information. | ||
type ImageServer interface { | ||
// ServeImage Serves the image | ||
ServeImage(meta *iiapi.InspectorMetadata, | ||
scanReport []byte, | ||
htmlScanReport []byte) error | ||
} | ||
|
||
// ImageServerOptions is used to configure an image server. | ||
type ImageServerOptions struct { | ||
// ServePath is the root path/port of serving. ex 0.0.0.0:8080 | ||
ServePath string | ||
// HealthzURL is the relative url of the health check. ex /healthz | ||
HealthzURL string | ||
// APIURL is the relative url where the api will be served. ex /api | ||
APIURL string | ||
// APIVersions are the supported API versions. | ||
APIVersions iiapi.APIVersions | ||
// MetadataURL is the relative url of the metadata content. ex /api/v1/metadata | ||
MetadataURL string | ||
// ContentURL is the relative url of the content. ex /api/v1/content/ | ||
ContentURL string | ||
// ImageServeURL is the location that the image is being served from. | ||
// NOTE: if the image server supports a chroot the server implementation will perform | ||
// the chroot based on this URL. | ||
ImageServeURL string | ||
// ScanType is the type of the scan that was done on the inspected image | ||
ScanType string | ||
// ScanReportURL is the url to publish the scan report | ||
ScanReportURL string | ||
// HTMLScanReport wether or not to publish an HTML scan report | ||
HTMLScanReport bool | ||
// HTMLScanReportURL url for the scan html report | ||
HTMLScanReportURL string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package imageserver | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"syscall" | ||
|
||
"golang.org/x/net/webdav" | ||
|
||
iiapi "github.com/openshift/image-inspector/pkg/api" | ||
) | ||
|
||
const ( | ||
// CHROOT_SERVE_PATH is the path to server if we are performing a chroot | ||
// this probably does not belong here. | ||
CHROOT_SERVE_PATH = "/" | ||
) | ||
|
||
// webdavImageServer implements ImageServer. | ||
type webdavImageServer struct { | ||
opts ImageServerOptions | ||
chroot bool | ||
} | ||
|
||
// ensures this always implements the interface or fail compilation. | ||
var _ ImageServer = &webdavImageServer{} | ||
|
||
// NewWebdavImageServer creates a new webdav image server. | ||
func NewWebdavImageServer(opts ImageServerOptions, chroot bool) ImageServer { | ||
return &webdavImageServer{ | ||
opts: opts, | ||
chroot: chroot, | ||
} | ||
} | ||
|
||
// ServeImage Serves the image. | ||
func (s *webdavImageServer) ServeImage(meta *iiapi.InspectorMetadata, | ||
scanReport []byte, | ||
htmlScanReport []byte) error { | ||
|
||
servePath := s.opts.ImageServeURL | ||
if s.chroot { | ||
if err := syscall.Chroot(s.opts.ImageServeURL); err != nil { | ||
return fmt.Errorf("Unable to chroot into %s: %v\n", s.opts.ImageServeURL, err) | ||
} | ||
servePath = CHROOT_SERVE_PATH | ||
} else { | ||
log.Printf("!!!WARNING!!! It is insecure to serve the image content without changing") | ||
log.Printf("root (--chroot). Absolute-path symlinks in the image can lead to disclose") | ||
log.Printf("information of the hosting system.") | ||
} | ||
|
||
log.Printf("Serving image content %s on webdav://%s%s", s.opts.ImageServeURL, s.opts.ServePath, s.opts.ContentURL) | ||
|
||
http.HandleFunc(s.opts.HealthzURL, func(w http.ResponseWriter, r *http.Request) { | ||
w.Write([]byte("ok\n")) | ||
}) | ||
|
||
http.HandleFunc(s.opts.APIURL, func(w http.ResponseWriter, r *http.Request) { | ||
body, err := json.MarshalIndent(s.opts.APIVersions, "", " ") | ||
if err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
w.Write(body) | ||
}) | ||
|
||
http.HandleFunc(s.opts.MetadataURL, func(w http.ResponseWriter, r *http.Request) { | ||
body, err := json.MarshalIndent(meta, "", " ") | ||
if err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
w.Write(body) | ||
}) | ||
|
||
http.HandleFunc(s.opts.ScanReportURL, func(w http.ResponseWriter, r *http.Request) { | ||
if s.opts.ScanType != "" && meta.OpenSCAP.Status == iiapi.StatusSuccess { | ||
w.Write(scanReport) | ||
} else { | ||
if meta.OpenSCAP.Status == iiapi.StatusError { | ||
http.Error(w, fmt.Sprintf("OpenSCAP Error: %s", meta.OpenSCAP.ErrorMessage), | ||
http.StatusInternalServerError) | ||
} else { | ||
http.Error(w, "OpenSCAP option was not chosen", http.StatusNotFound) | ||
} | ||
} | ||
}) | ||
|
||
http.HandleFunc(s.opts.HTMLScanReportURL, func(w http.ResponseWriter, r *http.Request) { | ||
if s.opts.ScanType != "" && meta.OpenSCAP.Status == iiapi.StatusSuccess && s.opts.HTMLScanReport { | ||
w.Write(htmlScanReport) | ||
} else { | ||
if meta.OpenSCAP.Status == iiapi.StatusError { | ||
http.Error(w, fmt.Sprintf("OpenSCAP Error: %s", meta.OpenSCAP.ErrorMessage), | ||
http.StatusInternalServerError) | ||
} else { | ||
http.Error(w, "OpenSCAP option was not chosen", http.StatusNotFound) | ||
} | ||
} | ||
}) | ||
|
||
http.Handle(s.opts.ContentURL, &webdav.Handler{ | ||
Prefix: s.opts.ContentURL, | ||
FileSystem: webdav.Dir(servePath), | ||
LockSystem: webdav.NewMemLS(), | ||
}) | ||
|
||
return http.ListenAndServe(s.opts.ServePath, nil) | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Why is this a string? Would there be a benefit to leaving it as
Time
? If it is because of issues with json marshalling should we take the Kube approach and provide a wrapper (seeunversioned.Time
in Kube) so we retain the option to perform time based functions on this field?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.
TBH it is string because it was string before [1], I didn't go into this that much when I moved these pieces of code around. I agree that it will be nice to have it as Time but I think that changing this should be done in a different PR because the issue is different than the one this PR is about.
[1]https://github.com/openshift/image-inspector/pull/39/files#diff-f5d24f0dc00fe1c3eeda8d22b2e523ebL20
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.
ah, ok. Been a while, sorry. I agree that we should leave it for this refactor