Commit 49b55fbb authored by Geoff Simmons's avatar Geoff Simmons

REST API: implement GET/HEAD /v1/pems/{namespace}/{name}

parent 43ecc180
......@@ -87,9 +87,9 @@ var (
Detail: "/v1/pems/ URL path does not match " +
"/v1/pems/{namespace}/{name}",
}
errPemDeleteNotFound = ErrorDetails{
Type: "/errors/pems/delete/notFound",
Title: "PEM file to be deleted not found",
errPemNotFound = ErrorDetails{
Type: "/errors/pems/notFound",
Title: "PEM file not found",
Detail: "",
}
errPemDeleteError = ErrorDetails{
......@@ -279,6 +279,47 @@ func (h *pemsHndlr) allPems(
reqLog(h.log, req, now, http.StatusOK, n)
}
func (h *pemsHndlr) pemInfo(
ns, name, uid, version string,
resp http.ResponseWriter,
req *http.Request,
now time.Time,
) {
// XXX check Accept
// XXX I-M-S and I-N-M
info, found, err := h.files.GetFileInfo(ns, name, uid, version)
if !found {
h.errorResponse(resp, req, now, http.StatusNotFound,
errPemNotFound, err)
return
}
if err != nil {
h.errorResponse(resp, req, now, http.StatusInternalServerError,
errPemsReadErr, err)
return
}
jsonBytes, err := json.Marshal(info)
if err != nil {
h.errorResponse(resp, req, now, http.StatusInternalServerError,
errPemsJSONMarshal, err)
return
}
// XXX LastModified and ETag
resp.Header().Set("Content-Type", jsonContentType)
resp.Header().Set("Content-Length", strconv.Itoa(len(jsonBytes)))
n := 0
if req.Method == http.MethodGet {
n, err = resp.Write(jsonBytes)
if err != nil {
h.log.Errorf("%s %s: cannot write body: %v", req.Method,
req.RequestURI, err)
}
} else {
resp.WriteHeader(http.StatusOK)
}
reqLog(h.log, req, now, http.StatusOK, n)
}
func (h *pemsHndlr) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
now := time.Now()
......@@ -289,7 +330,6 @@ func (h *pemsHndlr) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
resp.Header().Set("Content-Length", "0")
status := http.StatusTeapot
bytes := 0
matches := pemsRegex.FindStringSubmatch(req.URL.Path)
if matches == nil {
......@@ -302,22 +342,23 @@ func (h *pemsHndlr) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
status = http.StatusMethodNotAllowed
resp.Header().Set("Allow", allowPems)
resp.WriteHeader(status)
reqLog(h.log, req, now, status, bytes)
reqLog(h.log, req, now, status, 0)
return
}
ns, name := matches[1], matches[2]
uid := req.URL.Query().Get(uidParam)
version := req.URL.Query().Get(verParam)
if req.Method == http.MethodGet || req.Method == http.MethodHead {
status = http.StatusNotImplemented
resp.WriteHeader(status)
reqLog(h.log, req, now, status, bytes)
h.pemInfo(ns, name, uid, version, resp, req, now)
return
}
ns, name := matches[1], matches[2]
if req.Method == http.MethodDelete {
if exist, err := h.files.Delete(ns, name); !exist ||
(err != nil && os.IsNotExist(err)) {
h.errorResponse(resp, req, now, http.StatusNotFound,
errPemDeleteNotFound, err)
errPemNotFound, err)
return
} else if err != nil {
h.errorResponse(resp, req, now,
......@@ -328,26 +369,23 @@ func (h *pemsHndlr) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
status = http.StatusNoContent
resp.Header().Del("Content-Length")
resp.WriteHeader(status)
reqLog(h.log, req, now, status, bytes)
reqLog(h.log, req, now, status, 0)
return
}
uid := req.URL.Query().Get(uidParam)
version := req.URL.Query().Get(verParam)
// XXX If-Match: uid/version
// XXX If-Unmodified-Since: compare file mtime
have := h.files.Have(ns, name, uid, version)
if have && req.Method == http.MethodPost {
status = http.StatusConflict
resp.WriteHeader(status)
reqLog(h.log, req, now, status, bytes)
reqLog(h.log, req, now, status, 0)
return
} else if h.files.Check(ns, name, uid, version) {
status = http.StatusNoContent
resp.Header().Del("Content-Length")
resp.WriteHeader(status)
reqLog(h.log, req, now, status, bytes)
reqLog(h.log, req, now, status, 0)
return
}
if found, valid, err := h.files.Write(ns, name, uid, version); !found {
......@@ -392,5 +430,5 @@ func (h *pemsHndlr) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
// XXX ETag: uid/version
// XXX LastModified: file mtime
resp.WriteHeader(status)
reqLog(h.log, req, now, status, bytes)
reqLog(h.log, req, now, status, 0)
}
......@@ -893,15 +893,15 @@ func TestDeletePem(t *testing.T) {
t.Fatalf("2nd DELETE /v1/pems/ns1/secret1 body unmarshal: %v",
err)
}
if problem.Type != errPemDeleteNotFound.Type {
if problem.Type != errPemNotFound.Type {
t.Errorf("2nd DELETE /v1/pems/ns1/secret1 problem type: "+
"got %s want %s",
problem.Type, errPemDeleteNotFound.Type)
problem.Type, errPemNotFound.Type)
}
if problem.Title != errPemDeleteNotFound.Title {
if problem.Title != errPemNotFound.Title {
t.Errorf("2nd DELETE /v1/pems/ns1/secret1 problem title: "+
"got %s want %s",
problem.Title, errPemDeleteNotFound.Title)
problem.Title, errPemNotFound.Title)
}
if problem.Status != http.StatusNotFound {
t.Errorf("2nd DELETE /v1/pems/ns1/secret1 problem status: "+
......@@ -944,42 +944,6 @@ func TestDeletePem(t *testing.T) {
}
}
func TestGetPem(t *testing.T) {
client := fake.NewSimpleClientset()
lister := setupSecretLister(client)
getter := crt.NewGetter(lister)
base, err := getTempDir()
if err != nil {
t.Fatalf("ioutil.TempDir(): %+v", err)
}
defer os.RemoveAll(base)
files, err := pem.NewFiles(base, -1, getter)
if err != nil {
t.Fatalf("NewFiles(): %v", err)
}
hndlr := &pemsHndlr{
log: &logrus.Logger{Out: ioutil.Discard},
files: files,
crtGetter: getter,
}
for _, method := range []string{http.MethodGet, http.MethodHead} {
req := httptest.NewRequest(method, "/v1/pems/ns/name", nil)
rr := httptest.NewRecorder()
hndlr.ServeHTTP(rr, req)
if rr.Code != http.StatusNotImplemented {
t.Errorf("%s /v1/pems/ns/name status: got %d want %d",
method, rr.Code, http.StatusNotImplemented)
}
if rr.Result().Header.Get("Content-Length") != "0" {
t.Errorf("%s /v1/pems/ns/name Content-Length: "+
"got %s want 0", method,
rr.Result().Header.Get("Content-Length"))
}
}
}
func TestPem405(t *testing.T) {
client := fake.NewSimpleClientset()
lister := setupSecretLister(client)
......
This diff is collapsed.
-----BEGIN CERTIFICATE-----
DEADBEEF
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
FOOBAR
-----END RSA PRIVATE KEY-----
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment