diff --git a/.gitignore b/.gitignore index 66fd13c..97bd46e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,10 @@ # Dependency directories (remove the comment below to include it) # vendor/ + + +# Generated code from OpenAPI +examples/src/powershell/microservice/api/rediops-service-server.gen.go +examples/src/powershell/microservice/api/rediops-service-types.gen.go +examples/src/powershell/microservice/data/* +examples/src/powershell/microservice/config/devops.json diff --git a/.well-known/devops.json b/.well-known/devops.json index 7651d28..612c2c9 100644 --- a/.well-known/devops.json +++ b/.well-known/devops.json @@ -1,66 +1,83 @@ { + "unique_id": "d2429b4f-394b-498b-88ff-33ce28751188", "version": "0.0.1", - "created_on": "2022-08-07T13:43:21Z", - "updated_on": "2022-08-07T13:43:21Z", - "organisation": "Meerkat Manor", - - "name": "Web site", + "created_on": "2022-03-04T15:43:21Z", + "updated_on": "2022-03-04T15:43:21Z", + "organisation": "Meerkat Manor Tech College", + "name": "Microservce and web site", + "asset": { + "id": "AID07828923", + "name": "website", + "url": "" + }, "owner": { - "email": "meerkat@merebox.com", - "web": "https://www.merebox.com", - "matrix":"@devops:merebox.com" + "email": "devops@meerkatmanor-tech.org", + "web": "meerkatmanor-tech.org", + "slack": "", + "twitter": "", + "matrix": "@devops:meerkat-manor.org" }, "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/overview.md", - "repository": { - "guide": "https://github.com/meerkat-manor/rediOps", - "source-engine": "Git", - "source": "https://github.com/meerkat-manor/rediOps.git", - "artefact": "" + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/repository.md", + "artefact": { + "category": "ARTEFACT", + "name": "docker", + "url": "" + }, + "source": { + "category": "SOURCE", + "name": "git", + "url": "https://github.com/meerkat-manor/rediOps" + } }, - "dependency": { "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/dependency.md", - "apis": [], - "tools": [] - }, - - "build": { - "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/build.md", - "engine": "JENKINS" - }, - - - "test": { - "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/test.md", - "engine": "UNITTEST" - }, - - "api" : [ - { - "engine": "GIT", - "url": "/specification/rediops.json" - }, - { - "engine": "GIT", - "url": "/specification/rediops.yaml" - }, - { - "engine": "REST", - "url": "/api/v0/docs/rediops.json" - } - ], - - "health": { - "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/health.md", - "api" :[ - {"url": "/health", "status": 200, "response": ""} + "apis": [ + ], + "tools": [ + ] + }, + "build": [ + { + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/build.md", + "engine": { + "category": "UNINSTALL", + "name": "some text", + "url": "some text" + }, + "config": "some text", + "script": "some text" + } + ], + "test": [ + { + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/test.md", + "engine": { + "category": "SOURCE", + "name": "some text", + "url": "some text" + }, + "config": "some text", + "script": "some text" + } + ], + "health": { + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/health.md", + "api": [ + { + "url": "/health", + "status": 200, + "response": "OK" + } ] }, - "install": { "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/install.md", - "engine": "COMMAND", + "engine": { + "category": "COMMAND", + "name": "bash" + }, "playbook": "", "commands": { "pre": [ @@ -70,27 +87,52 @@ ] } }, - "refresh": { "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/refresh.md", - "engine": "COMMAND", + "engine": { + "category": "COMMAND", + "name": "bash" + }, "playbook": "", "commands": { - "pre": [], + "pre": [ + ], "script": "/deploy/refresh.sh", - "post": [] + "post": [ + ] } }, - "uninstall": { "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/uninstall.md", - "engine": "ANSIBLE", + "engine": { + "category": "COMMAND", + "name": "bash" + }, "playbook": "", "commands": { - "pre": [], + "pre": [ + ], "script": "/deploy/decommission.sh", - "post": [] + "post": [ + ] } - } - + }, + "apis": [ + { + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/api.md", + "engine": { + "category": "API", + "name": "openapi", + "url": "/specification/rediops.json" + } + }, + { + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/api.md", + "engine": { + "category": "API", + "name": "openapi", + "url": "/specification/rediops.yaml" + } + } + ] } \ No newline at end of file diff --git a/README.md b/README.md index ecc325f..ea4a8be 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,16 @@ # rediOps -Rediscover DevOps is about standardising how to find information about the code, specifically for use in the DevOps pipeline and -for engineers to locate relavant information about the code and its capability and DevOps process. +Rediscover DevOps (rediOps) is about standardising how to find information about the code, specifically +for use in the DevOps pipeline and for engineers to locate relavant information about the code and +its capability and DevOps process. -The information resides with the code in the code repository, commonly Git, and is human readable and also understood by tools. +The information resides with the code in the code repository, commonly Git, and is human readable +and also understood by tools. -RediOps takes the lead from the the **.well-known** folder approach used in web pages for source. +RediOps takes the lead from the the [**.well-known** folder](https://en.wikipedia.org/wiki/Well-known_URI) +approach used in web servers. That is the creation of a folder named ".well-known" and to create a file by the name of -**"devops.json"** within the folder in source. This will allow tools to retrieve the file if it exists +**"devops.json"** within the folder. This will allow tools to retrieve the file if it exists and to use the information for activities such as: * build @@ -25,25 +28,33 @@ for other files or actions to perform. ## Specification -The specification for the **devops.json** is defined as an OpenAPI document allowing the publishing -of the information also as a REST service if so required - though this is not mandatory - and -the "devops.json" file is expected to exist before the code is deployed. +The specification for the **devops.json** is defined as an [OpenAPI document](specification/rediops.json). The use of OpenAPI to define the details specification provides a format and protocol that can be understood -by tools and engineers. There a few aspects of the specifications that cannot be documented in OpenAPI. +by tools and engineers. + +Using a OpenAPI specification provides clarity on definition. Tools can also generate a +REST service if so required - though this is not mandatory - and +the "devops.json" file is expected to exist before the code is deployed. If you do publish the information as a REST service then you should consider protecting access to the data, especially if it contains data that may expose internal structures. **Note:** The specification does not capture credentials or runtime environment information. -## Audience +To read more see [overview](guide/overview.md) or +go to [tutorial](tutorial/readme.md) or +[examples](examples/readme.md) -If your organisation already has standrad automation tools and pipeline process, then you may not find the RediOps -and the specifications that useful. +## Audience You may find the specification useful if: -1. You are a small developer with custom tools or simple requirements -2. Your organisation has many different tools for different repositories and you need to document which tool goes with what +1. You don't have a standard and make assumptions about meta data file names in your Git repository +2. You are a small developer with custom tools or simple requirements +3. Your organisation has many different tools for different repositories and you need to document which tool goes with what + +If your organisation already has standard automation tools and pipeline process, then you may not find the rediOps +and the specifications that useful. If the specification is not relevant in its entirety, maybe you find the +concept or portions useful for adaptation in your organisation. diff --git a/examples/readme.md b/examples/readme.md new file mode 100644 index 0000000..3b359d2 --- /dev/null +++ b/examples/readme.md @@ -0,0 +1,25 @@ +# Examples + +The examples provided are opinionated and may not be a fit for you. + +The code is not optimised and is only intended to present +more concrete examples of various use cases. + + +## Refresh an executing docker image + +Build a static web server and refresh the existing +executing static web server. + +* Code is located at [deploy.ps1](src/powershell/static/deploy.ps1) +* Tutorial is located at [staticweb](../guide/tutorial/staticweb.md) + +## Generate Go web service code + +Using a OpenAPI specification for a service, this example +generates the server and type code. The example uses the **rediops.json** definition itself +to generate the server code. + + +* Code is located at [deploy.ps1](src/powershell/microsservice/deploy.ps1) +* Tutorial is located at [microservice](../guide/tutorial/microservice.md) \ No newline at end of file diff --git a/examples/src/powershell/microservice/api/rediops-service.go b/examples/src/powershell/microservice/api/rediops-service.go new file mode 100644 index 0000000..ab0beb0 --- /dev/null +++ b/examples/src/powershell/microservice/api/rediops-service.go @@ -0,0 +1,214 @@ +package api + + +import ( + "net/http" + "sync" + "os" + "io/ioutil" + "log" + "encoding/json" + + "github.com/labstack/echo/v4" +) + + +type Rediops struct { + Lock sync.Mutex + ConfigFilename string + DataFolder string + ConfigFolder string +} + +func NewRediops(configFolder string, configFilename string, dataFolder string) *Rediops { + + return &Rediops{ + ConfigFolder: configFolder, + ConfigFilename: configFilename, + DataFolder: dataFolder, + } +} + + +// A common error payload returned +// when the response code is not 2xx +type ErrorModel struct { + // Error description, that shuld be less technical + // and more user orientated where possible + Message *string `json:"message,omitempty"` + Resolution *string `json:"resolution,omitempty"` + + // Status code as a string + Status *string `json:"status,omitempty"` + + // Numerical value of the status code + StatusCode *int `json:"statusCode,omitempty"` + + // Technical information for the error. + // + // This must not contain sensitive information + Technical *string `json:"technical,omitempty"` +} + + +func sendGeneralError(ctx echo.Context, code int, message string) error { + + var s = "" + + genErr := ErrorModel{ + Message: &message, + Status: &s, + StatusCode: &code, + } + + err := ctx.JSON(code, genErr) + return err +} + + +func (ro *Rediops) GetHealth(ctx echo.Context) error { + + ro.Lock.Lock() + defer ro.Lock.Unlock() + + var item = HealthResponse { + Status: "OK", + Message: "Service available", + } + + return ctx.JSON(http.StatusOK, item) +} + +// Fetch the DevOps information +// (GET /.well-known/devops) +func (ro *Rediops) GetWellKnownDevopsJson(ctx echo.Context) error { + + // Check if the corresponding file exists + fileName := ro.ConfigFolder + "/devops.json" + if _, err := os.Stat(fileName); err == nil { + var item = DevopsModel {} + + content, err := ioutil.ReadFile(fileName) + if err != nil { + log.Fatal("Error when opening file: ", err) + return sendGeneralError(ctx, http.StatusInternalServerError , + "Internal server error") + } + + err = json.Unmarshal(content, &item) + if err != nil { + log.Fatal("Error during Unmarshal(): ", err) + return sendGeneralError(ctx, http.StatusInternalServerError , + "Internal server error") + } + + return ctx.JSON(http.StatusOK, item) + } + + + return sendGeneralError(ctx, http.StatusNotFound, + "devops.json not found") +} + +// List matching captured resources +// (GET /devops/) +func (ro *Rediops) GetDevops(ctx echo.Context, params GetDevopsParams) error { + + + var ilist = []DevopsbriefModel {} + + // Check if the corresponding folder exists + if _, err := os.Stat(ro.DataFolder); err == nil { + + files, err := ioutil.ReadDir(ro.DataFolder) + if err != nil { + log.Fatal(err) + } + + for _, file := range files { + + if (!file.IsDir()) { + content, err := ioutil.ReadFile(ro.DataFolder + "/"+ file.Name()) + if err != nil { + log.Printf("Error when opening file: %s", err) + return sendGeneralError(ctx, http.StatusInternalServerError , + "Internal server error") + } + + var item = DevopsModel {} + err = json.Unmarshal(content, &item) + if err != nil { + log.Printf("Error during Unmarshal(): %s", err) + return sendGeneralError(ctx, http.StatusInternalServerError , + "Internal server error") + } + + var brief = DevopsbriefModel { + Name: item.Name, + Version: item.Version, + } + brief.UniqueId = *item.UniqueId + brief.Guide = *item.Guide + brief.Self = "/devops/"+brief.UniqueId + + ilist = append(ilist, brief) + } + } + + return ctx.JSON(http.StatusOK, ilist) + } + + return sendGeneralError(ctx, http.StatusNotFound, + "Not found") + + +} + +// (DELETE /devops/{id}) +func (ro *Rediops) DeleteDevopsId(ctx echo.Context, id string) error { + + return sendGeneralError(ctx, http.StatusNotFound, + "Not supported") + +} + +// Fetch the Devops resource +// (GET /devops/{id}) +func (ro *Rediops) GetDevopsId(ctx echo.Context, id string) error { + + + // Check if the corresponding file exists + fileName := ro.DataFolder + "/"+ id + ".json" + if _, err := os.Stat(fileName); err == nil { + var item = DevopsModel {} + + content, err := ioutil.ReadFile(fileName) + if err != nil { + log.Printf("Error when opening file: %s", err) + return sendGeneralError(ctx, http.StatusInternalServerError , + "Internal server error") + } + + err = json.Unmarshal(content, &item) + if err != nil { + log.Printf("Error during Unmarshal(): %s", err) + return sendGeneralError(ctx, http.StatusInternalServerError , + "Internal server error") + } + + return ctx.JSON(http.StatusOK, item) + } + + return sendGeneralError(ctx, http.StatusNotFound, + (id + " not found")) + +} + +// Update the DevOps resource +// (POST /devops/{id}) +func (ro *Rediops) PostDevopsId(ctx echo.Context, id string) error { + + return sendGeneralError(ctx, http.StatusNotFound, + "Not supported") + +} diff --git a/examples/src/powershell/microservice/config/rediops.yml b/examples/src/powershell/microservice/config/rediops.yml new file mode 100644 index 0000000..28de167 --- /dev/null +++ b/examples/src/powershell/microservice/config/rediops.yml @@ -0,0 +1 @@ +package: rediops diff --git a/examples/src/powershell/microservice/config/server.cfg.yaml b/examples/src/powershell/microservice/config/server.cfg.yaml new file mode 100644 index 0000000..7848c6e --- /dev/null +++ b/examples/src/powershell/microservice/config/server.cfg.yaml @@ -0,0 +1,5 @@ +package: api +generate: + echo-server: true + embedded-spec: true +output: api/rediops-service-server.gen.go diff --git a/examples/src/powershell/microservice/config/types.cfg.yaml b/examples/src/powershell/microservice/config/types.cfg.yaml new file mode 100644 index 0000000..9a611b7 --- /dev/null +++ b/examples/src/powershell/microservice/config/types.cfg.yaml @@ -0,0 +1,4 @@ +package: api +generate: + models: true +output: api/rediops-service-types.gen.go diff --git a/examples/src/powershell/microservice/go.mod b/examples/src/powershell/microservice/go.mod new file mode 100644 index 0000000..31beaf0 --- /dev/null +++ b/examples/src/powershell/microservice/go.mod @@ -0,0 +1,31 @@ +module merebox.com/rediops + +go 1.18 + +require ( + github.com/deepmap/oapi-codegen v1.11.0 + github.com/getkin/kin-openapi v0.94.0 + github.com/labstack/echo/v4 v4.9.0 +) + +require ( + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/swag v0.21.1 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/labstack/gommon v0.3.1 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.1 // indirect + golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9 // indirect + golang.org/x/net v0.0.0-20220513224357-95641704303c // indirect + golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/examples/src/powershell/microservice/go.sum b/examples/src/powershell/microservice/go.sum new file mode 100644 index 0000000..de9dd58 --- /dev/null +++ b/examples/src/powershell/microservice/go.sum @@ -0,0 +1,179 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/deepmap/oapi-codegen v1.11.0 h1:f/X2NdIkaBKsSdpeuwLnY/vDI0AtPUrmB5LMgc7YD+A= +github.com/deepmap/oapi-codegen v1.11.0/go.mod h1:k+ujhoQGxmQYBZBbxhOZNZf4j08qv5mC+OH+fFTnKxM= +github.com/getkin/kin-openapi v0.94.0 h1:bAxg2vxgnHHHoeefVdmGbR+oxtJlcv5HsJJa3qmAHuo= +github.com/getkin/kin-openapi v0.94.0/go.mod h1:LWZfzOd7PRy8GJ1dJ6mCU6tNdSfOwRac1BUPam4aw6Q= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= +github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= +github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY= +github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= +github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o= +github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= +github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ= +github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc= +github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= +github.com/lestrrat-go/jwx v1.2.24/go.mod h1:zoNuZymNl5lgdcu6P7K6ie2QRll5HVfF4xwxBBK1NxY= +github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9 h1:NUzdAbFtCJSXU20AOXgeqaUwg8Ypg4MPYmL+d+rsB5c= +golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220513224357-95641704303c h1:nF9mHSvoKBLkQNQhJZNsc66z2UzAMUbLGjC95CF3pU0= +golang.org/x/net v0.0.0-20220513224357-95641704303c/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a h1:N2T1jUrTQE9Re6TFF5PhvEHXHCguynGhKjWVsIUt5cY= +golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= +golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/src/powershell/microservice/rediops.go b/examples/src/powershell/microservice/rediops.go new file mode 100644 index 0000000..2295eae --- /dev/null +++ b/examples/src/powershell/microservice/rediops.go @@ -0,0 +1,68 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/deepmap/oapi-codegen/pkg/middleware" + "github.com/labstack/echo/v4" + echomiddleware "github.com/labstack/echo/v4/middleware" + + "merebox.com/rediops/api" +) + +func main() { + var port = flag.Int("port", 8075, "Port for HTTP server micro service") + var dataFolder = flag.String("data", "./data", "Data folder") + var staticFolder = flag.String("static", "./static", "Static folder") + var configFolder = flag.String("configuration", "./config", "Configuration folder") + flag.Parse() + + swagger, err := api.GetSwagger() + if err != nil { + fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) + os.Exit(1) + } + + // Clear out the servers array in the swagger spec, that skips validating + // that server names match. We don't know how this thing will be run. + swagger.Servers = nil + + // Create an instance of our handler which satisfies the generated interface + configFilename := *configFolder + "/rediops.yaml" + var ro = api.NewRediops(*configFolder, configFilename, *dataFolder) + + e := echo.New() + // Log all requests + e.Use(echomiddleware.Logger()) + // Use our validation middleware to check all requests against the + // OpenAPI schema. + var options middleware.Options + // Skip static assets such as HTML, Images, CSS, etc + options.Skipper = func(c echo.Context) bool { + if (strings.HasSuffix(c.Request().URL.Path, ".html") || strings.HasSuffix(c.Request().URL.Path, ".json")) { + return true + } + if (strings.HasSuffix(c.Request().URL.Path, ".ico")) { + return true + } + if (c.Request().URL.Path =="/") { + return true + } + if strings.HasPrefix(c.Request().URL.Path, "/assets/") { + return true + } + + return false + } + e.Use(middleware.OapiRequestValidatorWithOptions(swagger, &options)) + + api.RegisterHandlers(e, ro) + + e.Static("/", *staticFolder) + + // And we serve HTTP until the world ends. + e.Logger.Fatal(e.Start(fmt.Sprintf("0.0.0.0:%d", *port))) +} diff --git a/examples/src/powershell/microservice/update.ps1 b/examples/src/powershell/microservice/update.ps1 new file mode 100644 index 0000000..d47f67c --- /dev/null +++ b/examples/src/powershell/microservice/update.ps1 @@ -0,0 +1,54 @@ +param ( + [string] $baseFolder, + [string] $specFile +) + +if (!(Test-Path $baseFolder)) { + Write-Host "The base folder '$baseFolder' not found" -ForegroundColor Red + return +} + +$wellFile = $baseFolder + "/.well-known/devops.json" +$devops = Get-Content $wellFile | ConvertFrom-JSON + +if ($specFile -eq "") { + $devops.apis | ForEach-Object { + if ($_.engine.url.endswith(".json") -and ($_.engine.category -eq "API") -and ($_.engine.name -eq "openapi")) { + $specFile = $baseFolder + $_.engine.url + } + } +} + +if (!(Test-Path $specFile -PathType Leaf)) { + Write-Host "The specification file '$specFile' not found" -ForegroundColor Red + return +} +Write-Host "Using specification file '$specFile' " -ForegroundColor White + +$opapiCodeGen = $env:USERPROFILE + "/go/pkg/mod/github.com/deepmap/oapi-codegen@v1.11.0/cmd/oapi-codegen/oapi-codegen.go" +if (!(Test-Path $opapiCodeGen -PathType Leaf)) { + Write-Host "The codse generator '$opapiCodeGen' not found" -ForegroundColor Red + return +} + +Write-Host "Commencing code generation" -ForegroundColor White + +go env -w GOOS=windows +go env -w GOARCH=386 + +go get gopkg.in/yaml.v2 +go get github.com/deepmap/oapi-codegen/pkg/codegen +go get github.com/deepmap/oapi-codegen/pkg/util +go get github.com/deepmap/oapi-codegen/pkg/types@v1.11.0 + +$configFile = "./config/types.cfg.yaml" +go run $opapiCodeGen --config $configFile $specFile +$configFile = "./config/server.cfg.yaml" +go run $opapiCodeGen --config $configFile $specFile + +go mod tidy + +$buildCode = "./rediops.go" +go build $buildCode + +Write-Host "Code generation completed" -ForegroundColor Green diff --git a/examples/src/powershell/static/deploy.ps1 b/examples/src/powershell/static/deploy.ps1 new file mode 100644 index 0000000..139597f --- /dev/null +++ b/examples/src/powershell/static/deploy.ps1 @@ -0,0 +1,2 @@ + + diff --git a/guide/api.md b/guide/api.md new file mode 100644 index 0000000..c12cab1 --- /dev/null +++ b/guide/api.md @@ -0,0 +1,27 @@ +# API + +The **api** section of the **devops.json** is used to locate the API +specification for the component. The specification is commonly in +OpenAPI format. + +The information can be used to: + +* Review the capabilities expose bu the service +* Call the service if included in the specification +* Generate code, eithers server based or client code + +Multiple versions can be published and it is up to the consumer +to determine which version to use. For example both +a YAML and JSON versions of the OpenApi specification can be published. + +Like all sections, there is guide reference which can give further information +on how the section can be used. + +## Engine + +The engine identifies the accessor for the API. + +The two accessors to consider are: + +* GIT : this is the git location of the file within the repository +* REST : A REST / Web based access to the API specification diff --git a/guide/build.md b/guide/build.md index a94f38c..67eb8e0 100644 --- a/guide/build.md +++ b/guide/build.md @@ -1 +1,9 @@ # Build + +The **build** section of the **devops.json** is used to build the component. + +The build action can be + +Like all sections, there is guide reference which can give further information +on how the section can be used. + diff --git a/guide/dependency.md b/guide/dependency.md index 6a7039c..bbf776d 100644 --- a/guide/dependency.md +++ b/guide/dependency.md @@ -1,6 +1,6 @@ # Dependency -The dependency section is for defining any downstream APIs. An API can be: +The **dependency** section of the **devops.json** is for defining any downstream APIs. An API can be: * ODBC or JDBC connection * REST @@ -13,6 +13,9 @@ For each dependency you can define the: 2. Protocol: The protocol that connects to the downstream component 3. URL: The resource location. This has different meanings for each protocol +Like all sections, there is guide reference which can give further information +on how the section can be used. + ## OBC or JDBC The URL is the connection string, minus user and password information. With credentials diff --git a/guide/docker.md b/guide/docker.md new file mode 100644 index 0000000..0c5a79e --- /dev/null +++ b/guide/docker.md @@ -0,0 +1,2 @@ +# Docker and Containers + diff --git a/guide/health.md b/guide/health.md index e7ae354..5c48b3a 100644 --- a/guide/health.md +++ b/guide/health.md @@ -1,7 +1,10 @@ # Health -The health section is to enable the discovery of any health services published by +The **health** section of the **devops.json** is to enable the discovery of any health services published by the component. This specifies the name(s) of the health service **Note:** A health service should also be described in the OpenAPI document, which will provide more details. + +Like all sections, there is guide reference which can give further information +on how the section can be used. diff --git a/guide/install.md b/guide/install.md index fa0459b..7da5665 100644 --- a/guide/install.md +++ b/guide/install.md @@ -1,6 +1,6 @@ # Install -The install section is to enable the discovery of the functions +The **install** section of the **devops.json** is to enable the discovery of the functions to use when a install of the component is required. The definition does not include details about the server or infrastructure @@ -11,6 +11,9 @@ The same instructions for installation can be used for both non-production and production installation if the environment attributes are soft coded. +Like all sections, there is guide reference which can give further information +on how the section can be used. + ## Engine The engine identifies the processor for the refresh. diff --git a/guide/overview.md b/guide/overview.md index 476060d..da65c77 100644 --- a/guide/overview.md +++ b/guide/overview.md @@ -1,2 +1,52 @@ # Overview +The objective is to produce a specification that can be stored with the source code and can be used +to locate files used by the DevOps process. + +## Background + +Existing DevOps tools make assumptions or are configured as webhooks, which are outside of the +source code. By capturing the assumptions with the code, there is less risk of errors or +missed processes. + +## Design + +The approach with the specification is to create a file in a specified format in +**.well-known/devops.json** location within your source. The format has placeholders for various +activities of DevOps. + +The specification does not mandate the tools to use but provides a location +in the json where configuration files and other files are located in +the source folder structure. + +This allows the source code to be portable and the resource +to be rebuilt using the same tools and process. + + +## Automation + + +### Using the DevOps.json file + +Depending on your tools, there are various ways to get the benefits +provided by the DevOps.json file. + +The simplest case is if you have a simple setup and don't require +complex tool, is to define a simple bash script file in source +and name that source file as the install or refresh script. + +This bash script's location is then saved to devops.json + +See [Tutorials](tutorial/readme.md) for some ideas. + + +## Generating the DevOps.json file + +If you want consistency you can generate the devops.json file +from a template and prefill the data based on your organisations +preferred DevOps tools. + +If you tools change or you import projects from other organisations +or Open Source then the values can be changed per project without +impacting existing projects. + diff --git a/guide/refresh.md b/guide/refresh.md index 4f08aa7..2904613 100644 --- a/guide/refresh.md +++ b/guide/refresh.md @@ -1,8 +1,11 @@ # Refresh -The refresh section is to enable the discovery of the functions +The **refresh** section of the **devops.json** is to enable the discovery of the functions to use when a refresh of the component is required. +Like all sections, there is guide reference which can give further information +on how the section can be used. + ## Engine The engine identifies the processor for the refresh. diff --git a/guide/repository.md b/guide/repository.md new file mode 100644 index 0000000..e69de29 diff --git a/guide/test.md b/guide/test.md index 6f1761b..782ab3b 100644 --- a/guide/test.md +++ b/guide/test.md @@ -1,6 +1,9 @@ # Test +Like all sections, there is guide reference which can give further information +on how the section can be used. + ## Regression diff --git a/guide/tutorial/coredns.md b/guide/tutorial/coredns.md new file mode 100644 index 0000000..dbf5ebe --- /dev/null +++ b/guide/tutorial/coredns.md @@ -0,0 +1,2 @@ +# CoreDNS project + diff --git a/guide/tutorial/microservice.md b/guide/tutorial/microservice.md new file mode 100644 index 0000000..1ab4cec --- /dev/null +++ b/guide/tutorial/microservice.md @@ -0,0 +1,6 @@ +# Microservice project + +This is a tutorial demonstrating the build and deploying a Microservice. + + + diff --git a/guide/tutorial/readme.md b/guide/tutorial/readme.md new file mode 100644 index 0000000..24feaa2 --- /dev/null +++ b/guide/tutorial/readme.md @@ -0,0 +1,12 @@ +# Tutorials + +This directory contains various tutorials demonstrating use +cases for the **.well-known/devsops.json** + + +* [CoreDNS](coredns.md) - deploying and refreshing a DNS instance +* [Static web site](staticweb.md) - deploying or refreshing a static web site +built using Go and Docker +* [Microservice](microservice.md) - deploying or refreshing a micro service +built using Go and Docker + diff --git a/guide/tutorial/staticweb.md b/guide/tutorial/staticweb.md new file mode 100644 index 0000000..91a3540 --- /dev/null +++ b/guide/tutorial/staticweb.md @@ -0,0 +1,9 @@ +# Docker project + +This is a tutorial demonstrating the build and deploying a Docker image. + +There are many commercial and open source tools that provide a similar capability +and this is not intended to replace those tools if yo have them already +in everyday use. + + diff --git a/guide/uninstall.md b/guide/uninstall.md index 25f3c05..0aa97d2 100644 --- a/guide/uninstall.md +++ b/guide/uninstall.md @@ -1,12 +1,15 @@ # Uninstall -The uninstall section is to enable the discovery of the functions +The **uninstall** section of the **devops.json** is to enable the discovery of the functions to use when a decommisison of the component is required. The definition does not include details about the server or infrastructure as these can vary. This is definition works similar to the Ansible inventory and playbooks. +Like all sections, there is guide reference which can give further information +on how the section can be used. + ## Engine The engine identifies the processor for the refresh. diff --git a/specification/rediops.json b/specification/rediops.json index b6daaa5..cf1dcec 100644 --- a/specification/rediops.json +++ b/specification/rediops.json @@ -3,7 +3,7 @@ "info": { "title": "Rediscover DevOps configuration", "version": "v1", - "description": "This document describes the specification of the \nproposed file **.well-known/devops.json** that can \nbe used in the DevOps CI/cD as identifier for\ninformation required by the tools.\n\nBy using the .well-known location, assumptions are\nreduced if not eliminated by the automation tools.\n\nAutomation tools can also validate the information during \nsource commit to confirm the engineers are providing the necessary \ninformation and that it is valid.", + "description": "This document describes the specification of the \nproposed file **.well-known/devops.json** that can \nbe used in the DevOps CI/CD as identifier for\ninformation required by the tools.\n\nBy using the .well-known location, assumptions are\nreduced if not eliminated by the automation tools.\n\nThe end result is a design using HATEOS principles where further\ninformation on a resource can be obatined by following the bread crumbs of the \nrelationships in the **.well-known/devops.json** file.\n\nAutomation tools can also validate the information during \nsource commit to confirm the engineers are providing the necessary \ninformation and that it is valid.\n\nThe **devops.json** file has been defined using OpenAPI but that does not imply that\na real API needs to be deployed or used. On the contrary it is unlikely that the main\ncopy stored on Git is accessed via a API service. \n\nYou could build a catalogue service of all your **devops.json** definitions linked to\nGit definitions, but that is not a specification requirement.\n\nFor further information see https://github.com/meerkat-manor/rediOps", "contact": { "name": "Meerkat", "url": "https://github.com/meerkat-manor/rediOps", @@ -15,14 +15,196 @@ } }, "paths": { - "/.well-known/devops": { + "/devops/": { + "summary": "List devops definitions", + "description": "This service will list the **devops** definitions registered \nwith it.\n\nThis definition is only applicable if the **deveops** is\npublished as a service outside of the source code.", + "get": { + "tags": [ + "Proposed" + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/devopsbrief-model" + } + } + } + }, + "description": "Listing matching resources" + }, + "404": { + "description": "No match for resource or no resources exist" + } + }, + "summary": "List matching captured resources", + "description": "Capability to list matching resorces captured from\ncode repositories" + }, + "parameters": [ + { + "name": "id", + "description": "List resources with matching asset id", + "schema": { + "type": "string" + }, + "in": "query" + }, + { + "name": "name", + "description": "List resources matching on name", + "schema": { + "type": "string" + }, + "in": "query" + } + ] + }, + "/devops/{id}": { + "summary": "Operate on the identified resources", + "description": "This service and its operations are intended for use where \nthe DevOps information from source control versioning (e.g. Git)\nis wanted to be stored on a centrral registry.\n\nThe process of updating the central registry can be automated by use\nof web hooks which will retrieve the latest **.well-known/deveops.json**\nfrom Git on commits as an example.\n\nThis definition is only applicable if the **deveops** is\npublished as a service outside of the source code.", + "get": { + "tags": [ + "Proposed" + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/devops-model" + } + } + }, + "description": "The DevOps record was found" + }, + "404": { + "description": "The required Devops recor with the requested identity wasnot found." + } + }, + "summary": "Fetch the Devops resource", + "description": "For web servers that provide a DevOps catalogue,this service\nfetches the details for the requested DevOps identity" + }, + "post": { + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/devops-model" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/devops-model" + } + } + }, + "description": "The updated record is returned to the caller\non succssful update" + } + }, + "security": [ + { + "BearerAuthentication": [ + ] + } + ], + "summary": "Update the DevOps resource", + "description": "This service is for servers providing a catalogue service\nfor DevOps information. The original Git details are not required to\nbe updated.\n\nYou could create a capability where this POST is used to \nupdate the source details and commit those changes." + }, + "delete": { + "responses": { + "200": { + "description": "Resource successfully deleted." + }, + "401": { + "description": "Not authorised to delete resource" + }, + "404": { + "description": "Resource not fouund" + } + }, + "security": [ + { + "BearerAuthentication": [ + ] + } + ] + }, + "parameters": [ + { + "examples": { + "Sample": { + "value": "\"AI7842389-01\"" + } + }, + "name": "id", + "description": "Resource identifier", + "schema": { + "type": "string" + }, + "in": "path", + "required": true + } + ] + }, + "/health": { + "summary": "Fetch the health of the service", + "description": "The service will return either a 200 (OK) or a 503 error message\n\nThis definition is only applicable if the **deveops** is\npublished as a service outside of the source code.", "get": { "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/devops", + "$ref": "#/components/schemas/health-response" + }, + "examples": { + "OK_state": { + "value": "\"OK\"" + } + } + } + }, + "description": "Returns the healthy message" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/health-response" + }, + "examples": { + "ERROR_sample": { + "value": "\"ERROR\"" + } + } + } + }, + "description": "Service is not available" + } + } + } + }, + "/.well-known/devops.json": { + "description": "This fetches the **devops.json\" file for this service,\n\nThis definition is only applicable if the **deveops** is\npublished as a service outside of the source code.", + "get": { + "tags": [ + "Proposed" + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/devops-model", "properties": { "version": { "type": "string", @@ -75,14 +257,14 @@ }, "guide": { "type": "string", - "example": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview" + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/overview.md" }, "repository": { "type": "object", "properties": { "guide": { "type": "string", - "example": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview" + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/repository.md" }, "source": { "type": "string", @@ -134,7 +316,7 @@ "properties": { "guide": { "type": "string", - "example": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview" + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/build.md" }, "engine": { "type": "string", @@ -147,7 +329,7 @@ "properties": { "guide": { "type": "string", - "example": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview" + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/test.md" }, "engine": { "type": "string", @@ -167,7 +349,7 @@ "properties": { "guide": { "type": "string", - "example": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview" + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/health.md" }, "api": { "type": "array", @@ -196,7 +378,7 @@ "properties": { "guide": { "type": "string", - "example": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview" + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/install.md" }, "engine": { "type": "string", @@ -236,7 +418,7 @@ "properties": { "guide": { "type": "string", - "example": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview" + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/refresh.md" }, "engine": { "type": "string", @@ -275,7 +457,7 @@ "properties": { "guide": { "type": "string", - "example": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview" + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/uninstall.md" }, "engine": { "type": "string", @@ -331,9 +513,9 @@ "twitter": "", "matrix": "@devops:meerkat-manor.org" }, - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/overview.md", "repository": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/repository.md", "source-engine": "Git", "source": "https://github.com", "artefact": "" @@ -356,11 +538,11 @@ ] }, "build": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/build.md", "engine": "JENKINS" }, "test": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/test.md", "engine": "UNITTEST" }, "api": [ @@ -374,7 +556,7 @@ } ], "health": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/health.md", "api": [ { "url": "/health", @@ -384,7 +566,7 @@ ] }, "install": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/install.md", "engine": "ANSIBLE", "playbook": "", "commands": { @@ -399,7 +581,7 @@ } }, "refresh": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/refresh.md", "engine": "COMMAND", "playbook": "", "commands": { @@ -412,7 +594,7 @@ } }, "uninstall": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/uninstall.md", "engine": "ANSIBLE", "playbook": "", "commands": { @@ -433,210 +615,262 @@ "description": "" } }, - "security": [ - { - - } - ], "summary": "Fetch the DevOps information", "description": "Commonly the DevOps information is not fetched using a REST API but is actually the JSON file stored the root **.well-known** directory as the file name **devops.json**\n\nIf so required there can be a supporting REST API to fetch the contents, but that is not the primary intent." } - }, - "/devops": { - "get": { - "responses": { - "404": { - "description": "No match for resource or no resources exist" - }, - "200": { - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/devops" - } - } - } - }, - "description": "Listing matching resources" - } - }, - "security": [ - { - - } - ] - }, - "parameters": [ - { - "name": "id", - "description": "List resources with matching asset id", - "schema": { - "type": "string" - }, - "in": "query" - }, - { - "name": "name", - "description": "List resources matchin on name", - "schema": { - "type": "string" - }, - "in": "query" - } - ] - }, - "/devops/{id}": { - "summary": "Operate on the identified resources", - "get": { - "parameters": [ - { - "name": "id", - "description": "Identifier for the DevOps resource.\n\nThe identifier is the Asset Id which is asumed to be unique for the catalogue servce.", - "schema": { - "type": "string" - }, - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/devops" - } - } - }, - "description": "The DevOps record was found" - }, - "404": { - "description": "The required Devops recor with the requested identity wasnot found." - } - }, - "security": [ - { - - } - ], - "summary": "Fetch the Devops resource", - "description": "For web servers that provide a DevOps catalogue,this service\nfetches the details for the requested DevOps identity" - }, - "post": { - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/devops" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "id", - "description": "Identifer of the DevOps resource.\n\nThis must match the asset identifier and is unique across all DevOps.", - "schema": { - "type": "string" - }, - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/devops" - } - } - }, - "description": "The updated record is returned to the caller\non succssful update" - } - }, - "security": [ - { - "BearerAuthentication": [ - ] - } - ], - "summary": "Update the DevOps resource", - "description": "This service is for servers providing a catalogue service\nfor DevOps information. The original Git details are not required to\nbe updated.\n\nYou could create a capability where this POST is used to \nupdate the source details and commit those changes." - }, - "delete": { - "parameters": [ - { - "name": "id", - "description": "Resource identifier for resource to be deleted", - "schema": { - "type": "string" - }, - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "Resource successfully deleted." - }, - "404": { - "description": "Resource not fouund" - }, - "401": { - "description": "Not authorised to delete resource" - } - }, - "security": [ - { - "BearerAuthentication": [ - ] - } - ] - }, - "parameters": [ - { - "examples": { - "Sample": { - "value": "\"AI7842389-01\"" - } - }, - "name": "id", - "description": "Resource identifier", - "schema": { - "type": "string" - }, - "in": "path", - "required": true - } - ] } }, "components": { "schemas": { - "devops-action": { - "title": "Root Type for devops-action", + "owner-contact": { + "title": "Root Type for asset-owner", + "description": "The name and /or contact detals of the DevOps owner.\n\nThe owner can be a single person or a team. It is preferale thati t is more\ngranualr then the organisation.\n\nIf you have a CMDB catalgue then the entry here should match the details on\nthe CMDB if you choose to include them here.\n\nThe contact details do not include a phone / mobile / cell number on purpose\nas this information is either know by the reader for the person / team or\ncan be obtained from an organisations internal directory.\n\nAutomated tools are unlikely to benefit from having access to a phone number, but they\ncan send emails or post messages to Slack.", + "type": "object", + "properties": { + "email": { + "description": "The email adress of the owner.\n\nThe email address could be a distribution list.", + "minLength": 6, + "pattern": "([-!#-'*+/-9=?A-Z^-~]+(\\.[-!#-'*+/-9=?A-Z^-~]+)*|\"([]!#-[^-~ \\t]|(\\\\[\\t -~]))+\")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])", + "type": "string", + "example": "emilia.jackson@devops.example.com" + }, + "web": { + "description": "A web page URL for the owner.\n\nThe web page could refer to a team page.", + "type": "string" + }, + "slack": { + "description": "Slack address of the owner.", + "type": "string" + }, + "twitter": { + "description": "Twitter handle for the contact", + "type": "string" + }, + "matrix": { + "description": "The matrrix IM identfier of the owner", + "type": "string", + "example": "@devops:meerkat-manor.org" + }, + "name": { + "description": "The name of the owner.\n\nThis may be persons or teams name.", + "type": "string" + } + }, + "example": { + "email": "devops@meerkatmanor-tech.org", + "web": "meerkatmanor-tech.org", + "slack": "", + "twitter": "", + "matrix": "@devops:meerkat-manor.org" + } + }, + "activity-model": { + "title": "Root Type for activity", "description": "", + "required": [ + "engine" + ], "type": "object", "properties": { "guide": { - "type": "string" + "description": "Link to documentation", + "type": "string", + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/activity.md" }, "engine": { - "enum": [ - "ANSIBLE", - "COMMANDS" - ], + "$ref": "#/components/schemas/engine-model", + "description": "Engine used for activties.\n\nFor example the engine name can be:\n\n* azure-pipeline\n* circle-ci\n* jenkins", + "maxLength": 20, + "example": "{\n \"category\": \"BUILD\",\n \"name\": \"Jenkins\",\n \"url\": \"some text\"\n}" + }, + "config": { + "description": "A configuration file that can be an URL location or a Git folder", "type": "string" }, + "script": { + "description": "A script file that is executed to perform the activity.\n\nThe choice of processing engine is up to the organisation, or \nsome assumptions can be made based on file extension.\n\nFor example:\n\n* .sh = Bash\n* .ps1 = PowerShell\n* .bat = MS DOS command", + "type": "string", + "example": "/build/builder.sh" + } + }, + "example": { + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/build.md", + "engine": { + "category": "BUILD", + "name": "Jenkins", + "url": "some text" + }, + "config": "/build/jenkins-build.conf", + "script": "/build/builder.sh" + } + }, + "dependency-model": { + "title": "Root Type for dependency-action", + "description": "The dependency section provides information on:\n\n1. APIs that the service calls such as ODBC, Authentication, System of Record API\n2. Tools that are required for build, testing and deployment", + "type": "object", + "properties": { + "guide": { + "description": "Link to documentation on dependencies", + "type": "string", + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/dependency.md" + }, + "apis": { + "description": "List of downstream dependency APIs.\n\nThe list can include:\n\n1. RESTful APIs\n2. SOAP APIs\n3. File transfer APIs\n4. ODBC or JDBC connections\n\nNo credentials are required to be captured in the definiton. Please do not include user names or passwords.", + "type": "array", + "items": { + "$ref": "#/components/schemas/api-model" + }, + "example": "[\n {\n \"asset_id\": \"AI560003\",\n \"protocol\": \"ODBC\",\n \"url\": \"\"\n },\n {\n \"asset_id\": \"AI560044\",\n \"protocol\": \"REST\",\n \"url\": \"\"\n }\n]" + }, + "tools": { + "type": "array", + "items": { + "$ref": "#/components/schemas/tools-model" + } + } + }, + "example": "{\n \"guide\": \"https://github.com/meerkat-manor/rediOps/blob/main/guide/dependency.md\",\n \"apis\": [\n {\n \"engine\": {\n \"category\": \"TEST\",\n \"name\": \"some text\",\n \"url\": \"some text\"\n },\n \"url\": \"some text\"\n },\n {\n \"engine\": {\n \"category\": \"SOURCE\",\n \"name\": \"some text\",\n \"url\": \"some text\"\n },\n \"url\": \"some text\"\n }\n ],\n \"tools\": [\n {\n \"guide\": \"some text\",\n \"engine\": {\n \"category\": \"API\",\n \"name\": \"some text\",\n \"url\": \"some text\"\n },\n \"playbook\": \"some text\",\n \"commands\": [\n \"some text\",\n \"some text\"\n ]\n },\n {\n \"guide\": \"some text\",\n \"engine\": {\n \"category\": \"OTHER\",\n \"name\": \"some text\",\n \"url\": \"some text\"\n },\n \"playbook\": \"some text\",\n \"commands\": [\n \"some text\",\n \"some text\"\n ]\n }\n ]\n}\n\n{\n \"apis\": [\n {\n \"asset_id\": \"AI560003\",\n \"protocol\": \"ODBC\",\n \"url\": \"\"\n },\n {\n \"asset_id\": \"AI560044\",\n \"protocol\": \"REST\",\n \"url\": \"\"\n }\n ],\n \"tools\": [\n {\n \"asset_id\": \"AI560003\",\n \"protocol\": \"ODBC\",\n \"url\": \"\"\n },\n {\n \"asset_id\": \"AI560044\",\n \"protocol\": \"REST\",\n \"url\": \"\"\n }\n ]\n}" + }, + "repository-model": { + "title": "Root Type for repository", + "description": "Link information to repositories for various registeries.\n\nYou can add custom extensions with prefix **x-** ", + "type": "object", + "properties": { + "guide": { + "description": "Link to documentation on repositories used by this component", + "type": "string", + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/repository.md" + }, + "artefact": { + "$ref": "#/components/schemas/engine-model", + "description": "Artefact engine\n\nSome common engines are:\n\n* Artifactory\n* Archiva\n\nCI servers can also have their own repository for generated artifact \n" + }, + "source": { + "$ref": "#/components/schemas/engine-model", + "description": "Source control version engine.\n\nThis can be used by tools to retreive source code using binary executables.\n\nSome common tools are \"Git\", \"TFS\", \"Mercurial\", \"CVS\".", + "example": "Git" + } + }, + "example": { + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/repository.md", + "artefact": { + "category": "ARTIFACT", + "name": "Artefactory", + "url": "https://archive.excample.com/" + }, + "source": { + "category": "SOURCE", + "name": "Git", + "url": "https://github.com" + } + } + }, + "tools-model": { + "title": "Root Type for tools-action", + "description": "The purpose of the tools section is an aid to identify the various tols required \nduring build, testing and deployment. This can server as a documentation item \nor actually preparing the nevironment to contain the necessary tool.\n\nIf you are using a well defined tool that is linked to your source versioning by\nweb hook then you are not likely to require this section for execution. \n\nA sample use case for a simple environment is to identify a tool that needs\nto be fetched from an artifact storage location as it is required by the \ndeployment install script.", + "type": "object", + "properties": { + "guide": { + "description": "Link to documentation for the tool in the context of this DevOps", + "type": "string", + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/tool.md" + }, + "engine": { + "$ref": "#/components/schemas/engine-model", + "description": "The processor to execute the commands.\n\nFor example you can define it as \"powershell\" to execute script file with extension .ps1\n\nYou cannot combine different commands for different processors in the one tools set. If you have different\nprocessors you can define multiple tools. ", + "example": "" + }, "playbook": { "type": "string" }, "commands": { - "$ref": "#/components/schemas/commands", + "type": "array", + "items": { + "type": "string" + }, + "properties": { + "pre": { + "type": "array", + "items": { + + } + }, + "script": { + "type": "string" + }, + "post": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "example": { + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/tool.md", + "engine": { + "category": "REFRESH", + "name": "cmd", + "url": "some text" + }, + "playbook": "some text", + "commands": [ + "some text", + "some text" + ] + } + }, + "asset-model": { + "title": "Root Type for asset-id", + "description": "A reference record linking the resource to an organisation asset record\nsuch as a CMDB entry.", + "type": "object", + "properties": { + "id": { + "description": "An external identifier for this rsource.", + "maxLength": 50, + "type": "string" + }, + "name": { + "description": "A name of the resource in the asset (CMDB) registry.\n\nThis could differ from the name specified in the \nparent level.", + "type": "string" + }, + "url": { + "description": "An URL to the resource in the asset (CMDB) registry.", + "type": "string" + } + }, + "example": { + "id": "AID07828923", + "name": "devops", + "url": "" + } + }, + "deploy-model": { + "title": "Root Type for devops-action", + "description": "Provides information of the commands or scripts to use when\nthe resources is bing installed, refreshed or uninstalled.\n\nThe script or playbook can be sourced from the source version manager (e.g. Git)", + "required": [ + "engine" + ], + "type": "object", + "properties": { + "guide": { + "description": "Link to documentation for the topic", + "type": "string", + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/deploy.md" + }, + "engine": { + "$ref": "#/components/schemas/engine-model", + "description": "The processor to understand and execute the commands or playbook.", + "example": "" + }, + "playbook": { + "description": "Playbook parameters", + "type": "string" + }, + "commands": { + "$ref": "#/components/schemas/commands-model", + "description": "Commands or script to be processed", "properties": { "pre": { "type": "array", @@ -657,22 +891,80 @@ } }, "example": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", - "engine": "ANSIBLE", + "guide": "https://github.com/meerkat-manor/rediOps/blob/main/guide/command.md", + "engine": { + "category": "COMMAND", + "name": "bash" + }, "playbook": "", "commands": { "pre": [ "hostname", "whoami" ], - "script": "deploy/install.sh", + "script": "/deploy/install.sh", "post": [ "echo Bye Bye" ] } } }, - "commands": { + "health-model": { + "title": "Root Type for health-model", + "description": "Lists the health services the resource exposes.\n\nThe guide can provide more detais about the health checks and their depth of checking.", + "type": "object", + "properties": { + "guide": { + "description": "Link to documentation describing the health check", + "type": "string", + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/health.md" + }, + "api": { + "description": "List of health check APIs published by the\nresource", + "type": "array", + "items": { + "$ref": "#/components/schemas/healthapi-model" + } + } + }, + "example": { + "guide": "https://", + "api": [ + { + "url": "/health", + "status": 200, + "response": "" + } + ] + } + }, + "healthapi-model": { + "title": "Root Type for healthapi-modle", + "description": "Describes the health service that the resource exposes.\n\nThe definition can inlcude expected response details", + "type": "object", + "properties": { + "url": { + "description": "URL for health check path. The path if suppied must\nmatch a path in the service definition (OpenAPI)\n\nUsing the URL path the details of the health check can\nbe found in the service definition.\n\nNormally a human coud make an intelligent assumption on\nwhat the name of the health check but a machine will find it\nmore difficult. Also consider how you would identify it \nin a foreign language.", + "type": "string" + }, + "status": { + "format": "int32", + "description": "The HTTP status code for a successful health check.\n\n", + "type": "integer", + "example": "200" + }, + "response": { + "description": "The expected response body from a healthy service", + "type": "string" + } + }, + "example": { + "url": "/health", + "status": 200, + "response": "" + } + }, + "commands-model": { "title": "Root Type for commands", "description": "Commands are executed by the engine. The commands need to be constructed in a format compatible with the engine. ", "type": "object", @@ -707,67 +999,98 @@ ] } }, - "owner-contact": { - "title": "Root Type for asset-owner", - "description": "The name and /or contact detals of the DevOps owner.\n\nThe owner can be a single person or a team. It is preferale thati t is more\ngranualr then the organisation.\n\nIf you have a CMDB catalgue then the entry here should match the details on\nthe CMDB if you choose to include them here.\n\nThe contact details do not include a phone / mobile / cell number on purpose\nas this information is either know by the reader for the person / team or\ncan be obtained from an organisations internal directory.\n\nAutomated tools are unlikely to benefit from having access to a phone number, but they\ncan send emails or post messages to Slack.", + "engine-model": { + "title": "Root Type for engine-model", + "description": "Engine details as used for apis, build, testing, configuration and deployment", + "required": [ + "category" + ], "type": "object", "properties": { - "email": { - "description": "The email adress of the owner.\n\nThe email address could be a distribution list.", - "minLength": 6, - "pattern": "([-!#-'*+/-9=?A-Z^-~]+(\\.[-!#-'*+/-9=?A-Z^-~]+)*|\"([]!#-[^-~ \\t]|(\\\\[\\t -~]))+\")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])", - "type": "string" - }, - "web": { - "description": "A web page URL for the owner.\n\nThe web page could refer to a team page.", - "type": "string" - }, - "slack": { - "description": "Slack address of the owner.", - "type": "string" - }, - "twitter": { - "type": "string" - }, - "matrix": { - "description": "The matrrix IM identfier of the owner", - "type": "string" - }, - "name": { - "description": "The name of the owner.\n\nThis may be persons or teams name.", - "type": "string" - } - }, - "example": { - "email": "devops@meerkatmanor-tech.org", - "web": "meerkatmanor-tech.org", - "slack": "", - "twitter": "", - "matrix": "@devops:meerkat-manor.org" - } - }, - "asset-id": { - "title": "Root Type for asset-id", - "description": "", - "type": "object", - "properties": { - "id": { + "category": { + "description": "Category of the engine", + "enum": [ + "BUILD", + "TEST", + "DEPLOY", + "UNINSTALL", + "SOURCE", + "API", + "CONFIG", + "ARTEFACT", + "COMMAND", + "OTHER" + ], "type": "string" }, "name": { + "description": "A common name for the tool, such as:\n\n* makefile\n* teamcity\n* azure-pipeline\n\nThe choice is up to you but you should keep it consistent.", "type": "string" }, "url": { + "description": "Link to engine or its configuration\n\nThe format of the URL will depend on the engine", "type": "string" } }, "example": { - "id": "AID07828923", - "name": "devops", - "url": "" + "category": "CONFIG", + "name": "some text", + "url": "/asset.conf" } }, - "devops": { + "api-model": { + "title": "Root Type for api", + "description": "A link to the API definition in OpenAPI format.\n\nThe definition file can be source from various locations, with\nthe most commo being either Git or REST (HTTPS) accessible \nlocations.\n\nA Git file can be accessed with Git command while REST / HTTPS\nmight use the \"wget\" or \"curl\" commands", + "required": [ + "engine", + "url" + ], + "type": "object", + "properties": { + "guide": { + "description": "Link to documentation for the topic", + "type": "string", + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/api.md" + }, + "engine": { + "$ref": "#/components/schemas/engine-model", + "description": "The engine that the Url refers to. As the Url format is used by various \nprocessors, an engine value is required for proper processing.\n\nThe acceptable values will depend on the organisation, but the\nminimal values that need to be supported are:\n\n* GIT for Git located resources. For this case the Git resource is assumed \n to be in the Git repository for this DevOps resource if the prefix is not\n HTTPS\n* REST for HTTP/S based web pages that are no explicitly handled by other engines\n\nOther possible values might be:\n\n* FILE for local or LAN based resources \n* S/FTP for FTP based URL resources", + "maxLength": 20, + "minLength": 0 + }, + "url": { + "description": "A full URL for the API or if the value is partial\nthen the location is assumed to be on the Git repo. That is the host name and\nGit name are the same as for the \"devops.json\" file.\n\nIf the resource details are being supplied by a catalogu service\nthen the value in the \"repository\" section will be used.", + "maxLength": 500, + "type": "string" + } + }, + "example": { + "engine": "REST", + "url": "api/v1/openapispec.json" + } + }, + "health-response": { + "title": "Root Type for health-response", + "description": "A response to the **/health** service\nand not a data model for **rediops** model\nas used in the **devops.json** definition", + "required": [ + "message", + "status" + ], + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "example": { + "status": "OK", + "message": "Available" + } + }, + "devops-model": { "title": "Root Type for devops", "description": "Information that supports DevOps activity.", "required": [ @@ -776,6 +1099,11 @@ ], "type": "object", "properties": { + "unique_id": { + "description": "Unique identifier \n\nThis is only applicable when the definition is serviced from a catalogue\nthat requires unique identifers.\n\nDo not use the Git repository URL as the unique identifier because\nto retrieve the file you would have to know the location. ", + "type": "string", + "example": "b85ffc5c-a1be-4bce-935e-4633577c7c1b" + }, "version": { "description": "Specification version\n\nMajor versions may not be compatible with minor versions.", "type": "string", @@ -805,7 +1133,7 @@ "example": "Ecommeerce web site" }, "asset": { - "$ref": "#/components/schemas/asset-id", + "$ref": "#/components/schemas/asset-model", "description": "Rsource information that is intended to be related to a Computer Management Database (CMDB).\n\nBy linking to the asset in an CMDB, further information can be retrieved.\n\nIf the CMDB link exists then it should be considered the authorative source where the same information exists in this definition.\n\nIf you wish the DevOps workflow to control the information and be versioned with Git, then you can use this information to push updates to the CMDB. Just include processing of the __./well-known/devops.json__ into your deployment pipeline and post to the CMDB the updates.", "example": "{\r\n \"id\": \"AID07828923\",\r\n \"name\": \"devops\",\r\n \"url\": \"\"\r\n}" }, @@ -831,12 +1159,13 @@ } }, "guide": { - "description": "A link to documentation for the resource being \ndescribed by this document.\n\nThe preferece is that the links is in the format of a HTTPS URL to a \nhuman readable web page.", - "type": "string" + "description": "A link to documentation for the resource being \ndescribed by this document.\n\nThe preference is that the links is in the format of a HTTPS URL to a \nhuman readable web page.", + "type": "string", + "example": "https://github.com/meerkat-manor/rediOps/blob/main/guide/overview.md" }, "repository": { + "$ref": "#/components/schemas/repository-model", "description": "Repository links", - "type": "object", "properties": { "guide": { "type": "string" @@ -850,7 +1179,8 @@ } }, "dependency": { - "type": "object", + "$ref": "#/components/schemas/dependency-model", + "description": "Describes the dependecies for the resource.\n\nThe dependecies include databases, downstream APIS, and build tooks.", "properties": { "guide": { "type": "string" @@ -881,8 +1211,11 @@ } }, "build": { - "$ref": "#/components/schemas/activity", "description": "Describes the build process, configuration and script file", + "type": "array", + "items": { + "$ref": "#/components/schemas/activity-model" + }, "properties": { "guide": { "type": "string" @@ -893,8 +1226,11 @@ } }, "test": { - "$ref": "#/components/schemas/activity", "description": "Describes the test process, tools and script", + "type": "array", + "items": { + "$ref": "#/components/schemas/activity-model" + }, "properties": { "guide": { "type": "string" @@ -902,11 +1238,12 @@ "engine": { "type": "string" } - } + }, + "example": "[\r\n {\r\n \"guide\": \"https://github.com/meerkat-manor/rediOps/blob/main/guide/test.md\",\r\n \"engine\": \"UNITTEST\"\r\n }\r\n]" }, "health": { + "$ref": "#/components/schemas/health-model", "description": "Information on the health service(s0 supported\nby the resource being described in this document.", - "type": "object", "properties": { "guide": { "type": "string" @@ -932,7 +1269,7 @@ } }, "install": { - "$ref": "#/components/schemas/devops-action", + "$ref": "#/components/schemas/deploy-model", "description": "The Install section gives information on installing the resource onto a server\nfor the first time. The detection on whether the resource is already\ninstalled is not defined in the specifications.\n\nThe information can be in the form of an Ansibe playbook or commands to \nbe executed on the server. You can also execute \ncommaonds from a script file that is found on the Git repo.", "properties": { "guide": { @@ -967,7 +1304,7 @@ } }, "refresh": { - "$ref": "#/components/schemas/devops-action", + "$ref": "#/components/schemas/deploy-model", "description": "The Refresh section gives information on refreshing the resource on the server. \nThe instructions can be the same as for installing the first time.\n\nThe information can be in the form of a Ansibe playbook or commands to \nbe executed on the server with the component installed. You can also execute \ncommaonds from a script file that is found on the Git repo.", "properties": { "guide": { @@ -1002,7 +1339,7 @@ } }, "uninstall": { - "$ref": "#/components/schemas/devops-action", + "$ref": "#/components/schemas/deploy-model", "description": "The Uninstall section gives information on uninstalling the component.\n\nThe information can be in the form of an Ansibe playbook or commands to \nbe executed on the server with the component installed. You can also execute \ncommaonds from a script file that is found on the Git repo.", "properties": { "guide": { @@ -1040,199 +1377,48 @@ "description": "List of OpenAPI definitions.\n\nThe list can include Git and REST versions, because before build the API might not be available\nas a REST service.\n\nA resource may have multiple definitions files or even different versions.", "type": "array", "items": { - "$ref": "#/components/schemas/api" - } - } - }, - "example": { - "version": "0.0.1", - "created_on": "2022-03-04T15:43:21Z", - "updated_on": "2022-03-04T15:43:21Z", - "organisation": "Meerkat Manor Tech College", - "name": "Web site", - "asset": { - "id": "AID07828923", - "name": "website", - "url": "" - }, - "owner": { - "email": "devops@meerkatmanor-tech.org", - "web": "meerkatmanor-tech.org", - "slack": "", - "twitter": "", - "matrix": "@devops:meerkat-manor.org" - }, - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", - "repository": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", - "source-engine": "Git", - "source": "https://github.com", - "artefact": "" - }, - "dependency": { - "guide": "", - "apis": [ - { - "asset_id": "AI560003", - "protocol": "ODBC", - "url": "" - }, - { - "asset_id": "AI560044", - "protocol": "REST", - "url": "" - } - ], - "tools": [ - ] - }, - "build": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", - "engine": "JENKINS" - }, - "test": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", - "engine": "UNITTEST" - }, - "api": [ - "api/v1/openapispec.json", - "api/v2/openapispec.json" - ], - "health": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", - "api": [ - { - "url": "/health", - "status": 200, - "response": "" - } - ] - }, - "install": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", - "engine": "ANSIBLE", - "playbook": "", - "commands": { - "pre": [ - "hostname", - "whoami" - ], - "script": "deploy/install.sh", - "post": [ - "echo Bye Bye" - ] - } - }, - "refresh": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", - "engine": "COMMAND", - "playbook": "", - "commands": { - "pre": [ - ], - "script": "deploy/refresh.sh", - "post": [ - "echo Refresh completed" - ] - } - }, - "uninstall": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", - "engine": "ANSIBLE", - "playbook": "", - "commands": { - "pre": [ - ], - "script": "deploy/decomission.sh", - "post": [ - "rm -R /opt/meerkat-manor/example", - "echo Component removed" - ] + "$ref": "#/components/schemas/api-model" } } } }, - "repository": { - "title": "Root Type for repository", - "description": "Link information to repositories for various registeries.\n\nYou can add custom extensions with prefix **x-** ", - "type": "object", - "properties": { - "guide": { - "description": "Link tgo documentation on repositories used by this component", - "type": "string" - }, - "source-engine": { - "description": "Source control version engine.\n\nThis can be used by tools to retreive source code using binary executables.\n\nSome common tools are \"Git\", \"TFS\", \"Mercurial\", \"CVS\".", - "type": "string", - "example": "Git" - }, - "source": { - "description": "Link to source version control system, such as Git.\n\nThe version control engine will provide the source version control system.", - "type": "string" - }, - "artefact-engine": { - "type": "string" - }, - "artefact": { - "type": "string" - } - }, - "example": { - "guide": "https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview", - "source-engine": "Git", - "source": "https://github.com", - "artefact-engine": "Archiva", - "artefact": "" - } - }, - "api": { - "title": "Root Type for api", - "description": "An API definition in OpenAPI format.\n\nThe definition file can be source from various locations, with\nthe most commo being either Git or REST (HTTPS) accessible \nlocations.\n\nA Git file can be accessed with Git command while REST / HTTPS\nmight use the \"wget\" or \"curl\" commands", + "devopsbrief-model": { + "description": "Used only for services and not part of the \n**rediops** definition ", "required": [ - "engine", - "url" + "unique_id", + "version", + "name", + "guide", + "self" ], "type": "object", "properties": { - "engine": { - "description": "The engine that the Url refers to. As the Url format is used by various \nprocessors, an engine value is required for proper processing.\n\nThe acceptable values will depend on the organisation, but the\nminimal values that need to be supported are:\n\n* GIT for Git located resources. For this case the Git resource is assumed \n to be in the Git repository for this DevOps resource if the prefix is not\n HTTPS\n* REST for HTTP/S based web pages that are no explicitly handled by other engines\n\nOther ppssible values might be:\n\n* FILE for loca or LAN based resources \n* S/FTP for FTP based URL resources", - "maxLength": 20, + "unique_id": { + "description": "Unique identifier of he devops definitions", "type": "string" }, - "url": { - "description": "A full URL for the API or if the valu is partial\nthen the location is assumed to be on the Git repo. That is the host name and\nGit name are the same as for the \"devops.json\" file.\n\nIf the resource details are being supplied by a catalogu service\nthen the value in the \"repository\" section will be ued.", - "maxLength": 500, + "version": { + "description": "Version of the devops definition", "type": "string" - } - }, - "example": { - "engine": "REST", - "url": "api/v1/openapispec.json" - } - }, - "activity": { - "title": "Root Type for activity", - "description": "", - "type": "object", - "properties": { + }, + "name": { + "description": "Name of the devops definition", + "type": "string" + }, "guide": { + "description": "Link to the guide of the devops definition", "type": "string" }, - "engine": { - "type": "string" - }, - "config": { - "type": "string" - }, - "script": { + "self": { + "description": "Link to full details of rediops definition as \ndefined by **deveops.json**\"", "type": "string" } }, "example": { - "guide": "https://", - "engine": "JENKINS", - "config": "/build/jenkins-build.conf", - "script": "/build/builder.sh" + "unique_id": "some text", + "version": "some text", + "name": "some text", + "guide": "some text" } } }, diff --git a/specification/rediops.yaml b/specification/rediops.yaml index bd28835..e2ca368 100644 --- a/specification/rediops.yaml +++ b/specification/rediops.yaml @@ -1,1057 +1 @@ -openapi: 3.0.0 -info: - title: Rediscover DevOps configuration - version: v1 - description: |- - This document describes the specification of the - proposed file **.well-known/devops.json** that can - be used in the DevOps CI/cD as identifier for - information required by the tools. - - By using the .well-known location, assumptions are - reduced if not eliminated by the automation tools. - - Automation tools can also validate the information during - source commit to confirm the engineers are providing the necessary - information and that it is valid. - contact: - name: Meerkat - url: 'https://github.com/meerkat-manor/rediOps' - email: meerkat@merebox.com - license: - name: Apache 2.0 - url: 'https://www.apache.org/licenses/LICENSE-2.0' -paths: - /.well-known/devops: - get: - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/devops' - properties: - version: - type: string - example: 0.0.1 - created_on: - type: string - example: '2022-03-04T15:43:21Z' - updated_on: - type: string - example: '2022-03-04T15:43:21Z' - organisation: - type: string - example: Meerkat Manor Tech College - name: - type: string - example: Web site - asset_id: - type: string - example: AID07828923 - owner: - type: object - properties: - email: - type: string - example: devops@meerkatmanor-tech.org - web: - type: string - example: meerkatmanor-tech.org - slack: - type: string - example: '' - twitter: - type: string - example: '' - matrix: - type: string - example: '@devops:meerkat-manor.org' - guide: - type: string - example: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - repository: - type: object - properties: - guide: - type: string - example: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - source: - type: string - example: 'https://github.com' - artefact: - type: string - example: '' - dependency: - type: object - properties: - guide: - type: string - example: '' - apis: - type: array - items: - type: object - properties: - asset_id: - type: string - example: AI560003 - protocol: - type: string - example: ODBC - url: - type: string - example: '' - tools: - type: array - items: {} - build: - type: object - properties: - guide: - type: string - example: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: - type: string - example: JENKINS - test: - type: object - properties: - guide: - type: string - example: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: - type: string - example: UNITTEST - api: - type: array - items: - type: string - example: api/v1/openapispec.json - health: - type: object - properties: - guide: - type: string - example: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - api: - type: array - items: - type: object - properties: - url: - type: string - example: /health - status: - type: integer - example: 200 - response: - type: string - example: '' - install: - type: object - properties: - guide: - type: string - example: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: - type: string - example: ANSIBLE - playbook: - type: string - example: '' - commands: - type: object - properties: - pre: - type: array - items: - type: string - example: hostname - script: - type: string - example: deploy/install.sh - post: - type: array - items: - type: string - example: echo Bye Bye - refresh: - type: object - properties: - guide: - type: string - example: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: - type: string - example: COMMAND - playbook: - type: string - example: '' - commands: - type: object - properties: - pre: - type: array - items: {} - script: - type: string - example: deploy/refresh.sh - post: - type: array - items: - type: string - example: echo Refresh completed - uninstall: - type: object - properties: - guide: - type: string - example: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: - type: string - example: ANSIBLE - playbook: - type: string - example: '' - commands: - type: object - properties: - pre: - type: array - items: {} - script: - type: string - example: deploy/decomission.sh - post: - type: array - items: - type: string - example: rm -R /opt/meerkat-manor/example - examples: - Demo: - value: - version: 0.0.1 - created_on: '2022-03-04T15:43:21Z' - updated_on: '2022-03-04T15:43:21Z' - organisation: Meerkat Manor Tech College - name: Web site - asset: - id: AID07828923 - name: '' - url: '' - owner: - email: devops@meerkatmanor-tech.org - web: meerkatmanor-tech.org - slack: '' - twitter: '' - matrix: '@devops:meerkat-manor.org' - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - repository: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - source-engine: Git - source: 'https://github.com' - artefact: '' - dependency: - guide: '' - apis: - - - asset_id: AI560003 - protocol: ODBC - url: '' - - - asset_id: AI560044 - protocol: REST - url: '' - tools: [] - build: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: JENKINS - test: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: UNITTEST - api: - - - engine: REST - url: api/v1/openapispec.json - - - engine: REST - url: api/v2/openapispec.json - health: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - api: - - - url: /health - status: 200 - response: '' - install: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: ANSIBLE - playbook: '' - commands: - pre: - - hostname - - whoami - script: deploy/install.sh - post: - - echo Bye Bye - refresh: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: COMMAND - playbook: '' - commands: - pre: [] - script: deploy/refresh.sh - post: - - echo Refresh completed - uninstall: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: ANSIBLE - playbook: '' - commands: - pre: [] - script: deploy/decomission.sh - post: - - rm -R /opt/meerkat-manor/example - - echo Component removed - description: '' - security: - - {} - summary: Fetch the DevOps information - description: >- - Commonly the DevOps information is not fetched using a REST API but is actually the JSON file - stored the root **.well-known** directory as the file name **devops.json** - - - If so required there can be a supporting REST API to fetch the contents, but that is not the - primary intent. - /devops: - get: - responses: - '200': - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/devops' - description: Listing matching resources - '404': - description: No match for resource or no resources exist - security: - - {} - parameters: - - - name: id - description: List resources with matching asset id - schema: - type: string - in: query - - - name: name - description: List resources matchin on name - schema: - type: string - in: query - '/devops/{id}': - summary: Operate on the identified resources - get: - parameters: - - - name: id - description: |- - Identifier for the DevOps resource. - - The identifier is the Asset Id which is asumed to be unique for the catalogue servce. - schema: - type: string - in: path - required: true - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/devops' - description: The DevOps record was found - '404': - description: The required Devops recor with the requested identity wasnot found. - security: - - {} - summary: Fetch the Devops resource - description: |- - For web servers that provide a DevOps catalogue,this service - fetches the details for the requested DevOps identity - post: - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/devops' - required: true - parameters: - - - name: id - description: |- - Identifer of the DevOps resource. - - This must match the asset identifier and is unique across all DevOps. - schema: - type: string - in: path - required: true - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/devops' - description: |- - The updated record is returned to the caller - on succssful update - security: - - - BearerAuthentication: [] - summary: Update the DevOps resource - description: |- - This service is for servers providing a catalogue service - for DevOps information. The original Git details are not required to - be updated. - - You could create a capability where this POST is used to - update the source details and commit those changes. - delete: - parameters: - - - name: id - description: Resource identifier for resource to be deleted - schema: - type: string - in: path - required: true - responses: - '200': - description: Resource successfully deleted. - '401': - description: Not authorised to delete resource - '404': - description: Resource not fouund - security: - - - BearerAuthentication: [] - parameters: - - - examples: - Sample: - value: '"AI7842389-01"' - name: id - description: Resource identifier - schema: - type: string - in: path - required: true -components: - schemas: - devops-action: - title: Root Type for devops-action - description: '' - type: object - properties: - guide: - type: string - engine: - enum: - - ANSIBLE - - COMMANDS - type: string - playbook: - type: string - commands: - $ref: '#/components/schemas/commands' - properties: - pre: - type: array - items: - type: string - script: - type: string - post: - type: array - items: - type: string - example: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: ANSIBLE - playbook: '' - commands: - pre: - - hostname - - whoami - script: deploy/install.sh - post: - - echo Bye Bye - commands: - title: Root Type for commands - description: >- - Commands are executed by the engine. The commands need to be constructed in a format - compatible with the engine. - type: object - properties: - pre: - description: Commands if any that are executed before the script and post items. - type: array - items: - type: string - script: - description: |- - A single script thais executed after the "pre" and before the "post" commands. - The script can be an URL or a file within the version control (e.g. Git) repository. - type: string - post: - description: Commands if any that are executed after the script. - type: array - items: - type: string - example: - pre: - - hostname - - whoami - script: /deploy/install.sh - post: - - echo Bye Bye - owner-contact: - title: Root Type for asset-owner - description: |- - The name and /or contact detals of the DevOps owner. - - The owner can be a single person or a team. It is preferale thati t is more - granualr then the organisation. - - If you have a CMDB catalgue then the entry here should match the details on - the CMDB if you choose to include them here. - - The contact details do not include a phone / mobile / cell number on purpose - as this information is either know by the reader for the person / team or - can be obtained from an organisations internal directory. - - Automated tools are unlikely to benefit from having access to a phone number, but they - can send emails or post messages to Slack. - type: object - properties: - email: - description: |- - The email adress of the owner. - - The email address could be a distribution list. - minLength: 6 - pattern: >- - ([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t - -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)]) - type: string - web: - description: |- - A web page URL for the owner. - - The web page could refer to a team page. - type: string - slack: - description: Slack address of the owner. - type: string - twitter: - type: string - matrix: - description: The matrrix IM identfier of the owner - type: string - name: - description: |- - The name of the owner. - - This may be persons or teams name. - type: string - example: - email: devops@meerkatmanor-tech.org - web: meerkatmanor-tech.org - slack: '' - twitter: '' - matrix: '@devops:meerkat-manor.org' - asset-id: - title: Root Type for asset-id - description: '' - type: object - properties: - id: - type: string - name: - type: string - url: - type: string - example: - id: AID07828923 - name: devops - url: '' - devops: - title: Root Type for devops - description: Information that supports DevOps activity. - required: - - version - - name - type: object - properties: - version: - description: |- - Specification version - - Major versions may not be compatible with minor versions. - type: string - example: 0.1.34 - created_on: - format: date-time - description: |- - Date and time this content was first created. - - The formatt is in ISO8061 and includes the date and time - type: string - example: '2022-05-29T13:44:11.000Z' - updated_on: - format: date-time - description: >- - Date this content was last updated. - - - If retrieved from source version control (e.g. Git) then the value here should match - the - - Git commit date for file. - - - The formatt is in ISO8061 and includes the date and time - type: string - example: '2022-07-25T17:22:11.00Z' - organisation: - description: |- - The name of the organisation that owns the implemened resouurce. - - The owner may not be netllectual Property / Copyright owner as the - general detaisl about the resource may be in teh public domain or - this organisation has licensed the rightsto use the resource - and its secification. - type: string - name: - description: |- - A name for the resource this document covers. - - If there is a CMDB catalogue then the name here should match the - name on the CMDB. - maxLength: 100 - minLength: 5 - type: string - example: Ecommeerce web site - asset: - $ref: '#/components/schemas/asset-id' - description: >- - Rsource information that is intended to be related to a Computer Management Database - (CMDB). - - - By linking to the asset in an CMDB, further information can be retrieved. - - - If the CMDB link exists then it should be considered the authorative source where the - same information exists in this definition. - - - If you wish the DevOps workflow to control the information and be versioned with Git, - then you can use this information to push updates to the CMDB. Just include - processing of the __./well-known/devops.json__ into your deployment pipeline and post - to the CMDB the updates. - example: "{\r\n \"id\": \"AID07828923\",\r\n \"name\": \"devops\",\r\n \"url\": \"\"\r\n}" - owner: - $ref: '#/components/schemas/owner-contact' - description: |- - Contact information for the resource being described. - - If the resorce information is provided from a central source - such as a CMDB then this content should match. - properties: - email: - type: string - web: - type: string - slack: - type: string - twitter: - type: string - matrix: - type: string - guide: - description: |- - A link to documentation for the resource being - described by this document. - - The preferece is that the links is in the format of a HTTPS URL to a - human readable web page. - type: string - repository: - description: Repository links - type: object - properties: - guide: - type: string - source: - type: string - artefact: - type: string - dependency: - type: object - properties: - guide: - type: string - apis: - type: array - items: - type: object - properties: - asset_id: - type: string - protocol: - type: string - url: - type: string - tools: - type: array - items: {} - build: - $ref: '#/components/schemas/activity' - description: 'Describes the build process, configuration and script file' - properties: - guide: - type: string - engine: - type: string - test: - $ref: '#/components/schemas/activity' - description: 'Describes the test process, tools and script' - properties: - guide: - type: string - engine: - type: string - health: - description: |- - Information on the health service(s0 supported - by the resource being described in this document. - type: object - properties: - guide: - type: string - api: - type: array - items: - type: object - properties: - url: - type: string - status: - format: int32 - type: integer - response: - type: string - install: - $ref: '#/components/schemas/devops-action' - description: |- - The Install section gives information on installing the resource onto a server - for the first time. The detection on whether the resource is already - installed is not defined in the specifications. - - The information can be in the form of an Ansibe playbook or commands to - be executed on the server. You can also execute - commaonds from a script file that is found on the Git repo. - properties: - guide: - type: string - engine: - type: string - playbook: - type: string - commands: - type: object - properties: - pre: - type: array - items: - type: string - script: - type: string - post: - type: array - items: - type: string - refresh: - $ref: '#/components/schemas/devops-action' - description: |- - The Refresh section gives information on refreshing the resource on the server. - The instructions can be the same as for installing the first time. - - The information can be in the form of a Ansibe playbook or commands to - be executed on the server with the component installed. You can also execute - commaonds from a script file that is found on the Git repo. - properties: - guide: - type: string - engine: - type: string - playbook: - type: string - commands: - type: object - properties: - pre: - type: array - items: {} - script: - type: string - post: - type: array - items: - type: string - uninstall: - $ref: '#/components/schemas/devops-action' - description: |- - The Uninstall section gives information on uninstalling the component. - - The information can be in the form of an Ansibe playbook or commands to - be executed on the server with the component installed. You can also execute - commaonds from a script file that is found on the Git repo. - properties: - guide: - type: string - engine: - type: string - playbook: - type: string - commands: - type: object - properties: - pre: - type: array - items: {} - script: - type: string - post: - type: array - items: - type: string - apis: - description: >- - List of OpenAPI definitions. - - - The list can include Git and REST versions, because before build the API might not be - available - - as a REST service. - - - A resource may have multiple definitions files or even different versions. - type: array - items: - $ref: '#/components/schemas/api' - example: - version: 0.0.1 - created_on: '2022-03-04T15:43:21Z' - updated_on: '2022-03-04T15:43:21Z' - organisation: Meerkat Manor Tech College - name: Web site - asset: - id: AID07828923 - name: website - url: '' - owner: - email: devops@meerkatmanor-tech.org - web: meerkatmanor-tech.org - slack: '' - twitter: '' - matrix: '@devops:meerkat-manor.org' - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - repository: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - source-engine: Git - source: 'https://github.com' - artefact: '' - dependency: - guide: '' - apis: - - - asset_id: AI560003 - protocol: ODBC - url: '' - - - asset_id: AI560044 - protocol: REST - url: '' - tools: [] - build: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: JENKINS - test: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: UNITTEST - api: - - api/v1/openapispec.json - - api/v2/openapispec.json - health: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - api: - - - url: /health - status: 200 - response: '' - install: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: ANSIBLE - playbook: '' - commands: - pre: - - hostname - - whoami - script: deploy/install.sh - post: - - echo Bye Bye - refresh: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: COMMAND - playbook: '' - commands: - pre: [] - script: deploy/refresh.sh - post: - - echo Refresh completed - uninstall: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - engine: ANSIBLE - playbook: '' - commands: - pre: [] - script: deploy/decomission.sh - post: - - rm -R /opt/meerkat-manor/example - - echo Component removed - repository: - title: Root Type for repository - description: |- - Link information to repositories for various registeries. - - You can add custom extensions with prefix **x-** - type: object - properties: - guide: - description: Link tgo documentation on repositories used by this component - type: string - source-engine: - description: |- - Source control version engine. - - This can be used by tools to retreive source code using binary executables. - - Some common tools are "Git", "TFS", "Mercurial", "CVS". - type: string - example: Git - source: - description: |- - Link to source version control system, such as Git. - - The version control engine will provide the source version control system. - type: string - artefact-engine: - type: string - artefact: - type: string - example: - guide: 'https://sku61.atlassian.net/wiki/spaces/WELLKNOWN/overview' - source-engine: Git - source: 'https://github.com' - artefact-engine: Archiva - artefact: '' - api: - title: Root Type for api - description: |- - An API definition in OpenAPI format. - - The definition file can be source from various locations, with - the most commo being either Git or REST (HTTPS) accessible - locations. - - A Git file can be accessed with Git command while REST / HTTPS - might use the "wget" or "curl" commands - required: - - engine - - url - type: object - properties: - engine: - description: |- - The engine that the Url refers to. As the Url format is used by various - processors, an engine value is required for proper processing. - - The acceptable values will depend on the organisation, but the - minimal values that need to be supported are: - - * GIT for Git located resources. For this case the Git resource is assumed - to be in the Git repository for this DevOps resource if the prefix is not - HTTPS - * REST for HTTP/S based web pages that are no explicitly handled by other engines - - Other ppssible values might be: - - * FILE for loca or LAN based resources - * S/FTP for FTP based URL resources - maxLength: 20 - type: string - url: - description: |- - A full URL for the API or if the valu is partial - then the location is assumed to be on the Git repo. That is the host name and - Git name are the same as for the "devops.json" file. - - If the resource details are being supplied by a catalogu service - then the value in the "repository" section will be ued. - maxLength: 500 - type: string - example: - engine: REST - url: api/v1/openapispec.json - activity: - title: Root Type for activity - description: '' - type: object - properties: - guide: - type: string - engine: - type: string - config: - type: string - script: - type: string - example: - guide: 'https://' - engine: JENKINS - config: /build/jenkins-build.conf - script: /build/builder.sh - securitySchemes: - BearerAuthentication: - scheme: bearer - type: http -tags: - - - name: Published - description: API has been deployed and is available for consumption - - - name: Development - description: 'API has been specified, but it is still in development and may change' - - - name: Drafted - description: API has been drafted but is subject to change - - - name: Proposed - description: API has been proposed but no specification has been drafted +ErrorInternal Server Error \ No newline at end of file