Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
61 changes: 59 additions & 2 deletions api/handlers/environments.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@ import (
"github.com/rs/zerolog/log"
)

// EnvironmentHandler - GET Handler to return one environment as JSON
// Define targets to be used to retrieve an environment map
var (
EnvMapTargets = map[string]bool{
"id": true,
"uuid": true,
"name": true,
}
)

// EnvironmentHandler - GET Handler to return one environment by UUID as JSON
func (h *HandlersApi) EnvironmentHandler(w http.ResponseWriter, r *http.Request) {
h.Inc(metricAPIEnvsReq)
utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAPI, settings.NoEnvironmentID), false)
Expand All @@ -24,7 +33,7 @@ func (h *HandlersApi) EnvironmentHandler(w http.ResponseWriter, r *http.Request)
h.Inc(metricAPIEnvsErr)
return
}
// Get environment by name
// Get environment by UUID
env, err := h.Envs.GetByUUID(envVar)
if err != nil {
if err.Error() == "record not found" {
Expand All @@ -50,6 +59,54 @@ func (h *HandlersApi) EnvironmentHandler(w http.ResponseWriter, r *http.Request)
h.Inc(metricAPIEnvsOK)
}

// EnvironmentMapHandler - GET Handler to return one environment as JSON
func (h *HandlersApi) EnvironmentMapHandler(w http.ResponseWriter, r *http.Request) {
h.Inc(metricAPIEnvsReq)
utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAPI, settings.NoEnvironmentID), false)
// Extract target
targetVar := r.PathValue("target")
if targetVar == "" {
apiErrorResponse(w, "error getting target", http.StatusBadRequest, nil)
h.Inc(metricAPIEnvsErr)
return
}
// Check if target is valid
if !EnvMapTargets[targetVar] {
apiErrorResponse(w, "invalid target", http.StatusBadRequest, fmt.Errorf("invalid target %s", targetVar))
h.Inc(metricAPIEnvsErr)
return
}
// Get context data and check access
ctx := r.Context().Value(ContextKey(contextAPI)).(ContextValue)
if !h.Users.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) {
apiErrorResponse(w, "no access", http.StatusForbidden, fmt.Errorf("attempt to use API by user %s", ctx[ctxUser]))
h.Inc(metricAPIEnvsErr)
return
}
// Prepare map by target
var envMap interface{}
var err error
switch targetVar {
case "id":
envMap, err = h.Envs.GetMapByID()
case "uuid":
envMap, err = h.Envs.GetMapByString()
case "name":
envMap, err = h.Envs.GetMapByString()
}
if err != nil {
apiErrorResponse(w, "error getting environments map", http.StatusInternalServerError, err)
h.Inc(metricAPIEnvsErr)
return
}
// Serialize and serve JSON
if h.Settings.DebugService(settings.ServiceAPI) {
log.Debug().Msg("DebugService: Returned environments map")
}
utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, envMap)
h.Inc(metricAPIEnvsOK)
}

// EnvironmentsHandler - GET Handler to return all environments as JSON
func (h *HandlersApi) EnvironmentsHandler(w http.ResponseWriter, r *http.Request) {
h.Inc(metricAPIEnvsReq)
Expand Down
1 change: 1 addition & 0 deletions api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ func osctrlAPIService() {
muxAPI.Handle("GET "+_apiPath(apiPlatformsPath), handlerAuthCheck(http.HandlerFunc(handlersApi.PlatformsHandler)))
muxAPI.Handle("GET "+_apiPath(apiPlatformsPath)+"/{env}", handlerAuthCheck(http.HandlerFunc(handlersApi.PlatformsEnvHandler)))
// API: environments
muxAPI.Handle("GET "+_apiPath(apiEnvironmentsPath)+"/map/{target}", handlerAuthCheck(http.HandlerFunc(handlersApi.EnvironmentMapHandler)))
muxAPI.Handle("GET "+_apiPath(apiEnvironmentsPath)+"/{env}", handlerAuthCheck(http.HandlerFunc(handlersApi.EnvironmentHandler)))
muxAPI.Handle("GET "+_apiPath(apiEnvironmentsPath)+"/{env}/enroll/{target}", handlerAuthCheck(http.HandlerFunc(handlersApi.EnvEnrollHandler)))
muxAPI.Handle("POST "+_apiPath(apiEnvironmentsPath)+"/{env}/enroll/{action}", handlerAuthCheck(http.HandlerFunc(handlersApi.EnvEnrollActionsHandler)))
Expand Down
14 changes: 14 additions & 0 deletions cli/api-environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ func (api *OsctrlAPI) GetEnvironment(identifier string) (environments.TLSEnviron
return e, nil
}

// GetEnvMap to retrieve a map of environments by ID
func (api *OsctrlAPI) GetEnvMap() (environments.MapEnvByID, error) {
var envMap environments.MapEnvByID
reqURL := fmt.Sprintf("%s%s%s/map/id", api.Configuration.URL, APIPath, APIEnvironments)
rawE, err := api.GetGeneric(reqURL, nil)
if err != nil {
return envMap, fmt.Errorf("error api request - %v - %s", err, string(rawE))
}
if err := json.Unmarshal(rawE, &envMap); err != nil {
return envMap, fmt.Errorf("can not parse body - %v", err)
}
return envMap, nil
}

// ExtendEnrollment to extend in time the enrollment URL of an environment
func (api *OsctrlAPI) ExtendEnrollment(identifier string) (string, error) {
return api.ActionEnrollmentRemove(identifier, settings.ActionExtend, "enroll", nil)
Expand Down
46 changes: 37 additions & 9 deletions cli/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,26 @@ import (
"os"
"strings"

"github.com/jmpsec/osctrl/environments"
"github.com/jmpsec/osctrl/tags"
"github.com/olekukonko/tablewriter"
"github.com/urfave/cli/v2"
)

// Helper function to convert a slice of tags into the data expected for output
func tagsToData(tgs []tags.AdminTag, header []string) [][]string {
func tagsToData(tgs []tags.AdminTag, m environments.MapEnvByID, header []string) [][]string {
var data [][]string
if header != nil {
data = append(data, header)
}
for _, n := range tgs {
data = append(data, tagToData(n, nil)...)
data = append(data, tagToData(n, m, nil)...)
}
return data
}

// Helper function to convert a tag into the data expected for output
func tagToData(t tags.AdminTag, header []string) [][]string {
func tagToData(t tags.AdminTag, m environments.MapEnvByID, header []string) [][]string {
var data [][]string
if header != nil {
data = append(data, header)
Expand All @@ -36,7 +37,7 @@ func tagToData(t tags.AdminTag, header []string) [][]string {
t.Description,
t.Color,
t.Icon,
//t.EnvironmentID,
m[t.EnvironmentID].Name,
t.CreatedBy,
stringifyBool(t.AutoTag),
tags.TagTypeDecorator(t.TagType),
Expand Down Expand Up @@ -198,6 +199,7 @@ func showTag(c *cli.Context) error {
os.Exit(1)
}
var t tags.AdminTag
var envName string
if dbFlag {
e, err := envs.Get(env)
if err != nil {
Expand All @@ -207,11 +209,17 @@ func showTag(c *cli.Context) error {
if err != nil {
return fmt.Errorf("❌ %s", err)
}
envName = e.Name
} else if apiFlag {
t, err = osctrlAPI.GetTag(env, name)
if err != nil {
return fmt.Errorf("❌ %s", err)
}
e, err := osctrlAPI.GetEnvironment(env)
if err != nil {
return fmt.Errorf("❌ %s", err)
}
envName = e.Name
}
fmt.Printf("Tag: %s\n", t.Name)
fmt.Printf("Description: %s\n", t.Description)
Expand All @@ -221,17 +229,19 @@ func showTag(c *cli.Context) error {
fmt.Printf("CreatedBy: %s\n", t.CreatedBy)
fmt.Printf("AutoTag: %s\n", stringifyBool(t.AutoTag))
fmt.Printf("TagType: %s\n", tags.TagTypeDecorator(t.TagType))
fmt.Printf("Environment: %s\n", envName)
fmt.Println()
return nil
}

func helperListTags(tgs []tags.AdminTag) error {
func helperListTags(tgs []tags.AdminTag, m environments.MapEnvByID) error {
header := []string{
"Created",
"Name",
"Description",
"Color",
"Icon",
"Environment",
"CreatedBy",
"AutoTag",
"TagType",
Expand All @@ -244,7 +254,7 @@ func helperListTags(tgs []tags.AdminTag) error {
}
fmt.Println(string(jsonRaw))
} else if formatFlag == csvFormat {
data := tagsToData(tgs, header)
data := tagsToData(tgs, m, header)
w := csv.NewWriter(os.Stdout)
if err := w.WriteAll(data); err != nil {
return fmt.Errorf("error writting csv - %s", err)
Expand All @@ -254,7 +264,7 @@ func helperListTags(tgs []tags.AdminTag) error {
table.SetHeader(header)
if len(tgs) > 0 {
fmt.Printf("Existing tags (%d):\n", len(tgs))
data := tagsToData(tgs, nil)
data := tagsToData(tgs, m, nil)
table.AppendBulk(data)
} else {
fmt.Println("No tags")
Expand All @@ -273,6 +283,7 @@ func listTagsByEnv(c *cli.Context) error {
}
// Retrieve data
var tgs []tags.AdminTag
var m environments.MapEnvByID
if dbFlag {
e, err := envs.Get(env)
if err != nil {
Expand All @@ -282,32 +293,49 @@ func listTagsByEnv(c *cli.Context) error {
if err != nil {
return fmt.Errorf("❌ %s", err)
}
m, err = envs.GetMapByID()
if err != nil {
return fmt.Errorf("❌ %s", err)
}
} else if apiFlag {
tgs, err = osctrlAPI.GetTags(env)
if err != nil {
return fmt.Errorf("❌ %s", err)
}
m, err = osctrlAPI.GetEnvMap()
if err != nil {
return fmt.Errorf("❌ %s", err)
}
}
if err := helperListTags(tgs); err != nil {
if err := helperListTags(tgs, m); err != nil {
return fmt.Errorf("❌ %s", err)
}
return nil
}

func listAllTags(c *cli.Context) error {
var tgs []tags.AdminTag
var m environments.MapEnvByID
if dbFlag {
tgs, err = tagsmgr.All()
if err != nil {
return fmt.Errorf("❌ %s", err)
}
m, err = envs.GetMapByID()
if err != nil {
return fmt.Errorf("❌ %s", err)
}
} else if apiFlag {
tgs, err = osctrlAPI.GetAllTags()
if err != nil {
return fmt.Errorf("❌ %s", err)
}
m, err = osctrlAPI.GetEnvMap()
if err != nil {
return fmt.Errorf("❌ %s", err)
}
}
if err := helperListTags(tgs); err != nil {
if err := helperListTags(tgs, m); err != nil {
return fmt.Errorf("❌ %s", err)
}
return nil
Expand Down
50 changes: 50 additions & 0 deletions environments/environments.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ type TLSEnvironment struct {
// MapEnvironments to hold the TLS environments by name and UUID
type MapEnvironments map[string]TLSEnvironment

// NameUUID to just hold the environment name and UUID
type NameUUID struct {
Name string
UUID string
ID uint
}

// MapEnvByID to hold the environments name and UUID by ID
type MapEnvByID map[uint]NameUUID

// MapEnvByString to hold the environments name and UUID by string
type MapEnvByString map[string]NameUUID

// Environment keeps all TLS Environments
type Environment struct {
DB *gorm.DB
Expand Down Expand Up @@ -256,6 +269,43 @@ func (environment *Environment) GetMap() (MapEnvironments, error) {
return _map, nil
}

// GetMapByID returns a smaller map of environments by ID
func (environment *Environment) GetMapByID() (MapEnvByID, error) {
all, err := environment.All()
if err != nil {
return nil, fmt.Errorf("error getting environments %v", err)
}
_map := make(MapEnvByID)
for _, e := range all {
_n := NameUUID{
Name: e.Name,
UUID: e.UUID,
ID: e.ID,
}
_map[e.ID] = _n
}
return _map, nil
}

// GetMapByString returns a smaller map of environments by string (name and UUID)
func (environment *Environment) GetMapByString() (MapEnvByString, error) {
all, err := environment.All()
if err != nil {
return nil, fmt.Errorf("error getting environments %v", err)
}
_map := make(MapEnvByString)
for _, e := range all {
_n := NameUUID{
Name: e.Name,
UUID: e.UUID,
ID: e.ID,
}
_map[e.Name] = _n
_map[e.UUID] = _n
}
return _map, nil
}

// Delete TLS Environment by name or UUID
func (environment *Environment) Delete(identifier string) error {
env, err := environment.Get(identifier)
Expand Down
Loading