Restructure project similar to hello and graph
This commit is contained in:
@@ -1,33 +0,0 @@
|
||||
[run]
|
||||
watch_all = true
|
||||
watch_dirs = ["cmd", "pkg"]
|
||||
watch_exts = [".go"]
|
||||
ignore = [".git", "bin", "dist"]
|
||||
ignore_files = []
|
||||
build_delay = 1500
|
||||
interrupt_timout = 15
|
||||
graceful_kill = false
|
||||
|
||||
init_cmds = [
|
||||
["make", "build"],
|
||||
[
|
||||
"./bin/ocis-phoenix",
|
||||
"--log-level",
|
||||
"debug",
|
||||
"server",
|
||||
"--asset-path",
|
||||
"assets/"
|
||||
]
|
||||
]
|
||||
|
||||
cmds = [
|
||||
["make", "build"],
|
||||
[
|
||||
"./bin/ocis-phoenix",
|
||||
"--log-level",
|
||||
"debug",
|
||||
"server",
|
||||
"--asset-path",
|
||||
"assets/"
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
exclude_paths:
|
||||
- CHANGELOG.md
|
||||
- changelog/**
|
||||
- docs/**
|
||||
- pkg/proto/**
|
||||
|
||||
...
|
||||
+25
-2
@@ -449,10 +449,33 @@ def changelog(ctx):
|
||||
'os': 'linux',
|
||||
'arch': 'amd64',
|
||||
},
|
||||
'clone': {
|
||||
'disable': True,
|
||||
},
|
||||
'steps': [
|
||||
{
|
||||
'name': 'clone',
|
||||
'image': 'plugins/git-action:1',
|
||||
'pull': 'always',
|
||||
'settings': {
|
||||
'actions': [
|
||||
'clone',
|
||||
],
|
||||
'remote': 'https://github.com/%s' % (ctx.repo.slug),
|
||||
'branch': ctx.build.branch if ctx.build.event == 'pull_request' else 'master',
|
||||
'path': '/drone/src',
|
||||
'netrc_machine': 'github.com',
|
||||
'netrc_username': {
|
||||
'from_secret': 'github_username',
|
||||
},
|
||||
'netrc_password': {
|
||||
'from_secret': 'github_token',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
'name': 'generate',
|
||||
'image': 'toolhippie/calens:latest',
|
||||
'image': 'webhippie/golang:1.13',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'make changelog',
|
||||
@@ -460,7 +483,7 @@ def changelog(ctx):
|
||||
},
|
||||
{
|
||||
'name': 'output',
|
||||
'image': 'toolhippie/calens:latest',
|
||||
'image': 'webhippie/golang:1.13',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'cat CHANGELOG.md',
|
||||
|
||||
+9
-1
@@ -19,7 +19,15 @@ indent_size = 4
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.yml]
|
||||
[*.{yml,json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{js,vue}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{css,less}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
repository:
|
||||
name: ocis-phoenix
|
||||
description: ':atom_symbol: Serve Phoenix for Reva/oCIS'
|
||||
description: ':atom_symbol: Serve Phoenix for oCIS'
|
||||
homepage: https://owncloud.github.io/ocis-phoenix/
|
||||
topics: reva, ocis
|
||||
|
||||
|
||||
@@ -4,5 +4,3 @@ coverage.out
|
||||
/dist
|
||||
|
||||
/assets
|
||||
|
||||
/pkg/assets/embed.go
|
||||
|
||||
+18
-1
@@ -1 +1,18 @@
|
||||
# Changelog
|
||||
# Changelog for unreleased
|
||||
|
||||
The following sections list the changes for unreleased.
|
||||
|
||||
## Summary
|
||||
|
||||
* Chg #3: Initial release of basic version
|
||||
|
||||
## Details
|
||||
|
||||
* Change #3: Initial release of basic version
|
||||
|
||||
Just prepared an initial basic version to serve Phoenix for the ownCloud Infinite Scale
|
||||
project. It just provides a minimal viable product to demonstrate the microservice pattern.
|
||||
|
||||
https://github.com/owncloud/ocis-phoenix/issues/3
|
||||
|
||||
|
||||
|
||||
@@ -6,13 +6,21 @@ DIST := dist
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
EXECUTABLE := $(NAME).exe
|
||||
UNAME := Windows
|
||||
else
|
||||
EXECUTABLE := $(NAME)
|
||||
UNAME := $(shell uname -s)
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Darwin)
|
||||
GOBUILD ?= go build -i
|
||||
else
|
||||
GOBUILD ?= go build
|
||||
endif
|
||||
|
||||
PACKAGES ?= $(shell go list ./...)
|
||||
SOURCES ?= $(shell find . -name "*.go" -type f)
|
||||
GENERATE ?= $(IMPORT)/pkg/assets
|
||||
SOURCES ?= $(shell find . -name "*.go" -type f -not -path "./node_modules/*")
|
||||
GENERATE ?= $(PACKAGES)
|
||||
|
||||
TAGS ?=
|
||||
|
||||
@@ -37,6 +45,7 @@ ifndef DATE
|
||||
endif
|
||||
|
||||
LDFLAGS += -s -w -X "$(IMPORT)/pkg/version.String=$(VERSION)" -X "$(IMPORT)/pkg/version.Date=$(DATE)"
|
||||
GCFLAGS += all=-N -l
|
||||
|
||||
.PHONY: all
|
||||
all: build
|
||||
@@ -48,7 +57,7 @@ sync:
|
||||
.PHONY: clean
|
||||
clean:
|
||||
go clean -i ./...
|
||||
rm -rf $(BIN) $(DIST) assets/
|
||||
rm -rf $(BIN) $(DIST)
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
@@ -83,10 +92,13 @@ install: $(SOURCES)
|
||||
go install -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)' ./cmd/$(NAME)
|
||||
|
||||
.PHONY: build
|
||||
build: $(BIN)/$(EXECUTABLE)
|
||||
build: $(BIN)/$(EXECUTABLE) $(BIN)/$(EXECUTABLE)-debug
|
||||
|
||||
$(BIN)/$(EXECUTABLE): $(SOURCES)
|
||||
go build -i -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $@ ./cmd/$(NAME)
|
||||
$(GOBUILD) -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $@ ./cmd/$(NAME)
|
||||
|
||||
$(BIN)/$(EXECUTABLE)-debug: $(SOURCES)
|
||||
$(GOBUILD) -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -gcflags '$(GCFLAGS)' -o $@ ./cmd/$(NAME)
|
||||
|
||||
.PHONY: release
|
||||
release: release-dirs release-linux release-windows release-darwin release-copy release-check
|
||||
@@ -122,5 +134,48 @@ release-finish: release-copy release-check
|
||||
docs:
|
||||
cd docs; hugo
|
||||
|
||||
.PHONY: watch
|
||||
watch:
|
||||
go run github.com/cespare/reflex -c reflex.conf
|
||||
|
||||
# $(GOPATH)/bin/protoc-gen-go:
|
||||
# GO111MODULE=off go get -v github.com/golang/protobuf/protoc-gen-go
|
||||
|
||||
# $(GOPATH)/bin/protoc-gen-micro:
|
||||
# GO111MODULE=off go get -v github.com/micro/protoc-gen-micro
|
||||
|
||||
# $(GOPATH)/bin/protoc-gen-microweb:
|
||||
# GO111MODULE=off go get -v github.com/webhippie/protoc-gen-microweb
|
||||
|
||||
# $(GOPATH)/bin/protoc-gen-swagger:
|
||||
# GO111MODULE=off go get -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
|
||||
|
||||
# pkg/proto/v0/example.pb.go: pkg/proto/v0/example.proto
|
||||
# protoc \
|
||||
# -I=third_party/ \
|
||||
# -I=pkg/proto/v0/ \
|
||||
# --go_out=logtostderr=true:pkg/proto/v0 example.proto
|
||||
|
||||
# pkg/proto/v0/example.pb.micro.go: pkg/proto/v0/example.proto
|
||||
# protoc \
|
||||
# -I=third_party/ \
|
||||
# -I=pkg/proto/v0/ \
|
||||
# --micro_out=logtostderr=true:pkg/proto/v0 example.proto
|
||||
|
||||
# pkg/proto/v0/example.pb.web.go: pkg/proto/v0/example.proto
|
||||
# protoc \
|
||||
# -I=third_party/ \
|
||||
# -I=pkg/proto/v0/ \
|
||||
# --microweb_out=logtostderr=true:pkg/proto/v0 example.proto
|
||||
|
||||
# pkg/proto/v0/example.swagger.json: pkg/proto/v0/example.proto
|
||||
# protoc \
|
||||
# -I=third_party/ \
|
||||
# -I=pkg/proto/v0/ \
|
||||
# --swagger_out=logtostderr=true:pkg/proto/v0 example.proto
|
||||
|
||||
# .PHONY: protobuf
|
||||
# protobuf: $(GOPATH)/bin/protoc-gen-go $(GOPATH)/bin/protoc-gen-micro $(GOPATH)/bin/protoc-gen-microweb $(GOPATH)/bin/protoc-gen-swagger pkg/proto/v0/example.pb.go pkg/proto/v0/example.pb.micro.go pkg/proto/v0/example.pb.web.go pkg/proto/v0/example.swagger.json
|
||||
|
||||
assets:
|
||||
mkdir assets/ && curl -slL -o- https://github.com/owncloud/phoenix/releases/download/0.2.5/phoenix.tar.gz | tar xvzf - -C assets/
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
|
||||
## Install
|
||||
|
||||
You can download prebuilt binaries from the GitHub releases or from our [download mirrors](http://download.owncloud.com/ocis/phoenix/). For instructions how to install this on your platform you should take a look at our [documentation](https://owncloud.github.cio/ocis-phoenix/)
|
||||
You can download prebuilt binaries from the GitHub releases or from our [download mirrors](http://download.owncloud.com/ocis/phoenix/). For instructions how to install this on your platform you should take a look at our [documentation](https://owncloud.github.io/ocis-phoenix/)
|
||||
|
||||
## Development
|
||||
|
||||
Make sure you have a working Go environment, for further reference or a guide take a look at the [install instructions](http://golang.org/doc/install.html). This project requires Go >= v1.12.
|
||||
Make sure you have a working Go environment, for further reference or a guide take a look at the [install instructions](http://golang.org/doc/install.html). This project requires Go >= v1.12. For the frontend it's also required to have [NodeJS](https://nodejs.org/en/download/package-manager/) and [Yarn](https://yarnpkg.com/lang/en/docs/install/) installed.
|
||||
|
||||
```console
|
||||
git clone https://github.com/owncloud/ocis-phoenix.git
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := command.Root().Execute(); err != nil {
|
||||
if err := command.Execute(); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
+22
-15
@@ -1,17 +1,24 @@
|
||||
{
|
||||
"debug": {
|
||||
"addr": "0.0.0.0:8090",
|
||||
"token": "",
|
||||
"pprof": false
|
||||
},
|
||||
"http": {
|
||||
"addr": "0.0.0.0:8080",
|
||||
"root": "/"
|
||||
},
|
||||
"asset": {
|
||||
"path": ""
|
||||
},
|
||||
"config": {
|
||||
"file": ""
|
||||
}
|
||||
"debug": {
|
||||
"addr": "0.0.0.0:9104",
|
||||
"token": "",
|
||||
"pprof": false,
|
||||
"zpages": false
|
||||
},
|
||||
"http": {
|
||||
"addr": "0.0.0.0:9100"
|
||||
},
|
||||
"tracing": {
|
||||
"enabled": false,
|
||||
"type": "jaeger",
|
||||
"endpoint": "localhost:6831",
|
||||
"collector": "http://localhost:14268/api/traces",
|
||||
"service": "phoenix"
|
||||
},
|
||||
"asset": {
|
||||
"path": ""
|
||||
},
|
||||
"config": {
|
||||
"file": ""
|
||||
}
|
||||
}
|
||||
|
||||
+10
-3
@@ -1,12 +1,19 @@
|
||||
---
|
||||
debug:
|
||||
addr: 0.0.0.0:8090
|
||||
addr: 0.0.0.0:9104
|
||||
token:
|
||||
pprof: false
|
||||
zpages: false
|
||||
|
||||
http:
|
||||
addr: 0.0.0.0:8080
|
||||
root: /
|
||||
addr: 0.0.0.0:9100
|
||||
|
||||
tracing:
|
||||
enabled: false
|
||||
type: jaeger
|
||||
endpoint: localhost:6831
|
||||
collector: http://localhost:14268/api/traces
|
||||
service: phoenix
|
||||
|
||||
asset:
|
||||
path:
|
||||
|
||||
@@ -11,6 +11,8 @@ LABEL maintainer="ownCloud GmbH <devops@owncloud.com>" \
|
||||
org.label-schema.vendor="ownCloud GmbH" \
|
||||
org.label-schema.schema-version="1.0"
|
||||
|
||||
EXPOSE 9100 9104
|
||||
|
||||
ENTRYPOINT ["/usr/bin/ocis-phoenix"]
|
||||
CMD ["server"]
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ LABEL maintainer="ownCloud GmbH <devops@owncloud.com>" \
|
||||
org.label-schema.vendor="ownCloud GmbH" \
|
||||
org.label-schema.schema-version="1.0"
|
||||
|
||||
EXPOSE 9100 9104
|
||||
|
||||
ENTRYPOINT ["/usr/bin/ocis-phoenix"]
|
||||
CMD ["server"]
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ LABEL maintainer="ownCloud GmbH <devops@owncloud.com>" \
|
||||
org.label-schema.vendor="ownCloud GmbH" \
|
||||
org.label-schema.schema-version="1.0"
|
||||
|
||||
EXPOSE 9100 9104
|
||||
|
||||
ENTRYPOINT ["/usr/bin/ocis-phoenix"]
|
||||
CMD ["server"]
|
||||
|
||||
|
||||
+1
-1
@@ -14,5 +14,5 @@ disableKinds = ["taxonomy", "taxonomyTerm", "RSS", "sitemap"]
|
||||
|
||||
[params]
|
||||
author = "ownCloud GmbH"
|
||||
description = "Serve Phoenix for Reva/oCIS"
|
||||
description = "Serve Phoenix for oCIS"
|
||||
keywords = "reva, ocis"
|
||||
|
||||
@@ -5,4 +5,4 @@ anchor: "about"
|
||||
weight: 10
|
||||
---
|
||||
|
||||
This service embeds [Phoenix](https://github.com/owncloud/phoenix) to provide a UI for the ownCloud Infinite Scale stack.
|
||||
This service embeds [Phoenix](https://github.com/owncloud/phoenix) to provide a UI for ownCloud Infinite Scale.
|
||||
|
||||
@@ -5,23 +5,20 @@ anchor: "building"
|
||||
weight: 30
|
||||
---
|
||||
|
||||
As this project is built with Go, so you need to install that first. The installation of Go is out of the scope of this document, please follow the official documentation for [Go](golang), to build this project you have to install Go >= v1.12. After the installation of the required tools you need to get the sources:
|
||||
As this project is built with Go, so you need to install that first. The installation of Go is out of the scope of this document, please follow the official documentation for [Go](https://golang.org/doc/install), to build this project you have to install Go >= v1.12. After the installation of the required tools you need to get the sources:
|
||||
|
||||
{{< highlight txt >}}
|
||||
git clone https://github.com/owncloud/ocis-hello.git
|
||||
cd ocis-hello
|
||||
git clone https://github.com/owncloud/ocis-phoenix.git
|
||||
cd ocis-phoenix
|
||||
{{< / highlight >}}
|
||||
|
||||
All required tool besides Go itself and make are bundled or getting automatically installed within the `GOPATH`. All commands to build this project are part of our `Makefile`.
|
||||
|
||||
## Backend
|
||||
### Backend
|
||||
|
||||
{{< highlight txt >}}
|
||||
make generate
|
||||
make build
|
||||
{{< / highlight >}}
|
||||
|
||||
The above commands will download a [Phoenix](phoenix) release and embed it into the binary. Finally you should have the binary within the `bin/` folder now, give it a try with `./bin/ocis-hello -h` to see all available options.
|
||||
|
||||
[golang]: https://golang.org/doc/install
|
||||
[phoenix]: https://github.com/owncloud/phoenix
|
||||
The above commands will download a [Phoenix](https://github.com/owncloud/phoenix) release and embed it into the binary. Finally you should have the binary within the `bin/` folder now, give it a try with `./bin/ocis-phoenix -h` to see all available options.
|
||||
|
||||
@@ -5,27 +5,30 @@ anchor: "getting-started"
|
||||
weight: 20
|
||||
---
|
||||
|
||||
## Installation
|
||||
### Installation
|
||||
|
||||
So far we are offering two different variants for the installation. You can choose between [Docker](docker) or pre-built binaries which are stored on our download mirrors and GitHub releases. Maybe we will also provide system packages for the major distributions later if we see the need for it.
|
||||
So far we are offering two different variants for the installation. You can choose between [Docker](https://www.docker.com/) or pre-built binaries which are stored on our download mirrors and GitHub releases. Maybe we will also provide system packages for the major distributions later if we see the need for it.
|
||||
|
||||
### Docker
|
||||
#### Docker
|
||||
|
||||
TBD
|
||||
|
||||
### Binaries
|
||||
#### Binaries
|
||||
|
||||
TBD
|
||||
|
||||
## Configuration
|
||||
### Configuration
|
||||
|
||||
We provide overall three different variants of configuration. The variant based on environment variables and commandline flags are split up into global values and command-specific values.
|
||||
|
||||
### Envrionment variables
|
||||
#### Envrionment variables
|
||||
|
||||
If you prefer to configure the service with environment variables you can see the available variables below.
|
||||
|
||||
#### Global
|
||||
##### Global
|
||||
|
||||
PHOENIX_CONFIG_FILE
|
||||
: Path to config file, empty default value
|
||||
|
||||
PHOENIX_LOG_LEVEL
|
||||
: Set logging level, defaults to `info`
|
||||
@@ -36,10 +39,25 @@ PHOENIX_LOG_COLOR
|
||||
PHOENIX_LOG_PRETTY
|
||||
: Enable pretty logging, defaults to `true`
|
||||
|
||||
#### Server
|
||||
##### Server
|
||||
|
||||
PHOENIX_TRACING_ENABLED
|
||||
: Enable sending traces, defaults to `false`
|
||||
|
||||
PHOENIX_TRACING_TYPE
|
||||
: Tracing backend type, defaults to `jaeger`
|
||||
|
||||
PHOENIX_TRACING_ENDPOINT
|
||||
: Endpoint for the agent, empty default value
|
||||
|
||||
PHOENIX_TRACING_COLLECTOR
|
||||
: Endpoint for the collector, empty default value
|
||||
|
||||
PHOENIX_TRACING_SERVICE
|
||||
: Service name for tracing, defaults to `phoenix`
|
||||
|
||||
PHOENIX_DEBUG_ADDR
|
||||
: Address to bind debug server, defaults to `0.0.0.0:8090`
|
||||
: Address to bind debug server, defaults to `0.0.0.0:9104`
|
||||
|
||||
PHOENIX_DEBUG_TOKEN
|
||||
: Token to grant metrics access, empty default value
|
||||
@@ -47,28 +65,31 @@ PHOENIX_DEBUG_TOKEN
|
||||
PHOENIX_DEBUG_PPROF
|
||||
: Enable pprof debugging, defaults to `false`
|
||||
|
||||
PHOENIX_HTTP_ADDR
|
||||
: Address to bind http server, defaults to `0.0.0.0:8080`
|
||||
PHOENIX_DEBUG_ZPAGES
|
||||
: Enable zpages debugging, defaults to `false`
|
||||
|
||||
PHOENIX_HTTP_ROOT
|
||||
: Root path for http endpoint, defaults to `/`
|
||||
PHOENIX_HTTP_ADDR
|
||||
: Address to bind http server, defaults to `0.0.0.0:9100`
|
||||
|
||||
PHOENIX_ASSET_PATH
|
||||
: Path to custom assets, empty default value
|
||||
|
||||
PHOENIX_CONFIG_FILE
|
||||
PHOENIX_WEB_CONFIG
|
||||
: Path to phoenix config, empty default value
|
||||
|
||||
#### Health
|
||||
##### Health
|
||||
|
||||
PHOENIX_DEBUG_ADDR
|
||||
: Address to debug endpoint, defaults to `0.0.0.0:8090`
|
||||
: Address to debug endpoint, defaults to `0.0.0.0:9104`
|
||||
|
||||
### Commandline flags
|
||||
#### Commandline flags
|
||||
|
||||
If you prefer to configure the service with commandline flags you can see the available variables below.
|
||||
|
||||
#### Global
|
||||
##### Global
|
||||
|
||||
--config-file
|
||||
: Path to config file, empty default value
|
||||
|
||||
--log-level
|
||||
: Set logging level, defaults to `info`
|
||||
@@ -79,10 +100,25 @@ If you prefer to configure the service with commandline flags you can see the av
|
||||
--log-pretty
|
||||
: Enable pretty logging, defaults to `true`
|
||||
|
||||
#### Server
|
||||
##### Server
|
||||
|
||||
--tracing-enabled
|
||||
: Enable sending traces, defaults to `false`
|
||||
|
||||
--tracing-type
|
||||
: Tracing backend type, defaults to `jaeger`
|
||||
|
||||
--tracing-endpoint
|
||||
: Endpoint for the agent, empty default value
|
||||
|
||||
--tracing-collector
|
||||
: Endpoint for the collector, empty default value
|
||||
|
||||
--tracing-service
|
||||
: Service name for tracing, defaults to `phoenix`
|
||||
|
||||
--debug-addr
|
||||
: Address to bind debug server, defaults to `0.0.0.0:8090`
|
||||
: Address to bind debug server, defaults to `0.0.0.0:9104`
|
||||
|
||||
--debug-token
|
||||
: Token to grant metrics access, empty default value
|
||||
@@ -90,32 +126,32 @@ If you prefer to configure the service with commandline flags you can see the av
|
||||
--debug-pprof
|
||||
: Enable pprof debugging, defaults to `false`
|
||||
|
||||
--http-addr
|
||||
: Address to bind http server, defaults to `0.0.0.0:8080`
|
||||
--debug-zpages
|
||||
: Enable zpages debugging, defaults to `false`
|
||||
|
||||
--http-root
|
||||
: Root path for http endpoint, defaults to `/`
|
||||
--http-addr
|
||||
: Address to bind http server, defaults to `0.0.0.0:9100`
|
||||
|
||||
--asset-path
|
||||
: Path to custom assets, empty default value
|
||||
|
||||
--config-file
|
||||
--web-config
|
||||
: Path to phoenix config, empty default value
|
||||
|
||||
#### Health
|
||||
##### Health
|
||||
|
||||
--debug-addr
|
||||
: Address to debug endpoint, defaults to `0.0.0.0:8090`
|
||||
: Address to debug endpoint, defaults to `0.0.0.0:9104`
|
||||
|
||||
### Configuration file
|
||||
#### Configuration file
|
||||
|
||||
So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](repo), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/phoenix.yml`, `${HOME}/.ocis/phoenix.yml` or `$(pwd)/config/phoenix.yml`.
|
||||
So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis-phoenix/tree/master/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/phoenix.yml`, `${HOME}/.ocis/phoenix.yml` or `$(pwd)/config/phoenix.yml`.
|
||||
|
||||
## Usage
|
||||
### Usage
|
||||
|
||||
The program provides a few sub-commands on execution. The available configuration methods have already been mentioned above. Generally you can always see a formated help output if you execute the binary via `ocis-phoenix --help`.
|
||||
|
||||
### Server
|
||||
#### Server
|
||||
|
||||
The server command is used to start the http and debug server on two addresses within a single process. The http server is serving the general webservice while the debug server is used for health check, readiness check and to server the metrics mentioned below. For further help please execute:
|
||||
|
||||
@@ -123,7 +159,7 @@ The server command is used to start the http and debug server on two addresses w
|
||||
ocis-phoenix server --help
|
||||
{{< / highlight >}}
|
||||
|
||||
### Health
|
||||
#### Health
|
||||
|
||||
The health command is used to execute a health check, if the exit code equals zero the service should be up and running, if the exist code is greater than zero the service is not in a healthy state. Generally this command is used within our Docker containers, it could also be used within Kubernetes.
|
||||
|
||||
@@ -131,9 +167,9 @@ The health command is used to execute a health check, if the exit code equals ze
|
||||
ocis-phoenix health --help
|
||||
{{< / highlight >}}
|
||||
|
||||
## Metrics
|
||||
### Metrics
|
||||
|
||||
This service provides some [Prometheus](prom) metrics through the debug endpoint, you can optionally secure the metrics endpoint by some random token, which got to be configured through one of the flag `--debug-token` or the environment variable `PHOENIX_DEBUG_TOKEN` mentioned above. By default the metrics endpoint is bound to `http://0.0.0.0:8090/metrics`.
|
||||
This service provides some [Prometheus](https://prometheus.io/) metrics through the debug endpoint, you can optionally secure the metrics endpoint by some random token, which got to be configured through one of the flag `--debug-token` or the environment variable `PHOENIX_DEBUG_TOKEN` mentioned above. By default the metrics endpoint is bound to `http://0.0.0.0:9104/metrics`.
|
||||
|
||||
go_gc_duration_seconds
|
||||
: A summary of the GC invocation durations
|
||||
@@ -230,7 +266,3 @@ promhttp_metric_handler_requests_in_flight
|
||||
|
||||
promhttp_metric_handler_requests_total
|
||||
: Total number of scrapes by HTTP status code
|
||||
|
||||
[docker]: https://www.docker.com/
|
||||
[repo]: https://github.com/owncloud/ocis-phoenix/tree/master/config
|
||||
[prom]: https://prometheus.io/
|
||||
|
||||
@@ -5,6 +5,4 @@ anchor: "license"
|
||||
weight: 40
|
||||
---
|
||||
|
||||
This project is licensed under the [Apache 2.0](license) license. For the license of the used libraries you have to check the respective sources.
|
||||
|
||||
[license]: https://github.com/owncloud/ocis-phoenix/blob/master/LICENSE
|
||||
This project is licensed under the [Apache 2.0](https://github.com/owncloud/ocis-phoenix/blob/master/LICENSE) license. For the license of the used libraries you have to check the respective sources.
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
module github.com/owncloud/ocis-phoenix
|
||||
|
||||
go 1.12
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/UnnoTed/fileb0x v1.1.3 // indirect
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.2.0
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.6.0
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.1
|
||||
github.com/UnnoTed/fileb0x v1.1.4 // indirect
|
||||
github.com/cespare/reflex v0.2.0 // indirect
|
||||
github.com/go-chi/chi v4.0.2+incompatible
|
||||
github.com/haya14busa/goverage v0.0.0-20180129164344-eec3514a20b5 // indirect
|
||||
github.com/mitchellh/gox v1.0.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/micro/cli v0.2.0
|
||||
github.com/ogier/pflag v0.0.1 // indirect
|
||||
github.com/oklog/run v1.0.0
|
||||
github.com/prometheus/client_golang v1.1.0
|
||||
github.com/rs/zerolog v1.15.0
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/viper v1.4.0
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
|
||||
github.com/openzipkin/zipkin-go v0.2.2
|
||||
github.com/owncloud/ocis-pkg v1.1.0
|
||||
github.com/spf13/viper v1.5.0
|
||||
go.opencensus.io v0.22.2
|
||||
golang.org/x/net v0.0.0-20191206103017-1ddd1de85cb0
|
||||
)
|
||||
|
||||
+12
-11
@@ -5,22 +5,24 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-pkg/log"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/UnnoTed/fileb0x embed.yml
|
||||
|
||||
// assets gets initialized by New and provides the handler.
|
||||
type assets struct {
|
||||
path string
|
||||
logger log.Logger
|
||||
config *config.Config
|
||||
}
|
||||
|
||||
// Open just implements the HTTP filesystem interface.
|
||||
func (a assets) Open(original string) (http.File, error) {
|
||||
if a.path != "" {
|
||||
if stat, err := os.Stat(a.path); err == nil && stat.IsDir() {
|
||||
if a.config.Asset.Path != "" {
|
||||
if stat, err := os.Stat(a.config.Asset.Path); err == nil && stat.IsDir() {
|
||||
custom := path.Join(
|
||||
a.path,
|
||||
a.config.Asset.Path,
|
||||
original,
|
||||
)
|
||||
|
||||
@@ -34,7 +36,8 @@ func (a assets) Open(original string) (http.File, error) {
|
||||
return f, nil
|
||||
}
|
||||
} else {
|
||||
log.Warn().
|
||||
a.logger.Warn().
|
||||
Str("path", a.config.Asset.Path).
|
||||
Msg("Assets directory doesn't exist")
|
||||
}
|
||||
}
|
||||
@@ -49,11 +52,9 @@ func (a assets) Open(original string) (http.File, error) {
|
||||
|
||||
// New returns a new http filesystem to serve assets.
|
||||
func New(opts ...Option) http.FileSystem {
|
||||
a := new(assets)
|
||||
options := newOptions(opts...)
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(a)
|
||||
return assets{
|
||||
config: options.Config,
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAssets(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
+35
-6
@@ -1,11 +1,40 @@
|
||||
package assets
|
||||
|
||||
// Option configures an assets option.
|
||||
type Option func(*assets)
|
||||
import (
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// WithPath returns an option to set custom assets path.
|
||||
func WithPath(val string) Option {
|
||||
return func(a *assets) {
|
||||
a.path = val
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
Config *config.Config
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(val log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = val
|
||||
}
|
||||
}
|
||||
|
||||
// Config provides a function to set the config option.
|
||||
func Config(val *config.Config) Option {
|
||||
return func(o *Options) {
|
||||
o.Config = val
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// init defined the default options for viper.
|
||||
func init() {
|
||||
viper.SetDefault("debug.addr", "0.0.0.0:8090")
|
||||
viper.SetDefault("debug.token", "")
|
||||
viper.SetDefault("debug.pprof", false)
|
||||
|
||||
viper.SetDefault("http.addr", "0.0.0.0:8080")
|
||||
viper.SetDefault("http.root", "/")
|
||||
|
||||
viper.SetDefault("asset.path", "")
|
||||
viper.SetDefault("config.file", "")
|
||||
}
|
||||
+19
-24
@@ -3,52 +3,47 @@ package command
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/micro/cli"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/flagset"
|
||||
)
|
||||
|
||||
// Health is the entrypoint for the health command.
|
||||
func Health() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "health",
|
||||
Short: "Check health status",
|
||||
Long: "",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
func Health(cfg *config.Config) cli.Command {
|
||||
return cli.Command{
|
||||
Name: "health",
|
||||
Usage: "Check health status",
|
||||
Flags: flagset.HealthWithConfig(cfg),
|
||||
Action: func(c *cli.Context) error {
|
||||
logger := NewLogger(cfg)
|
||||
|
||||
resp, err := http.Get(
|
||||
fmt.Sprintf(
|
||||
"http://%s/healthz",
|
||||
viper.GetString("debug.addr"),
|
||||
cfg.Debug.Addr,
|
||||
),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Error().
|
||||
logger.Fatal().
|
||||
Err(err).
|
||||
Msg("Failed to request health check")
|
||||
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
log.Error().
|
||||
logger.Fatal().
|
||||
Int("code", resp.StatusCode).
|
||||
Msg("Health seems to be in bad state")
|
||||
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
logger.Debug().
|
||||
Int("code", resp.StatusCode).
|
||||
Msg("Health got a good state")
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().String("debug-addr", "", "Address to debug endpoint")
|
||||
viper.BindPFlag("debug.addr", cmd.Flags().Lookup("debug-addr"))
|
||||
viper.BindEnv("debug.addr", "PHOENIX_DEBUG_ADDR")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHealth(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
+84
-85
@@ -4,101 +4,100 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/micro/cli"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/flagset"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/version"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/owncloud/ocis-pkg/log"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// Root is the entry point for the ocis-phoenix command.
|
||||
func Root() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "ocis-phoenix",
|
||||
Short: "Reva service for phoenix",
|
||||
Long: ``,
|
||||
Version: version.String,
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
setupLogger()
|
||||
setupConfig()
|
||||
// Execute is the entry point for the ocis-phoenix command.
|
||||
func Execute() error {
|
||||
cfg := config.New()
|
||||
|
||||
app := &cli.App{
|
||||
Name: "ocis-phoenix",
|
||||
Version: version.String,
|
||||
Usage: "Serve Phoenix for oCIS",
|
||||
Compiled: version.Compiled(),
|
||||
|
||||
Authors: []cli.Author{
|
||||
{
|
||||
Name: "ownCloud GmbH",
|
||||
Email: "support@owncloud.com",
|
||||
},
|
||||
},
|
||||
|
||||
Flags: flagset.RootWithConfig(cfg),
|
||||
|
||||
Before: func(c *cli.Context) error {
|
||||
logger := NewLogger(cfg)
|
||||
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
viper.SetEnvPrefix("PHOENIX")
|
||||
viper.AutomaticEnv()
|
||||
|
||||
if c.IsSet("config-file") {
|
||||
viper.SetConfigFile(c.String("config-file"))
|
||||
} else {
|
||||
viper.SetConfigName("phoenix")
|
||||
|
||||
viper.AddConfigPath("/etc/ocis")
|
||||
viper.AddConfigPath("$HOME/.ocis")
|
||||
viper.AddConfigPath("./config")
|
||||
}
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
switch err.(type) {
|
||||
case viper.ConfigFileNotFoundError:
|
||||
logger.Info().
|
||||
Msg("Continue without config")
|
||||
case viper.UnsupportedConfigError:
|
||||
logger.Fatal().
|
||||
Err(err).
|
||||
Msg("Unsupported config type")
|
||||
default:
|
||||
logger.Fatal().
|
||||
Err(err).
|
||||
Msg("Failed to read config")
|
||||
}
|
||||
}
|
||||
|
||||
if err := viper.Unmarshal(&cfg); err != nil {
|
||||
logger.Fatal().
|
||||
Err(err).
|
||||
Msg("Failed to parse config")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
|
||||
Commands: []cli.Command{
|
||||
Server(cfg),
|
||||
Health(cfg),
|
||||
},
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().String("log-level", "", "Set logging level")
|
||||
viper.BindPFlag("log.level", cmd.PersistentFlags().Lookup("log-level"))
|
||||
viper.SetDefault("log.level", "info")
|
||||
viper.BindEnv("log.level", "PHOENIX_LOG_LEVEL")
|
||||
|
||||
cmd.PersistentFlags().Bool("log-pretty", false, "Enable pretty logging")
|
||||
viper.BindPFlag("log.pretty", cmd.PersistentFlags().Lookup("log-pretty"))
|
||||
viper.SetDefault("log.pretty", true)
|
||||
viper.BindEnv("log.pretty", "PHOENIX_LOG_PRETTY")
|
||||
|
||||
cmd.PersistentFlags().Bool("log-color", false, "Enable colored logging")
|
||||
viper.BindPFlag("log.color", cmd.PersistentFlags().Lookup("log-color"))
|
||||
viper.SetDefault("log.color", true)
|
||||
viper.BindEnv("log.color", "PHOENIX_LOG_COLOR")
|
||||
|
||||
cmd.AddCommand(Server())
|
||||
cmd.AddCommand(Health())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// setupLogger prepares the logger.
|
||||
func setupLogger() {
|
||||
switch strings.ToLower(viper.GetString("log.level")) {
|
||||
case "panic":
|
||||
zerolog.SetGlobalLevel(zerolog.PanicLevel)
|
||||
case "fatal":
|
||||
zerolog.SetGlobalLevel(zerolog.FatalLevel)
|
||||
case "error":
|
||||
zerolog.SetGlobalLevel(zerolog.ErrorLevel)
|
||||
case "warn":
|
||||
zerolog.SetGlobalLevel(zerolog.WarnLevel)
|
||||
case "info":
|
||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||
case "debug":
|
||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||
default:
|
||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||
cli.HelpFlag = &cli.BoolFlag{
|
||||
Name: "help,h",
|
||||
Usage: "Show the help",
|
||||
}
|
||||
|
||||
if viper.GetBool("log.pretty") {
|
||||
log.Logger = log.Output(
|
||||
zerolog.ConsoleWriter{
|
||||
Out: os.Stderr,
|
||||
NoColor: !viper.GetBool("log.color"),
|
||||
},
|
||||
)
|
||||
cli.VersionFlag = &cli.BoolFlag{
|
||||
Name: "version,v",
|
||||
Usage: "Print the version",
|
||||
}
|
||||
|
||||
return app.Run(os.Args)
|
||||
}
|
||||
|
||||
// setupConfig prepares the config.
|
||||
func setupConfig() {
|
||||
viper.SetConfigName("phoenix")
|
||||
|
||||
viper.AddConfigPath("/etc/ocis")
|
||||
viper.AddConfigPath("$HOME/.ocis")
|
||||
viper.AddConfigPath("./config")
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
switch err.(type) {
|
||||
case viper.ConfigFileNotFoundError:
|
||||
log.Debug().
|
||||
Msg("Initializing without config file")
|
||||
case viper.UnsupportedConfigError:
|
||||
log.Fatal().
|
||||
Msg("Unsupported config type")
|
||||
default:
|
||||
if e := log.Debug(); e.Enabled() {
|
||||
log.Fatal().
|
||||
Err(err).
|
||||
Msg("Failed to read config")
|
||||
} else {
|
||||
log.Fatal().
|
||||
Msg("Failed to read config")
|
||||
}
|
||||
}
|
||||
}
|
||||
// NewLogger initializes a service-specific logger instance.
|
||||
func NewLogger(cfg *config.Config) log.Logger {
|
||||
return log.NewLogger(
|
||||
log.Name("phoenix"),
|
||||
log.Level(cfg.Log.Level),
|
||||
log.Pretty(cfg.Log.Pretty),
|
||||
log.Color(cfg.Log.Color),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRoot(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
+157
-195
@@ -2,198 +2,189 @@ package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"contrib.go.opencensus.io/exporter/jaeger"
|
||||
"contrib.go.opencensus.io/exporter/ocagent"
|
||||
"contrib.go.opencensus.io/exporter/zipkin"
|
||||
"github.com/micro/cli"
|
||||
"github.com/oklog/run"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/router/debug"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/router/server"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
openzipkin "github.com/openzipkin/zipkin-go"
|
||||
zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/flagset"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/metrics"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/server/debug"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/server/http"
|
||||
"go.opencensus.io/stats/view"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// Server is the entrypoint for the server command.
|
||||
func Server() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "server",
|
||||
Short: "Start integrated server",
|
||||
Long: "",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var gr run.Group
|
||||
func Server(cfg *config.Config) cli.Command {
|
||||
return cli.Command{
|
||||
Name: "server",
|
||||
Usage: "Start integrated server",
|
||||
Flags: flagset.ServerWithConfig(cfg),
|
||||
Action: func(c *cli.Context) error {
|
||||
logger := NewLogger(cfg)
|
||||
|
||||
if cfg.Tracing.Enabled {
|
||||
switch t := cfg.Tracing.Type; t {
|
||||
case "agent":
|
||||
exporter, err := ocagent.NewExporter(
|
||||
ocagent.WithReconnectionPeriod(5*time.Second),
|
||||
ocagent.WithAddress(cfg.Tracing.Endpoint),
|
||||
ocagent.WithServiceName(cfg.Tracing.Service),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("endpoint", cfg.Tracing.Endpoint).
|
||||
Str("collector", cfg.Tracing.Collector).
|
||||
Msg("Failed to create agent tracing")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
trace.RegisterExporter(exporter)
|
||||
view.RegisterExporter(exporter)
|
||||
|
||||
case "jaeger":
|
||||
exporter, err := jaeger.NewExporter(
|
||||
jaeger.Options{
|
||||
AgentEndpoint: cfg.Tracing.Endpoint,
|
||||
CollectorEndpoint: cfg.Tracing.Collector,
|
||||
ServiceName: cfg.Tracing.Service,
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("endpoint", cfg.Tracing.Endpoint).
|
||||
Str("collector", cfg.Tracing.Collector).
|
||||
Msg("Failed to create jaeger tracing")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
trace.RegisterExporter(exporter)
|
||||
|
||||
case "zipkin":
|
||||
endpoint, err := openzipkin.NewEndpoint(
|
||||
cfg.Tracing.Service,
|
||||
cfg.Tracing.Endpoint,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("endpoint", cfg.Tracing.Endpoint).
|
||||
Str("collector", cfg.Tracing.Collector).
|
||||
Msg("Failed to create zipkin tracing")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
exporter := zipkin.NewExporter(
|
||||
zipkinhttp.NewReporter(
|
||||
cfg.Tracing.Collector,
|
||||
),
|
||||
endpoint,
|
||||
)
|
||||
|
||||
trace.RegisterExporter(exporter)
|
||||
|
||||
default:
|
||||
logger.Warn().
|
||||
Str("type", t).
|
||||
Msg("Unknown tracing backend")
|
||||
}
|
||||
|
||||
trace.ApplyConfig(
|
||||
trace.Config{
|
||||
DefaultSampler: trace.AlwaysSample(),
|
||||
},
|
||||
)
|
||||
} else {
|
||||
logger.Debug().
|
||||
Msg("Tracing is not enabled")
|
||||
}
|
||||
|
||||
var (
|
||||
gr = run.Group{}
|
||||
ctx, cancel = context.WithCancel(context.Background())
|
||||
metrics = metrics.New()
|
||||
)
|
||||
|
||||
defer cancel()
|
||||
|
||||
{
|
||||
server := &http.Server{
|
||||
Addr: viper.GetString("debug.addr"),
|
||||
Handler: debug.Router(
|
||||
debug.WithToken(viper.GetString("debug.token")),
|
||||
debug.WithPprof(viper.GetBool("debug.pprof")),
|
||||
),
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
server, err := http.Server(
|
||||
http.Logger(logger),
|
||||
http.Context(ctx),
|
||||
http.Config(cfg),
|
||||
http.Metrics(metrics),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Info().
|
||||
Err(err).
|
||||
Str("transport", "http").
|
||||
Msg("Failed to initialize server")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
gr.Add(func() error {
|
||||
log.Info().
|
||||
Str("addr", viper.GetString("debug.addr")).
|
||||
Msg("Starting debug server")
|
||||
return server.Run()
|
||||
}, func(_ error) {
|
||||
logger.Info().
|
||||
Str("transport", "http").
|
||||
Msg("Shutting down server")
|
||||
|
||||
if strings.HasPrefix(viper.GetString("debug.addr"), "unix://") {
|
||||
socket := strings.TrimPrefix(viper.GetString("debug.addr"), "unix://")
|
||||
|
||||
if err := os.Remove(socket); err != nil && !os.IsNotExist(err) {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("socket", socket).
|
||||
Msg("Failed to remove existing debug socket")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
listener, err := net.ListenUnix(
|
||||
"unix",
|
||||
&net.UnixAddr{
|
||||
Name: socket,
|
||||
Net: "unix",
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Msg("Failed to initialize debug unix socket")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.Chmod(socket, os.FileMode(0666)); err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Msg("Failed to change debug socket permissions")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return server.Serve(listener)
|
||||
}
|
||||
|
||||
return server.ListenAndServe()
|
||||
}, func(reason error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Msg("Failed to shutdown debug server gracefully")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if strings.HasPrefix(viper.GetString("debug.addr"), "unix://") {
|
||||
socket := strings.TrimPrefix(viper.GetString("debug.addr"), "unix://")
|
||||
|
||||
if err := os.Remove(socket); err != nil && !os.IsNotExist(err) {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("socket", socket).
|
||||
Msg("Failed to remove debug server socket")
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().
|
||||
Err(reason).
|
||||
Msg("Shutdown debug server gracefully")
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
server := &http.Server{
|
||||
Addr: viper.GetString("http.addr"),
|
||||
Handler: server.Router(
|
||||
server.WithRoot(viper.GetString("http.root")),
|
||||
server.WithPath(viper.GetString("asset.path")),
|
||||
server.WithConfig(viper.GetString("config.file")),
|
||||
),
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
server, err := debug.Server(
|
||||
debug.Logger(logger),
|
||||
debug.Context(ctx),
|
||||
debug.Config(cfg),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Info().
|
||||
Err(err).
|
||||
Str("transport", "debug").
|
||||
Msg("Failed to initialize server")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
gr.Add(func() error {
|
||||
log.Info().
|
||||
Str("addr", viper.GetString("http.addr")).
|
||||
Msg("Starting http server")
|
||||
|
||||
if strings.HasPrefix(viper.GetString("http.addr"), "unix://") {
|
||||
socket := strings.TrimPrefix(viper.GetString("http.addr"), "unix://")
|
||||
|
||||
if err := os.Remove(socket); err != nil && !os.IsNotExist(err) {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("socket", socket).
|
||||
Msg("Failed to remove existing http socket")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
listener, err := net.ListenUnix(
|
||||
"unix",
|
||||
&net.UnixAddr{
|
||||
Name: socket,
|
||||
Net: "unix",
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Msg("Failed to initialize http unix socket")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.Chmod(socket, os.FileMode(0666)); err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Msg("Failed to change http socket permissions")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return server.Serve(listener)
|
||||
}
|
||||
|
||||
return server.ListenAndServe()
|
||||
}, func(reason error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
}, func(_ error) {
|
||||
ctx, timeout := context.WithTimeout(ctx, 5*time.Second)
|
||||
|
||||
defer timeout()
|
||||
defer cancel()
|
||||
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
log.Error().
|
||||
logger.Info().
|
||||
Err(err).
|
||||
Msg("Failed to shutdown http server gracefully")
|
||||
|
||||
return
|
||||
Str("transport", "debug").
|
||||
Msg("Failed to shutdown server")
|
||||
} else {
|
||||
logger.Info().
|
||||
Str("transport", "debug").
|
||||
Msg("Shutting down server")
|
||||
}
|
||||
|
||||
if strings.HasPrefix(viper.GetString("http.addr"), "unix://") {
|
||||
socket := strings.TrimPrefix(viper.GetString("http.addr"), "unix://")
|
||||
|
||||
if err := os.Remove(socket); err != nil && !os.IsNotExist(err) {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("socket", socket).
|
||||
Msg("Failed to remove http server socket")
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().
|
||||
Err(reason).
|
||||
Msg("Shutdown http server gracefully")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -208,40 +199,11 @@ func Server() *cobra.Command {
|
||||
return nil
|
||||
}, func(err error) {
|
||||
close(stop)
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
|
||||
return gr.Run()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().String("debug-addr", "", "Address to bind debug server")
|
||||
viper.BindPFlag("debug.addr", cmd.Flags().Lookup("debug-addr"))
|
||||
viper.BindEnv("debug.addr", "PHOENIX_DEBUG_ADDR")
|
||||
|
||||
cmd.Flags().String("debug-token", "", "Token to grant metrics access")
|
||||
viper.BindPFlag("debug.token", cmd.Flags().Lookup("debug-token"))
|
||||
viper.BindEnv("debug.token", "PHOENIX_DEBUG_TOKEN")
|
||||
|
||||
cmd.Flags().Bool("debug-pprof", false, "Enable pprof debugging")
|
||||
viper.BindPFlag("debug.pprof", cmd.Flags().Lookup("debug-pprof"))
|
||||
viper.BindEnv("debug.pprof", "PHOENIX_DEBUG_PPROF")
|
||||
|
||||
cmd.Flags().String("http-addr", "", "Address to bind http server")
|
||||
viper.BindPFlag("http.addr", cmd.Flags().Lookup("http-addr"))
|
||||
viper.BindEnv("http.addr", "PHOENIX_HTTP_ADDR")
|
||||
|
||||
cmd.Flags().String("http-root", "", "Root path for http endpoint")
|
||||
viper.BindPFlag("http.root", cmd.Flags().Lookup("http-root"))
|
||||
viper.BindEnv("http.root", "PHOENIX_HTTP_ROOT")
|
||||
|
||||
cmd.Flags().String("asset-path", "", "Path to custom assets")
|
||||
viper.BindPFlag("asset.path", cmd.Flags().Lookup("asset-path"))
|
||||
viper.BindEnv("asset.path", "PHOENIX_ASSET_PATH")
|
||||
|
||||
cmd.Flags().String("config-file", "", "Path to phoenix config")
|
||||
viper.BindPFlag("config.file", cmd.Flags().Lookup("config-file"))
|
||||
viper.BindEnv("config.file", "PHOENIX_CONFIG_FILE")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestServer(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package config
|
||||
|
||||
// Log defines the available logging configuration.
|
||||
type Log struct {
|
||||
Level string
|
||||
Pretty bool
|
||||
Color bool
|
||||
}
|
||||
|
||||
// Debug defines the available debug configuration.
|
||||
type Debug struct {
|
||||
Addr string
|
||||
Token string
|
||||
Pprof bool
|
||||
Zpages bool
|
||||
}
|
||||
|
||||
// HTTP defines the available http configuration.
|
||||
type HTTP struct {
|
||||
Addr string
|
||||
}
|
||||
|
||||
// Tracing defines the available tracing configuration.
|
||||
type Tracing struct {
|
||||
Enabled bool
|
||||
Type string
|
||||
Endpoint string
|
||||
Collector string
|
||||
Service string
|
||||
}
|
||||
|
||||
// Asset defines the available asset configuration.
|
||||
type Asset struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
// Phoenix defines the available phoenic configuration.
|
||||
type Phoenix struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
// Config combines all available configuration parts.
|
||||
type Config struct {
|
||||
File string
|
||||
Log Log
|
||||
Debug Debug
|
||||
HTTP HTTP
|
||||
Tracing Tracing
|
||||
Asset Asset
|
||||
Phoenix Phoenix
|
||||
}
|
||||
|
||||
// New initializes a new configuration with or without defaults.
|
||||
func New() *Config {
|
||||
return &Config{}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package flagset
|
||||
|
||||
import (
|
||||
"github.com/micro/cli"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
)
|
||||
|
||||
// RootWithConfig applies cfg to the root flagset
|
||||
func RootWithConfig(cfg *config.Config) []cli.Flag {
|
||||
return []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "config-file",
|
||||
Value: "",
|
||||
Usage: "Path to config file",
|
||||
EnvVar: "PHOENIX_CONFIG_FILE",
|
||||
Destination: &cfg.File,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "log-level",
|
||||
Value: "info",
|
||||
Usage: "Set logging level",
|
||||
EnvVar: "PHOENIX_LOG_LEVEL",
|
||||
Destination: &cfg.Log.Level,
|
||||
},
|
||||
&cli.BoolTFlag{
|
||||
Name: "log-pretty",
|
||||
Usage: "Enable pretty logging",
|
||||
EnvVar: "PHOENIX_LOG_PRETTY",
|
||||
Destination: &cfg.Log.Pretty,
|
||||
},
|
||||
&cli.BoolTFlag{
|
||||
Name: "log-color",
|
||||
Usage: "Enable colored logging",
|
||||
EnvVar: "PHOENIX_LOG_COLOR",
|
||||
Destination: &cfg.Log.Color,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// HealthWithConfig applies cfg to the root flagset
|
||||
func HealthWithConfig(cfg *config.Config) []cli.Flag {
|
||||
return []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "debug-addr",
|
||||
Value: "0.0.0.0:9104",
|
||||
Usage: "Address to debug endpoint",
|
||||
EnvVar: "PHOENIX_DEBUG_ADDR",
|
||||
Destination: &cfg.Debug.Addr,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ServerWithConfig applies cfg to the root flagset
|
||||
func ServerWithConfig(cfg *config.Config) []cli.Flag {
|
||||
return []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "tracing-enabled",
|
||||
Usage: "Enable sending traces",
|
||||
EnvVar: "PHOENIX_TRACING_ENABLED",
|
||||
Destination: &cfg.Tracing.Enabled,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tracing-type",
|
||||
Value: "jaeger",
|
||||
Usage: "Tracing backend type",
|
||||
EnvVar: "PHOENIX_TRACING_TYPE",
|
||||
Destination: &cfg.Tracing.Type,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tracing-endpoint",
|
||||
Value: "",
|
||||
Usage: "Endpoint for the agent",
|
||||
EnvVar: "PHOENIX_TRACING_ENDPOINT",
|
||||
Destination: &cfg.Tracing.Endpoint,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tracing-collector",
|
||||
Value: "",
|
||||
Usage: "Endpoint for the collector",
|
||||
EnvVar: "PHOENIX_TRACING_COLLECTOR",
|
||||
Destination: &cfg.Tracing.Collector,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tracing-service",
|
||||
Value: "phoenix",
|
||||
Usage: "Service name for tracing",
|
||||
EnvVar: "PHOENIX_TRACING_SERVICE",
|
||||
Destination: &cfg.Tracing.Service,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "debug-addr",
|
||||
Value: "0.0.0.0:9104",
|
||||
Usage: "Address to bind debug server",
|
||||
EnvVar: "PHOENIX_DEBUG_ADDR",
|
||||
Destination: &cfg.Debug.Addr,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "debug-token",
|
||||
Value: "",
|
||||
Usage: "Token to grant metrics access",
|
||||
EnvVar: "PHOENIX_DEBUG_TOKEN",
|
||||
Destination: &cfg.Debug.Token,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "debug-pprof",
|
||||
Usage: "Enable pprof debugging",
|
||||
EnvVar: "PHOENIX_DEBUG_PPROF",
|
||||
Destination: &cfg.Debug.Pprof,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "debug-zpages",
|
||||
Usage: "Enable zpages debugging",
|
||||
EnvVar: "PHOENIX_DEBUG_ZPAGES",
|
||||
Destination: &cfg.Debug.Zpages,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "http-addr",
|
||||
Value: "0.0.0.0:9100",
|
||||
Usage: "Address to bind http server",
|
||||
EnvVar: "PHOENIX_HTTP_ADDR",
|
||||
Destination: &cfg.HTTP.Addr,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "asset-path",
|
||||
Value: "",
|
||||
Usage: "Path to custom assets",
|
||||
EnvVar: "PHOENIX_ASSET_PATH",
|
||||
Destination: &cfg.Asset.Path,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "web-config",
|
||||
Value: "",
|
||||
Usage: "Path to phoenix config",
|
||||
EnvVar: "PHOENIX_WEB_CONFIG",
|
||||
Destination: &cfg.Phoenix.Path,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrConfigInvalid is returned when the config parse is invalid.
|
||||
ErrConfigInvalid = `Invalid or missing config`
|
||||
)
|
||||
|
||||
// config gets initialized by New and provides the handler.
|
||||
type config struct {
|
||||
file string
|
||||
}
|
||||
|
||||
// ServeHTTP just implements the http.Handler interface.
|
||||
func (c config) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if _, err := os.Stat(c.file); os.IsNotExist(err) {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("config", c.file).
|
||||
Msg("Phoenix config doesn't exist")
|
||||
|
||||
http.Error(w, ErrConfigInvalid, http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
payload, err := ioutil.ReadFile(c.file)
|
||||
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("config", c.file).
|
||||
Msg("Failed to read custom config")
|
||||
|
||||
http.Error(w, ErrConfigInvalid, http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(payload)
|
||||
}
|
||||
|
||||
// Handler returns the handler for config endpoint.
|
||||
func Handler(opts ...Option) http.Handler {
|
||||
c := new(config)
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(c)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConfig(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package config
|
||||
|
||||
// Option configures an assets option.
|
||||
type Option func(*config)
|
||||
|
||||
// WithConfig returns an option to set config.
|
||||
func WithConfig(val string) Option {
|
||||
return func(c *config) {
|
||||
c.file = val
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidToken is returned when the request token is invalid.
|
||||
ErrInvalidToken = `Invalid or missing token`
|
||||
)
|
||||
|
||||
// metrics gets initialized by New and provides the handler.
|
||||
type metrics struct {
|
||||
token string
|
||||
}
|
||||
|
||||
// ServeHTTP just implements the http.Handler interface.
|
||||
func (m metrics) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if m.token == "" {
|
||||
promhttp.Handler().ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
header := r.Header.Get("Authorization")
|
||||
|
||||
if header == "" {
|
||||
log.Debug().
|
||||
Msg("Missing auth header")
|
||||
|
||||
http.Error(w, ErrInvalidToken, http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
if header != fmt.Sprintf("Bearer %s", m.token) {
|
||||
log.Debug().
|
||||
Msg("Invalid token provided")
|
||||
|
||||
http.Error(w, ErrInvalidToken, http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
promhttp.Handler().ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// Handler returns the handler for metrics endpoint.
|
||||
func Handler(opts ...Option) http.Handler {
|
||||
m := new(metrics)
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(m)
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMetrics(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package metrics
|
||||
|
||||
// Option configures an assets option.
|
||||
type Option func(*metrics)
|
||||
|
||||
// WithToken returns an option to set a token.
|
||||
func WithToken(val string) Option {
|
||||
return func(m *metrics) {
|
||||
m.token = val
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package static
|
||||
|
||||
// Option configures an assets option.
|
||||
type Option func(*static)
|
||||
|
||||
// WithRoot returns an option to set a root.
|
||||
func WithRoot(val string) Option {
|
||||
return func(s *static) {
|
||||
s.root = val
|
||||
}
|
||||
}
|
||||
|
||||
// WithPath returns an option to set a path.
|
||||
func WithPath(val string) Option {
|
||||
return func(s *static) {
|
||||
s.path = val
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis-phoenix/pkg/assets"
|
||||
)
|
||||
|
||||
// static gets initialized by New and provides the handler.
|
||||
type static struct {
|
||||
root string
|
||||
path string
|
||||
|
||||
handler http.Handler
|
||||
}
|
||||
|
||||
// ServeHTTP just implements the http.Handler interface.
|
||||
func (s static) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
s.handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// Handler returns the handler for static endpoint.
|
||||
func Handler(opts ...Option) http.Handler {
|
||||
s := new(static)
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(s)
|
||||
}
|
||||
|
||||
s.handler = http.StripPrefix(
|
||||
s.root,
|
||||
http.FileServer(
|
||||
assets.New(
|
||||
assets.WithPath(s.path),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStatic(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package metrics
|
||||
|
||||
var (
|
||||
// Namespace defines the namespace for the defines metrics.
|
||||
Namespace = "ocis"
|
||||
|
||||
// Subsystem defines the subsystem for the defines metrics.
|
||||
Subsystem = "phoenix"
|
||||
)
|
||||
|
||||
// Metrics defines the available metrics of this service.
|
||||
type Metrics struct {
|
||||
// Counter *prometheus.CounterVec
|
||||
}
|
||||
|
||||
// New initializes the available metrics.
|
||||
func New() *Metrics {
|
||||
m := &Metrics{
|
||||
// Counter: prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
// Namespace: Namespace,
|
||||
// Subsystem: Subsystem,
|
||||
// Name: "greet_total",
|
||||
// Help: "How many greeting requests processed",
|
||||
// }, []string{}),
|
||||
}
|
||||
|
||||
// prometheus.Register(
|
||||
// m.Counter,
|
||||
// )
|
||||
|
||||
return m
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package header
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/owncloud/ocis-phoenix/pkg/version"
|
||||
)
|
||||
|
||||
// Cache writes required cache headers to all requests.
|
||||
func Cache(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate, value")
|
||||
w.Header().Set("Expires", "Thu, 01 Jan 1970 00:00:00 GMT")
|
||||
w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// Options writes required option headers to all requests.
|
||||
func Options(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "OPTIONS" {
|
||||
next.ServeHTTP(w, r)
|
||||
} else {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
|
||||
w.Header().Set("Access-Control-Allow-Headers", "authorization, origin, content-type, accept")
|
||||
w.Header().Set("Allow", "HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS")
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Secure writes required access headers to all requests.
|
||||
func Secure(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("X-Frame-Options", "DENY")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Set("X-XSS-Protection", "1; mode=block")
|
||||
|
||||
if r.TLS != nil {
|
||||
w.Header().Set("Strict-Transport-Security", "max-age=31536000")
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// Version writes the current version to the headers.
|
||||
func Version(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("X-PHOENIX-VERSION", version.String)
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package header
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHeader(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/handler/metrics"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/middleware/header"
|
||||
"github.com/rs/zerolog/hlog"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// debug gets initialized by Router and configures the router.
|
||||
type debug struct {
|
||||
token string
|
||||
pprof bool
|
||||
}
|
||||
|
||||
// Router initializes a router for the debug server.
|
||||
func Router(opts ...Option) *chi.Mux {
|
||||
d := new(debug)
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(d)
|
||||
}
|
||||
|
||||
mux := chi.NewRouter()
|
||||
|
||||
mux.Use(hlog.NewHandler(log.Logger))
|
||||
mux.Use(hlog.RemoteAddrHandler("ip"))
|
||||
mux.Use(hlog.URLHandler("path"))
|
||||
mux.Use(hlog.MethodHandler("method"))
|
||||
mux.Use(hlog.RequestIDHandler("request_id", "Request-Id"))
|
||||
|
||||
mux.Use(middleware.RealIP)
|
||||
mux.Use(header.Version)
|
||||
mux.Use(header.Cache)
|
||||
mux.Use(header.Secure)
|
||||
mux.Use(header.Options)
|
||||
|
||||
mux.Route("/", func(root chi.Router) {
|
||||
if d.pprof {
|
||||
root.Mount(
|
||||
"/debug",
|
||||
middleware.Profiler(),
|
||||
)
|
||||
}
|
||||
|
||||
root.Mount(
|
||||
"/metrics",
|
||||
metrics.Handler(
|
||||
metrics.WithToken(d.token),
|
||||
),
|
||||
)
|
||||
|
||||
root.Get("/healthz", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
io.WriteString(w, http.StatusText(http.StatusOK))
|
||||
})
|
||||
|
||||
root.Get("/readyz", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
io.WriteString(w, http.StatusText(http.StatusOK))
|
||||
})
|
||||
})
|
||||
|
||||
return mux
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDebug(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package debug
|
||||
|
||||
// Option configures an assets option.
|
||||
type Option func(*debug)
|
||||
|
||||
// WithToken returns an option to set a token.
|
||||
func WithToken(val string) Option {
|
||||
return func(d *debug) {
|
||||
d.token = val
|
||||
}
|
||||
}
|
||||
|
||||
// WithPprof returns an option to enable pprof.
|
||||
func WithPprof(val bool) Option {
|
||||
return func(d *debug) {
|
||||
d.pprof = val
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package server
|
||||
|
||||
// Option configures an assets option.
|
||||
type Option func(*server)
|
||||
|
||||
// WithRoot returns an option to set root.
|
||||
func WithRoot(val string) Option {
|
||||
return func(s *server) {
|
||||
s.root = val
|
||||
}
|
||||
}
|
||||
|
||||
// WithPath returns an option to set path.
|
||||
func WithPath(val string) Option {
|
||||
return func(s *server) {
|
||||
s.path = val
|
||||
}
|
||||
}
|
||||
|
||||
// WithConfig returns an option to set config.
|
||||
func WithConfig(val string) Option {
|
||||
return func(s *server) {
|
||||
s.config = val
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/handler/config"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/handler/static"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/middleware/header"
|
||||
"github.com/rs/zerolog/hlog"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// server gets initialized by Router and configures the router.
|
||||
type server struct {
|
||||
root string
|
||||
path string
|
||||
config string
|
||||
}
|
||||
|
||||
// Router initializes a router for the http server.
|
||||
func Router(opts ...Option) *chi.Mux {
|
||||
s := new(server)
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(s)
|
||||
}
|
||||
|
||||
mux := chi.NewRouter()
|
||||
|
||||
mux.Use(hlog.NewHandler(log.Logger))
|
||||
mux.Use(hlog.RemoteAddrHandler("ip"))
|
||||
mux.Use(hlog.URLHandler("path"))
|
||||
mux.Use(hlog.MethodHandler("method"))
|
||||
mux.Use(hlog.RequestIDHandler("request_id", "Request-Id"))
|
||||
|
||||
mux.Use(hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
|
||||
hlog.FromRequest(r).Debug().
|
||||
Str("method", r.Method).
|
||||
Str("url", r.URL.String()).
|
||||
Int("status", status).
|
||||
Int("size", size).
|
||||
Dur("duration", duration).
|
||||
Msg("")
|
||||
}))
|
||||
|
||||
mux.Use(middleware.RealIP)
|
||||
mux.Use(header.Version)
|
||||
mux.Use(header.Cache)
|
||||
mux.Use(header.Secure)
|
||||
mux.Use(header.Options)
|
||||
|
||||
mux.Route(s.root, func(root chi.Router) {
|
||||
root.Mount(
|
||||
"/config.json",
|
||||
config.Handler(
|
||||
config.WithConfig(s.config),
|
||||
),
|
||||
)
|
||||
|
||||
root.Mount(
|
||||
"/",
|
||||
static.Handler(
|
||||
static.WithRoot(s.root),
|
||||
static.WithPath(s.path),
|
||||
),
|
||||
)
|
||||
})
|
||||
|
||||
return mux
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestServer(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
Context context.Context
|
||||
Config *config.Config
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(val log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = val
|
||||
}
|
||||
}
|
||||
|
||||
// Context provides a function to set the context option.
|
||||
func Context(val context.Context) Option {
|
||||
return func(o *Options) {
|
||||
o.Context = val
|
||||
}
|
||||
}
|
||||
|
||||
// Config provides a function to set the config option.
|
||||
func Config(val *config.Config) Option {
|
||||
return func(o *Options) {
|
||||
o.Config = val
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/version"
|
||||
"github.com/owncloud/ocis-pkg/service/debug"
|
||||
)
|
||||
|
||||
// Server initializes the debug service and server.
|
||||
func Server(opts ...Option) (*http.Server, error) {
|
||||
options := newOptions(opts...)
|
||||
|
||||
return debug.NewService(
|
||||
debug.Logger(options.Logger),
|
||||
debug.Name("phoenix"),
|
||||
debug.Version(version.String),
|
||||
debug.Address(options.Config.Debug.Addr),
|
||||
debug.Token(options.Config.Debug.Token),
|
||||
debug.Pprof(options.Config.Debug.Pprof),
|
||||
debug.Zpages(options.Config.Debug.Zpages),
|
||||
debug.Health(health(options.Config)),
|
||||
debug.Ready(ready(options.Config)),
|
||||
), nil
|
||||
}
|
||||
|
||||
// health implements the health check.
|
||||
func health(cfg *config.Config) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
// TODO(tboerger): check if services are up and running
|
||||
|
||||
io.WriteString(w, http.StatusText(http.StatusOK))
|
||||
}
|
||||
}
|
||||
|
||||
// ready implements the ready check.
|
||||
func ready(cfg *config.Config) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
// TODO(tboerger): check if services are up and running
|
||||
|
||||
io.WriteString(w, http.StatusText(http.StatusOK))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/metrics"
|
||||
"github.com/owncloud/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
Context context.Context
|
||||
Config *config.Config
|
||||
Metrics *metrics.Metrics
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(val log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = val
|
||||
}
|
||||
}
|
||||
|
||||
// Context provides a function to set the context option.
|
||||
func Context(val context.Context) Option {
|
||||
return func(o *Options) {
|
||||
o.Context = val
|
||||
}
|
||||
}
|
||||
|
||||
// Config provides a function to set the config option.
|
||||
func Config(val *config.Config) Option {
|
||||
return func(o *Options) {
|
||||
o.Config = val
|
||||
}
|
||||
}
|
||||
|
||||
// Metrics provides a function to set the metrics option.
|
||||
func Metrics(val *metrics.Metrics) Option {
|
||||
return func(o *Options) {
|
||||
o.Metrics = val
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis-phoenix/pkg/assets"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/flagset"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/service/v0"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/version"
|
||||
"github.com/owncloud/ocis-pkg/middleware"
|
||||
"github.com/owncloud/ocis-pkg/service/http"
|
||||
)
|
||||
|
||||
// Server initializes the http service and server.
|
||||
func Server(opts ...Option) (http.Service, error) {
|
||||
options := newOptions(opts...)
|
||||
|
||||
service := http.NewService(
|
||||
http.Logger(options.Logger),
|
||||
http.Namespace("go.micro.web"),
|
||||
http.Name("phoenix"),
|
||||
http.Version(version.String),
|
||||
http.Address(options.Config.HTTP.Addr),
|
||||
http.Context(options.Context),
|
||||
http.Flags(flagset.RootWithConfig(config.New())...),
|
||||
http.Flags(flagset.ServerWithConfig(config.New())...),
|
||||
)
|
||||
|
||||
handle := svc.NewService(
|
||||
svc.Logger(options.Logger),
|
||||
svc.Config(options.Config),
|
||||
svc.Middleware(
|
||||
middleware.RealIP,
|
||||
middleware.RequestID,
|
||||
middleware.Cache,
|
||||
middleware.Cors,
|
||||
middleware.Secure,
|
||||
middleware.Version(
|
||||
"phoenix",
|
||||
version.String,
|
||||
),
|
||||
middleware.Logger(
|
||||
options.Logger,
|
||||
),
|
||||
middleware.Static(
|
||||
assets.New(
|
||||
assets.Logger(options.Logger),
|
||||
assets.Config(options.Config),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
{
|
||||
handle = svc.NewInstrument(handle, options.Metrics)
|
||||
handle = svc.NewLogging(handle, options.Logger)
|
||||
handle = svc.NewTracing(handle)
|
||||
}
|
||||
|
||||
service.Handle(
|
||||
"/",
|
||||
handle,
|
||||
)
|
||||
|
||||
service.Init()
|
||||
return service, nil
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis-phoenix/pkg/metrics"
|
||||
)
|
||||
|
||||
// NewInstrument returns a service that instruments metrics.
|
||||
func NewInstrument(next Service, metrics *metrics.Metrics) Service {
|
||||
return instrument{
|
||||
next: next,
|
||||
metrics: metrics,
|
||||
}
|
||||
}
|
||||
|
||||
type instrument struct {
|
||||
next Service
|
||||
metrics *metrics.Metrics
|
||||
}
|
||||
|
||||
// ServeHTTP implements the Service interface.
|
||||
func (i instrument) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
i.next.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// Config implements the Service interface.
|
||||
func (i instrument) Config(w http.ResponseWriter, r *http.Request) {
|
||||
i.next.Config(w, r)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// NewLogging returns a service that logs messages.
|
||||
func NewLogging(next Service, logger log.Logger) Service {
|
||||
return logging{
|
||||
next: next,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
type logging struct {
|
||||
next Service
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// ServeHTTP implements the Service interface.
|
||||
func (l logging) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
l.next.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// Config implements the Service interface.
|
||||
func (l logging) Config(w http.ResponseWriter, r *http.Request) {
|
||||
l.next.Config(w, r)
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
Config *config.Config
|
||||
Middleware []func(http.Handler) http.Handler
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(val log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = val
|
||||
}
|
||||
}
|
||||
|
||||
// Config provides a function to set the config option.
|
||||
func Config(val *config.Config) Option {
|
||||
return func(o *Options) {
|
||||
o.Config = val
|
||||
}
|
||||
}
|
||||
|
||||
// Middleware provides a function to set the middleware option.
|
||||
func Middleware(val ...func(http.Handler) http.Handler) Option {
|
||||
return func(o *Options) {
|
||||
o.Middleware = val
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/owncloud/ocis-phoenix/pkg/config"
|
||||
"github.com/owncloud/ocis-pkg/log"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrConfigInvalid is returned when the config parse is invalid.
|
||||
ErrConfigInvalid = `Invalid or missing config`
|
||||
)
|
||||
|
||||
// Service defines the extension handlers.
|
||||
type Service interface {
|
||||
ServeHTTP(http.ResponseWriter, *http.Request)
|
||||
Config(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// NewService returns a service implementation for Service.
|
||||
func NewService(opts ...Option) Service {
|
||||
options := newOptions(opts...)
|
||||
|
||||
m := chi.NewMux()
|
||||
m.Use(options.Middleware...)
|
||||
|
||||
svc := Phoenix{
|
||||
config: options.Config,
|
||||
mux: m,
|
||||
}
|
||||
|
||||
m.HandleFunc("/config.json", svc.Config)
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// Phoenix defines implements the business logic for Service.
|
||||
type Phoenix struct {
|
||||
logger log.Logger
|
||||
config *config.Config
|
||||
mux *chi.Mux
|
||||
}
|
||||
|
||||
// ServeHTTP implements the Service interface.
|
||||
func (g Phoenix) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
g.mux.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// Config implements the Service interface.
|
||||
func (g Phoenix) Config(w http.ResponseWriter, r *http.Request) {
|
||||
if _, err := os.Stat(g.config.Phoenix.Path); os.IsNotExist(err) {
|
||||
g.logger.Error().
|
||||
Err(err).
|
||||
Str("config", g.config.Phoenix.Path).
|
||||
Msg("Phoenix config doesn't exist")
|
||||
|
||||
http.Error(w, ErrConfigInvalid, http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
payload, err := ioutil.ReadFile(g.config.Phoenix.Path)
|
||||
|
||||
if err != nil {
|
||||
g.logger.Error().
|
||||
Err(err).
|
||||
Str("config", g.config.Phoenix.Path).
|
||||
Msg("Failed to read custom config")
|
||||
|
||||
http.Error(w, ErrConfigInvalid, http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(payload)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// NewTracing returns a service that instruments traces.
|
||||
func NewTracing(next Service) Service {
|
||||
return tracing{
|
||||
next: next,
|
||||
}
|
||||
}
|
||||
|
||||
type tracing struct {
|
||||
next Service
|
||||
}
|
||||
|
||||
// ServeHTTP implements the Service interface.
|
||||
func (t tracing) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
t.next.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// Config implements the Service interface.
|
||||
func (t tracing) Config(w http.ResponseWriter, r *http.Request) {
|
||||
t.next.Config(w, r)
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// String gets defined by the build system.
|
||||
String = "0.0.0"
|
||||
@@ -7,3 +11,9 @@ var (
|
||||
// Date indicates the build date.
|
||||
Date = "00000000"
|
||||
)
|
||||
|
||||
// Compiled returns the compile time of this service.
|
||||
func Compiled() time.Time {
|
||||
t, _ := time.Parse("20060102", Date)
|
||||
return t
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# backend
|
||||
-r '^(cmd|pkg)/.*\.go$' -R '^node_modules/' -s -- sh -c 'make bin/ocis-phoenix-debug && bin/ocis-phoenix-debug --log-level debug server --debug-pprof --debug-zpages --asset-path assets/'
|
||||
Reference in New Issue
Block a user