From: enyinna1234 Date: Fri, 13 Sep 2019 00:13:40 +0000 (-0700) Subject: Adding TLS authentication X-Git-Tag: v0.4.0~84 X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;h=f863cd9c51cdfccc3996bedfd650c147d095eea3;p=icn.git Adding TLS authentication This creates auth.go and adds tls authentication to main.go. Also, containerization is introduced using Dockerfile. It also fixes patch 1431 revert issues Signed-off-by: Enyinna Ochulor Change-Id: I7f6d8d210618e4630e9240c3596ced2f672df67e --- diff --git a/cmd/bpa-restapi-agent/Makefile b/cmd/bpa-restapi-agent/Makefile index ba40a6f..2e70365 100644 --- a/cmd/bpa-restapi-agent/Makefile +++ b/cmd/bpa-restapi-agent/Makefile @@ -1,24 +1,32 @@ -# The name of the executable (default is current directory name) -TARGET := $(shell echo $${PWD\#\#*/}) -.DEFAULT_GOAL: $(TARGET) - -# These will be provided to the target -VERSION := 1.0.0 -BUILD := `git rev-parse HEAD` - -# Use linker flags to provide version/build settings to the target -LDFLAGS=-ldflags "-X=main.Version=$(VERSION) -X=main.Build=$(BUILD)" - -# go source files, ignore vendor directory -SRC = $(shell find . -type f -name '*.go' -not -path "./vendor/*") - -.PHONY: all build - -all: build - -$(TARGET): $(SRC) - @go build $(LDFLAGS) -o $(TARGET) - -build: $(TARGET) - @true +# # The name of the executable (default is current directory name) +# TARGET := $(shell echo $${PWD\#\#*/}) +# .DEFAULT_GOAL: $(TARGET) +# +# # These will be provided to the target +# VERSION := 1.0.0 +# BUILD := `git rev-parse HEAD` +# +# # Use linker flags to provide version/build settings to the target +# LDFLAGS=-ldflags "-X=main.Version=$(VERSION) -X=main.Build=$(BUILD)" +# +# # go source files, ignore vendor directory +# SRC = $(shell find . -type f -name '*.go' -not -path "./vendor/*") +# +# .PHONY: all build +# +# all: build +# +# $(TARGET): $(SRC) +# @go build $(LDFLAGS) -o $(TARGET) +# +# build: $(TARGET) +# @true + +.PHONY: build + +build: + go build -mod=vendor -o build/_output/bin/bpa-restapi-agent main.go + +docker: + docker build -t akraino.org/icn/bpa-restapi-agent:latest . -f build/Dockerfile diff --git a/cmd/bpa-restapi-agent/README.md b/cmd/bpa-restapi-agent/README.md index 27a7a51..a3300c0 100644 --- a/cmd/bpa-restapi-agent/README.md +++ b/cmd/bpa-restapi-agent/README.md @@ -1,9 +1,187 @@ ### Running the server To run the server, follow these simple steps: -``` +Integrated Cloud Native (ICN) RESTful API + +This is a Golang application providing a RESTful API to interact with and upload image objects. + +The API application source files are in the icn/cmd/bpa-restapi-agent directory. + +While the database back-end is extensible, this initial release requires mongodb. + +Install + +Install and start mongodb. For instructions: https://docs.mongodb.com/manual/installation/ + +git clone "https://gerrit.akraino.org/r/icn" +cd icn/cmd/bpa-restapi-agent + +Run the application go run main.go -``` + +Output without a config file: + +2019/08/22 14:08:41 Error loading config file. Using defaults +2019/08/22 14:08:41 Starting Integrated Cloud Native API + +RESTful API usage examples + +Sample Post Request + +curl -i -F "metadata=//jsonfile -X POST http://NODE_IP:9015//baremetalcluster/{owner}/{clustername}/ + +#image type can be binary_image, container_image, or os_image + +Example requests and responses: + +Create image - POST + +#Using a json file called sample.json +#image_length in sample.json can be determined with the command +ls -al + +Request + +curl -i -F "metadata=/{imgname} + + +example: +#continuing with our container image from above + +Request + +curl -i -X GET http://localhost:9015/v1/baremetalcluster/alpha/beta/container_images/asdf246 + +Response + +HTTP/1.1 200 OK +Content-Type: application/json +Date: Thu, 22 Aug 2019 22:57:10 GMT +Content-Length: 239 + +{"owner":"alpha","cluster_name":"beta","type":"container","image_name":"asdf246","image_offset":0,"image_length":29718177,"upload_complete":false,"description":{"image_records":[{"image_record_name":"iuysdi1234","repo":"icn","tag":"1"}]}} + +Upload container image - PATCH +Request + +curl --request PATCH --data-binary "@/home/enyi/workspace/icn/cmd/bpa-restapi-agent/sample_image" http://localhost:9015/v1/baremetalcluster/alpha/beta/container_images/asdf246 --header "Upload-Offset: 0" --header "Expect:" -i + + +Response + +HTTP/1.1 204 No Content +Upload-Offset: 29718177 +Date: Thu, 22 Aug 2019 23:19:44 GMT + +Check uploaded image - GET + +Request + +curl -i -X GET http://localhost:9015/v1/baremetalcluster/alpha/beta/container_images/asdf246 + +Response + +HTTP/1.1 200 OK +Content-Type: application/json +Date: Fri, 23 Aug 2019 17:12:07 GMT +Content-Length: 245 + +{"owner":"alpha","cluster_name":"beta","type":"container","image_name":"asdf246","image_offset":29718177,"image_length":29718177,"upload_complete":true,"description":{"image_records":[{"image_record_name":"iuysdi1234","repo":"icn","tag":"1"}]}} + +#after the upload, the image_offset is now the same as image_length and upload_complete changed to true +#if upload was incomplete + +Resumable upload instructions + +Resumable upload -PATCH + +#this is the current resumable upload mechanism + +Request + +curl --request PATCH --data-binary "@/home/enyi/workspace/icn/cmd/bpa-restapi-agent/sample_image" http://localhost:9015/v1/baremetalcluster/alpha/beta/container_images/asdf246 --header "Upload-Offset: 0" --header "Expect:" -i --limit-rate 200K + +#the above request limits transfer for testing purposes +#'ctl c' out after a few seconds, to stop file transfer +#check image_offset with a GET + +Check upload - GET + +Request + +curl -i -X GET http://localhost:9015/v1/baremetalcluster/alpha/beta/container_images/asdf246 + +Response + +HTTP/1.1 200 OK +Content-Type: application/json +Date: Sat, 24 Aug 2019 00:30:00 GMT +Content-Length: 245 + +{"owner":"alpha","cluster_name":"beta","type":"container","image_name":"asdf246","image_offset":4079616,"image_length":29718177,"upload_complete":false,"description":{"image_records":[{"image_record_name":"iuysdi1234","repo":"icn","tag":"2"}]}} + +#from our response you can see that image_offset is still less than image_length and #upload_complete is still false +#next we use the dd command (no limiting this time) + +Request + +dd if=/home/enyi/workspace/icn/cmd/bpa-restapi-agent/sample_image skip=4079616 bs=1 | curl --request PATCH --data-binary @- http://localhost:9015/v1/baremetalcluster/alpha/beta/container_images/asdf246 --header "Upload-Offset: 4079616" --header "Expect:" -i + +#the request skips already uploaded 4079616 bytes of data + +Response + +25638561+0 records in +25638561+0 records out +25638561 bytes (26 MB, 24 MiB) copied, 207.954 s, 123 kB/s +HTTP/1.1 204 No Content +Upload-Offset: 29718177 +Date: Sat, 24 Aug 2019 00:43:18 GMT + +Update image description - PUT + +# let's change the tag in description from 1 to latest +# once the change is made in sample.json (or your json file) + +Request + +curl -i -F "metadata= 0 { + log.Println("Pemfile has extra data") + } + + if x509.IsEncryptedPEMBlock(pemBlock) { + password, err := ioutil.ReadFile(filename + ".pass") + if err != nil { + return nil, pkgerrors.Wrap(err, "Read Password File") + } + + pByte, err := base64.StdEncoding.DecodeString(string(password)) + if err != nil { + return nil, pkgerrors.Wrap(err, "Decode PEM Password") + } + + pemData, err = x509.DecryptPEMBlock(pemBlock, pByte) + if err != nil { + return nil, pkgerrors.Wrap(err, "Decrypt PEM Data") + } + var newPEMBlock pem.Block + newPEMBlock.Type = pemBlock.Type + newPEMBlock.Bytes = pemData + // Converting back to PEM from DER data you get from + // DecryptPEMBlock + pemData = pem.EncodeToMemory(&newPEMBlock) + } + + return pemData, nil +} diff --git a/cmd/bpa-restapi-agent/main.go b/cmd/bpa-restapi-agent/main.go index 6a8960b..26f0ba4 100644 --- a/cmd/bpa-restapi-agent/main.go +++ b/cmd/bpa-restapi-agent/main.go @@ -10,16 +10,16 @@ import ( "os/signal" "time" - //To Do - Implement internal for checking config + "github.com/gorilla/handlers" "bpa-restapi-agent/api" utils "bpa-restapi-agent/internal" + "bpa-restapi-agent/internal/auth" "bpa-restapi-agent/internal/config" ) func main() { - // To Do - Implement initial settings // check initial config err := utils.CheckInitialSettings() if err != nil{ @@ -36,7 +36,6 @@ func main() { // Create custom http server httpServer := &http.Server{ Handler: loggedRouter, - // To Do - Implement config Addr: ":" + config.GetConfiguration().ServicePort, } connectionsClose := make(chan struct{}) @@ -49,6 +48,13 @@ func main() { }() // Start server - log.Fatal(httpServer.ListenAndServe()) - + tlsConfig, err := auth.GetTLSConfig("ca.cert", "server.cert", "server.key") + if err != nil { + log.Println("Error Getting TLS Configuration. Starting without TLS...") + log.Fatal(httpServer.ListenAndServe()) + } else { + httpServer.TLSConfig = tlsConfig + // empty strings because tlsconfig already has this information + err = httpServer.ListenAndServeTLS("", "") + } }