Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
513 changes: 513 additions & 0 deletions Docktor.postman_collection.json

Large diffs are not rendered by default.

4,079 changes: 4,079 additions & 0 deletions Postman Echo.postman_collection.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ var cfgFile string
var RootCmd = &cobra.Command{
Use: "docktor",
Short: "Administration & Monitoring Deployment with Docker",
Long: `Docktor is a web application which aims to make the deployment of docke services easier
Long: `Docktor is a web application which aims to make the deployment of docker services easier.
With it, you can manage several daemons, services and group.
Each service can be deployed on a daemon for a group.
`,
Expand Down
2 changes: 1 addition & 1 deletion cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func init() {
serveCmd.Flags().StringP("jwt-secret", "j", "dev-docktor-secret", "Secret key used for JWT token authentication. Change it in your instance")
serveCmd.Flags().StringP("reset-pwd-secret", "", "dev-docktor-reset-pwd-to-change", "Secret key used when resetting the password. Change it in your instance")
serveCmd.Flags().StringP("bcrypt-pepper", "p", "dev-docktor-bcrypt", "Pepper used in password generation. Change it in your instance")
serveCmd.Flags().StringP("env", "e", "prod", "dev or prod")
serveCmd.Flags().StringP("env", "e", "dev", "dev or prod")
serveCmd.Flags().String("encrypt-secret", "encrypt-secret-to-change", "Secret for sensible data encryption. Change it in your instance")
serveCmd.Flags().String("ldap-address", "", "LDAP full address like : ldap.server:389. Optional")
serveCmd.Flags().String("ldap-baseDN", "", "BaseDN. Optional")
Expand Down
1 change: 1 addition & 0 deletions newman-docker
Submodule newman-docker added at b28f5a
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"François Samin - fsamin",
"Gwendal Leclerc - gwleclerc",
"Mathieu Cornic - macornic",
"Thibaut Rousseau - Thiht"
"Thibaut Rousseau - Thiht",
"Quentin Foucault - qfoucault"
],
"repository": {
"type": "git",
Expand Down Expand Up @@ -73,8 +74,8 @@
"sass-loader": "^6.0.6",
"source-map-loader": "^0.2.1",
"style-loader": "^0.18.2",
"webpack": "^3.5.5",
"webpack-dev-server": "^2.7.1"
"webpack": "^3.7.1",
"webpack-dev-server": "^2.9.1"
},
"dependencies": {
"classnames": "^2.2.5",
Expand Down
8 changes: 4 additions & 4 deletions server/controllers/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ func (a *Auth) Login(c echo.Context) error {
return c.JSON(http.StatusOK, Token{ID: token, User: user})
}

//ResetPassword handles resets the password of someone
//When user reset his password, it generates an email to this person with a link to change his.
// ResetPassword handles resets the password of someone
// When user reset his password, it generates an email to this person with a link to change his.
// The password is not reset in database because someone with bad intentions could use this feature to prevent someone else to login.
func (a *Auth) ResetPassword(c echo.Context) error {
// Get input parameters
Expand Down Expand Up @@ -189,8 +189,8 @@ func (a *Auth) ResetPassword(c echo.Context) error {
return c.JSON(http.StatusOK, "OK")
}

//ChangeResetPassword changes the password of someone that reset it before
//When user changes the password, he's automatically connected
// ChangeResetPassword changes the password of someone that reset it before
// When user changes the password, he's automatically connected
func (a *Auth) ChangeResetPassword(c echo.Context) error {
// Get input parameters

Expand Down
135 changes: 135 additions & 0 deletions server/controllers/catalogServices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package controllers

import (
"fmt"
"net/http"
"time"

"github.com/labstack/echo"
log "github.com/sirupsen/logrus"
"github.com/soprasteria/docktor/server/storage"
"github.com/soprasteria/docktor/server/types"
mgo "gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)

// CatalogServices contains all services handlers
type CatalogServices struct {
}

// GetAll catalogServices from docktor
func (s *CatalogServices) GetAll(c echo.Context) error {
docktorAPI := c.Get("api").(*storage.Docktor)
catalogServices, err := docktorAPI.CatalogServices().FindAll()
if err != nil {
log.WithError(err).Error("Unable to get all catalogServices")
return c.String(http.StatusInternalServerError, fmt.Sprintf("Unable to get all daemons because of technical error: %v. Retry later.", err))
}
return c.JSON(http.StatusOK, catalogServices)
}

// Save catalogService into docktor
func (s *CatalogServices) Save(c echo.Context) error {
docktorAPI := c.Get("api").(*storage.Docktor)
var catalogService types.CatalogService
if err := c.Bind(&catalogService); err != nil {
log.WithError(err).Error("Unable to bind catalogService to save")
return c.String(http.StatusBadRequest, "Unable to parse catalogService received from client")
}

// If the ID is empty, it's a creation, so generate an object ID
id := c.Param("catalogServiceID")
if id == "" {
// New catalogService to create
catalogService.ID = bson.NewObjectId()
catalogService.Created = time.Now()
} else {
// Existing catalogService
catalogService.ID = bson.ObjectIdHex(id)
s, err := docktorAPI.CatalogServices().FindByIDBson(catalogService.ID)
if err != nil {
if err == mgo.ErrNotFound {
log.WithError(err).Warnf("Tried to save a catalogService that does not exist: %v", catalogService.ID)
return c.String(http.StatusBadRequest, "CatalogService does not exist")
}
log.WithError(err).Errorf("Unable to find catalogService because of unexpected error : %v", catalogService.ID)
return c.String(http.StatusInternalServerError, "Unable to find catalogService because of technical error. Retry later.")
}
catalogService.Created = s.Created
}

// Validate fields from validator tags for common types
if err := c.Validate(catalogService); err != nil {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On ne valide rien ici car la structure CatalogueService et toutes les sous-structures ne contient pas de flags 'validate'. Exemple : https://github.com/go-playground/validator/blob/v9/_examples/simple/main.go

Il faut valider au max ce qu'on peut avec cette librairie validate. Et pour les trucs plus compliqué, il y a la fonction en dessous.

log.WithError(err).Errorf("Unable to save catalogService %v because some fields are not valid", catalogService.ID)
return c.String(http.StatusBadRequest, fmt.Sprintf("Some fields of catalogService are not valid: %v", err))
}

// Validate fields that cIannot be validated by validator engine

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cannot

if err := catalogService.Validate(); err != nil {
log.WithError(err).Errorf("Unable to save catalogService %v because some fields are not valid", catalogService.ID)
return c.String(http.StatusBadRequest, fmt.Sprintf("Some fields of catalogService are not valid: %v", err))
}

// Keep only existing and remove duplicates of external collections
// Used to clean the service of old data when saving
catalogService.Tags = existingTags(docktorAPI, catalogService.Tags)
catalogService.Updated = time.Now()

res, err := docktorAPI.CatalogServices().Save(catalogService)
if err != nil {
log.WithError(err).Errorf("Unexpected error when saving catalogService %v", catalogService.ID)
return c.String(http.StatusInternalServerError, fmt.Sprintf("Unable to save catalogService because of technical error: %v. Retry later.", err))
}
return c.JSON(http.StatusOK, res)
}

// existingCatalogServices return catalogServices filtered by existing ones
// Checks wether the Services actually exists in database
func existingCatalogServices(docktorAPI *storage.Docktor, catalogServicesIDs []bson.ObjectId) []bson.ObjectId {

existingCatalogServiceIDs := []bson.ObjectId{}

// Get all real groups

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong comment

existingcatalogServices, _ := docktorAPI.CatalogServices().FindAllByIDs(catalogServicesIDs)

// Get their ids only
for _, s := range existingcatalogServices {
existingCatalogServiceIDs = append(existingCatalogServiceIDs, s.ID)
}

return existingCatalogServiceIDs
}

// Delete catalogServices into docktor
func (s *CatalogServices) Delete(c echo.Context) error {
docktorAPI := c.Get("api").(*storage.Docktor)
id := c.Param("catalogServiceID")

res, err := docktorAPI.CatalogServices().Delete(bson.ObjectIdHex(id))
if err != nil {
log.WithError(err).Errorf("Unexpected error when deleting catalogService %v", id)
return c.String(http.StatusInternalServerError, fmt.Sprintf("Unable to delete catalogService because of technical error: %v. Retry later.", err))
}
return c.String(http.StatusOK, res.Hex())
}

// Get get a catalogService from docktor by its ID
func (s *CatalogServices) Get(c echo.Context) error {
catalogService := c.Get("catalogService").(types.CatalogService)
return c.JSON(http.StatusOK, catalogService)
}

// GetTags get all tags from a given catalogsService
// It is able to get tags from sub entities (like containers and services if needed)
func (s *CatalogServices) GetTags(c echo.Context) error {
catalogService := c.Get("catalogService").(types.CatalogService)
docktorAPI := c.Get("api").(*storage.Docktor)
tagIds := catalogService.Tags

tags, err := docktorAPI.Tags().FindAllByIDs(tagIds)
if err != nil {
log.WithError(err).WithField("catalogService", catalogService.ID).Error("Can't get tags of catalogService")
return c.JSON(http.StatusInternalServerError, "Incorrect data. Contact your administrator")
}
return c.JSON(http.StatusOK, tags)
}
9 changes: 9 additions & 0 deletions server/controllers/catalogServices/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package catalogServices

const (
// CatalogServiceNotFound : error while retreiving services
CatalogServiceNotFound string = "Cannot find catalog services %s"

// CatalogServiceInvalidID : ID is not set in url or is invalid
CatalogServiceInvalidID string = "Invalid catalog services ID"
)
28 changes: 28 additions & 0 deletions server/controllers/catalogServices/middlewares.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package catalogServices

import (
"fmt"
"net/http"

"github.com/labstack/echo"
log "github.com/sirupsen/logrus"
"github.com/soprasteria/docktor/server/storage"
)

// RetrieveCatalogService find catalogService using id param and put it in echo.Context
func RetrieveCatalogService(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
docktorAPI := c.Get("api").(*storage.Docktor)
catalogServiceID := c.Param("catalogServiceID")
if catalogServiceID == "" {
return c.String(http.StatusBadRequest, CatalogServiceInvalidID)
}
catalogService, err := docktorAPI.CatalogServices().FindByID(catalogServiceID)
if err != nil || catalogService.ID.Hex() == "" {
log.WithField("catalogService", catalogServiceID).Error("Unable to fetch catalogService")
return c.String(http.StatusNotFound, fmt.Sprintf(CatalogServiceNotFound, catalogServiceID))
}
c.Set("catalogService", catalogService)
return next(c)
}
}
6 changes: 3 additions & 3 deletions server/controllers/daemons.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (d *Daemons) GetAll(c echo.Context) error {
return c.JSON(http.StatusOK, docktorDaemons)
}

//Save daemon into docktor
// Save daemon into docktor
func (d *Daemons) Save(c echo.Context) error {
docktorAPI := c.Get("api").(*storage.Docktor)
var daemon types.Daemon
Expand Down Expand Up @@ -125,7 +125,7 @@ func (d *Daemons) Save(c echo.Context) error {
return c.JSON(http.StatusOK, res)
}

//Delete daemon into docktor
// Delete daemon into docktor
func (d *Daemons) Delete(c echo.Context) error {
docktorAPI := c.Get("api").(*storage.Docktor)
id := c.Param("daemonID")
Expand All @@ -149,7 +149,7 @@ func (d *Daemons) Delete(c echo.Context) error {
return c.String(http.StatusOK, res.Hex())
}

//Get daemon from docktor
// Get daemon from docktor
func (d *Daemons) Get(c echo.Context) error {
daemon := c.Get("daemon").(types.Daemon)
authenticatedUser, err := getUserFromToken(c)
Expand Down
2 changes: 1 addition & 1 deletion server/controllers/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
type Export struct {
}

//ExportAll exports all the data as a file
// ExportAll exports all the data as a file
func (a *Export) ExportAll(c echo.Context) error {
docktorAPI := c.Get("api").(*storage.Docktor)
exporter := export.Export{Docktor: docktorAPI}
Expand Down
72 changes: 38 additions & 34 deletions server/controllers/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
type Groups struct {
}

//GetAll groups from docktor
// GetAll groups from docktor
func (g *Groups) GetAll(c echo.Context) error {
docktorAPI := c.Get("api").(*storage.Docktor)
groups, err := docktorAPI.Groups().FindAll()
Expand All @@ -30,7 +30,7 @@ func (g *Groups) GetAll(c echo.Context) error {
return c.JSON(http.StatusOK, groups)
}

//Save group into docktor
// Save group into docktor
func (g *Groups) Save(c echo.Context) error {
docktorAPI := c.Get("api").(*storage.Docktor)
var group types.Group
Expand Down Expand Up @@ -151,7 +151,7 @@ func existingFileSystems(docktorAPI *storage.Docktor, fileSystems types.FileSyst
return existingFileSystems
}

//Delete group into docktor
// Delete group into docktor
func (g *Groups) Delete(c echo.Context) error {
docktorAPI := c.Get("api").(*storage.Docktor)
id := c.Param("groupID")
Expand All @@ -166,7 +166,7 @@ func (g *Groups) Delete(c echo.Context) error {
return c.String(http.StatusOK, res.Hex())
}

//Get group from docktor
// Get group from docktor
func (g *Groups) Get(c echo.Context) error {
group := c.Get("group").(types.Group)
return c.JSON(http.StatusOK, group)
Expand All @@ -175,36 +175,38 @@ func (g *Groups) Get(c echo.Context) error {
// GetTags get all tags from a given group
// It is able to get get tags from sub entities (like containers and services if needed)
func (g *Groups) GetTags(c echo.Context) error {
// withServices, _ := strconv.ParseBool(c.QueryParam("services")) // Get all tags from a given daemon
// withcontainers, _ := strconv.ParseBool(c.QueryParam("containers")) // Get all tags from a given Users
//withServices, _ := strconv.ParseBool(c.QueryParam("services")) // Get all tags from a given daemon
//withcontainers, _ := strconv.ParseBool(c.QueryParam("containers")) // Get all tags from a given Users
group := c.Get("group").(types.Group)
docktorAPI := c.Get("api").(*storage.Docktor)
tagIds := group.Tags

// TODO : enable it when containers and services are used again.
// Get also tags from container instances of group
// if withcontainers {
// for _, c := range group.Containers {
// tagIds = append(tagIds, c.Tags...)
// }
// }
// // Get also tags from the type of containers (= service)
// if withServices {
// var serviceIds []bson.ObjectId
// // Get services from containers
// for _, c := range group.Containers {
// serviceIds = append(serviceIds, c.ServiceID)
// }
// services, err := docktorAPI.Services().FindAllByIDs(serviceIds)
// if err != nil {
// log.WithError(err).WithField("group", group.ID).WithField("services.ids", serviceIds).Error("Can't get tags of service")
// return c.JSON(http.StatusInternalServerError, "Incorrect data. Contact your administrator")
// }
// // Get tags from services
// for _, s := range services {
// tagIds = append(tagIds, s.Tags...)
// }
// }
/*
// TODO : enable it when containers and services are used again.
// Get also tags from container instances of group
if withcontainers {
for _, c := range group.Containers {
tagIds = append(tagIds, c.Tags...)
}
}
//Get also tags from the type of containers (= service)
if withServices {
var serviceIds []bson.ObjectId
// Get services from containers
for _, c := range group.Containers {
serviceIds = append(serviceIds, c.ServiceID)
}
services, err := docktorAPI.CatalogServices().FindAllByIDs(serviceIds)
if err != nil {
log.WithError(err).WithField("group", group.ID).WithField("services.ids", serviceIds).Error("Can't get tags of service")
return c.JSON(http.StatusInternalServerError, "Incorrect data. Contact your administrator")
}
// Get tags from services
for _, s := range services {
tagIds = append(tagIds, s.Tags...)
}
}
*/

tags, err := docktorAPI.Tags().FindAllByIDs(tagIds)
if err != nil {
Expand Down Expand Up @@ -243,10 +245,12 @@ func (g *Groups) GetDaemons(c echo.Context) error {
daemonIds = append(daemonIds, fs.Daemon)
}

// TODO : enable it when containers and services are used again.
// for _, c := range group.Containers {
// daemonIds = append(daemonIds, c.DaemonID)
// }
/*
// TODO : enable it when containers and services are used again.
for _, c := range group.Containers {
daemonIds = append(daemonIds, c.DaemonID)
}
*/

ds, err := docktorAPI.Daemons().FindAllByIDs(daemonIds)
if err != nil {
Expand Down
Loading