browser policy store type & path in labels.

This commit is contained in:
Miroslav Šedivý
2021-07-27 20:17:17 +02:00
parent 3bb7fc25cf
commit 06e3c52e05
9 changed files with 99 additions and 105 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ import (
//go:embed policies.json //go:embed policies.json
var policiesJson string var policiesJson string
func Generate(policies types.Policies) (string, error) { func Generate(policies types.BrowserPolicyContent) (string, error) {
policiesTmpl := map[string]interface{}{} policiesTmpl := map[string]interface{}{}
if err := json.Unmarshal([]byte(policiesJson), &policiesTmpl); err != nil { if err := json.Unmarshal([]byte(policiesJson), &policiesTmpl); err != nil {
return "", err return "", err
+4 -4
View File
@@ -8,8 +8,8 @@ import (
"strings" "strings"
) )
func Parse(policiesJson string) (*types.Policies, error) { func Parse(policiesJson string) (*types.BrowserPolicyContent, error) {
policies := types.Policies{} policies := types.BrowserPolicyContent{}
policiesTmpl := map[string]interface{}{} policiesTmpl := map[string]interface{}{}
if err := json.Unmarshal([]byte(policiesJson), &policiesTmpl); err != nil { if err := json.Unmarshal([]byte(policiesJson), &policiesTmpl); err != nil {
@@ -21,12 +21,12 @@ func Parse(policiesJson string) (*types.Policies, error) {
// //
if extensions, ok := policiesTmpl["ExtensionInstallForcelist"]; ok { if extensions, ok := policiesTmpl["ExtensionInstallForcelist"]; ok {
policies.Extensions = []types.Extension{} policies.Extensions = []types.BrowserPolicyExtension{}
for _, val := range extensions.([]interface{}) { for _, val := range extensions.([]interface{}) {
s := strings.Split(val.(string), ";") s := strings.Split(val.(string), ";")
policies.Extensions = append( policies.Extensions = append(
policies.Extensions, policies.Extensions,
types.Extension{ types.BrowserPolicyExtension{
ID: s[0], ID: s[0],
URL: s[1], URL: s[1],
}, },
+6 -62
View File
@@ -7,80 +7,24 @@ import (
"m1k1o/neko_rooms/internal/types" "m1k1o/neko_rooms/internal/types"
) )
type PolicyType string func Generate(policies types.BrowserPolicyContent, policyType types.BrowserPolicyType) (string, error) {
if policyType == types.ChromiumBrowserPolicy {
const (
Chromium PolicyType = "chromium"
Firefox PolicyType = "friefox"
)
type PoliciesConfig struct {
Type PolicyType
Path string
Profile string
}
func GetConfig(image string) *PoliciesConfig {
switch image {
case "m1k1o/neko:latest":
fallthrough
case "m1k1o/neko:firefox":
return &PoliciesConfig{
Type: Firefox,
Path: "/usr/lib/firefox/distribution/policies.json",
Profile: "/home/neko/.mozilla/firefox/profile.default",
}
case "m1k1o/neko:arm-firefox":
return &PoliciesConfig{
Type: Firefox,
Path: "/usr/lib/firefox-esr/distribution/policies.json",
Profile: "/home/neko/.mozilla/firefox/profile.default",
}
case "m1k1o/neko:chromium":
fallthrough
case "m1k1o/neko:arm-chromium":
fallthrough
case "m1k1o/neko:ungoogled-chromium":
return &PoliciesConfig{
Type: Chromium,
Path: "/etc/chromium/policies/managed/policies.json",
Profile: "/home/neko/.config/chromium",
}
case "m1k1o/neko:google-chrome":
return &PoliciesConfig{
Type: Chromium,
Path: "/etc/opt/chrome/policies/managed/policies.json",
Profile: "/home/neko/.config/google-chrome",
}
case "m1k1o/neko:brave":
return &PoliciesConfig{
Type: Chromium,
Path: "/etc/brave/policies/managed/policies.json",
Profile: "/home/neko/.config/brave",
}
}
return nil
}
func Generate(policies types.Policies, policyType PolicyType) (string, error) {
if policyType == Chromium {
return chromium.Generate(policies) return chromium.Generate(policies)
} }
if policyType == Firefox { if policyType == types.FirefoxBrowserPolicy {
return firefox.Generate(policies) return firefox.Generate(policies)
} }
return "", errors.New("unknown policy type") return "", errors.New("unknown policy type")
} }
func Parse(policiesJson string, policyType PolicyType) (*types.Policies, error) { func Parse(policiesJson string, policyType types.BrowserPolicyType) (*types.BrowserPolicyContent, error) {
if policyType == Chromium { if policyType == types.ChromiumBrowserPolicy {
return chromium.Parse(policiesJson) return chromium.Parse(policiesJson)
} }
if policyType == Firefox { if policyType == types.FirefoxBrowserPolicy {
return firefox.Parse(policiesJson) return firefox.Parse(policiesJson)
} }
+1 -1
View File
@@ -11,7 +11,7 @@ import (
//go:embed policies.json //go:embed policies.json
var policiesJson string var policiesJson string
func Generate(policies types.Policies) (string, error) { func Generate(policies types.BrowserPolicyContent) (string, error) {
policiesTmpl := struct { policiesTmpl := struct {
Policies map[string]interface{} `json:"policies"` Policies map[string]interface{} `json:"policies"`
}{} }{}
+4 -4
View File
@@ -8,8 +8,8 @@ import (
"m1k1o/neko_rooms/internal/types" "m1k1o/neko_rooms/internal/types"
) )
func Parse(policiesJson string) (*types.Policies, error) { func Parse(policiesJson string) (*types.BrowserPolicyContent, error) {
policies := types.Policies{} policies := types.BrowserPolicyContent{}
policiesTmpl := struct { policiesTmpl := struct {
Policies map[string]interface{} `json:"policies"` Policies map[string]interface{} `json:"policies"`
@@ -28,7 +28,7 @@ func Parse(policiesJson string) (*types.Policies, error) {
// //
if extensions, ok := policiesTmpl.Policies["ExtensionSettings"]; ok { if extensions, ok := policiesTmpl.Policies["ExtensionSettings"]; ok {
policies.Extensions = []types.Extension{} policies.Extensions = []types.BrowserPolicyExtension{}
for id, val := range extensions.(map[string]interface{}) { for id, val := range extensions.(map[string]interface{}) {
if id == "*" { if id == "*" {
continue continue
@@ -39,7 +39,7 @@ func Parse(policiesJson string) (*types.Policies, error) {
policies.Extensions = append( policies.Extensions = append(
policies.Extensions, policies.Extensions,
types.Extension{ types.BrowserPolicyExtension{
ID: id, ID: id,
URL: url, URL: url,
}, },
+37 -1
View File
@@ -3,6 +3,8 @@ package room
import ( import (
"fmt" "fmt"
"strconv" "strconv"
"m1k1o/neko_rooms/internal/types"
) )
type RoomLabels struct { type RoomLabels struct {
@@ -10,6 +12,13 @@ type RoomLabels struct {
URL string URL string
Epr EprPorts Epr EprPorts
NekoImage string NekoImage string
BrowserPolicy *BrowserPolicyLabels
}
type BrowserPolicyLabels struct {
Type types.BrowserPolicyType
Path string
} }
func (manager *RoomManagerCtx) extractLabels(labels map[string]string) (*RoomLabels, error) { func (manager *RoomManagerCtx) extractLabels(labels map[string]string) (*RoomLabels, error) {
@@ -48,6 +57,24 @@ func (manager *RoomManagerCtx) extractLabels(labels map[string]string) (*RoomLab
return nil, err return nil, err
} }
var browserPolicy *BrowserPolicyLabels
if val, ok := labels["m1k1o.neko_rooms.browser_policy"]; ok && val == "true" {
policyType, ok := labels["m1k1o.neko_rooms.browser_policy.type"]
if !ok {
return nil, fmt.Errorf("damaged container labels: browser_policy.type not found")
}
policyPath, ok := labels["m1k1o.neko_rooms.browser_policy.path"]
if !ok {
return nil, fmt.Errorf("damaged container labels: browser_policy.path not found")
}
browserPolicy = &BrowserPolicyLabels{
Type: types.BrowserPolicyType(policyType),
Path: policyPath,
}
}
return &RoomLabels{ return &RoomLabels{
Name: name, Name: name,
URL: url, URL: url,
@@ -56,11 +83,12 @@ func (manager *RoomManagerCtx) extractLabels(labels map[string]string) (*RoomLab
Min: uint16(eprMin), Min: uint16(eprMin),
Max: uint16(eprMax), Max: uint16(eprMax),
}, },
BrowserPolicy: browserPolicy,
}, nil }, nil
} }
func (manager *RoomManagerCtx) serializeLabels(labels RoomLabels) map[string]string { func (manager *RoomManagerCtx) serializeLabels(labels RoomLabels) map[string]string {
return map[string]string{ labelsMap := map[string]string{
"m1k1o.neko_rooms.name": labels.Name, "m1k1o.neko_rooms.name": labels.Name,
"m1k1o.neko_rooms.url": labels.URL, "m1k1o.neko_rooms.url": labels.URL,
"m1k1o.neko_rooms.instance": manager.config.InstanceName, "m1k1o.neko_rooms.instance": manager.config.InstanceName,
@@ -68,4 +96,12 @@ func (manager *RoomManagerCtx) serializeLabels(labels RoomLabels) map[string]str
"m1k1o.neko_rooms.epr.max": fmt.Sprintf("%d", labels.Epr.Max), "m1k1o.neko_rooms.epr.max": fmt.Sprintf("%d", labels.Epr.Max),
"m1k1o.neko_rooms.neko_image": labels.NekoImage, "m1k1o.neko_rooms.neko_image": labels.NekoImage,
} }
if labels.BrowserPolicy != nil {
labelsMap["m1k1o.neko_rooms.browser_policy"] = "true"
labelsMap["m1k1o.neko_rooms.browser_policy.type"] = string(labels.BrowserPolicy.Type)
labelsMap["m1k1o.neko_rooms.browser_policy.path"] = labels.BrowserPolicy.Path
}
return labelsMap
} }
+27 -26
View File
@@ -187,11 +187,21 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
instanceUrl = instanceUrl + "/" instanceUrl = instanceUrl + "/"
} }
var browserPolicyLabels *BrowserPolicyLabels
if settings.BrowserPolicy != nil {
browserPolicyLabels = &BrowserPolicyLabels{
Type: settings.BrowserPolicy.Type,
Path: settings.BrowserPolicy.Path,
}
}
labels := manager.serializeLabels(RoomLabels{ labels := manager.serializeLabels(RoomLabels{
Name: roomName, Name: roomName,
URL: instanceUrl + roomName + "/", URL: instanceUrl + roomName + "/",
Epr: epr, Epr: epr,
NekoImage: settings.NekoImage, NekoImage: settings.NekoImage,
BrowserPolicy: browserPolicyLabels,
}) })
for k, v := range traefikLabels { for k, v := range traefikLabels {
@@ -213,24 +223,22 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
env = append(env, fmt.Sprintf("NEKO_NAT1TO1=%s", strings.Join(manager.config.NAT1To1IPs, ","))) env = append(env, fmt.Sprintf("NEKO_NAT1TO1=%s", strings.Join(manager.config.NAT1To1IPs, ",")))
} }
// browser policies //
if settings.Policies != nil { // Set browser policies
//
if settings.BrowserPolicy != nil {
if !manager.config.StorageEnabled { if !manager.config.StorageEnabled {
return "", fmt.Errorf("policies cannot be specified, because storage is disabled or unavailable") return "", fmt.Errorf("policies cannot be specified, because storage is disabled or unavailable")
} }
policyConfig := policies.GetConfig(settings.NekoImage) policyJson, err := policies.Generate(settings.BrowserPolicy.Content, settings.BrowserPolicy.Type)
if policyConfig == nil {
return "", fmt.Errorf("policy config for this image does not exist")
}
policyJson, err := policies.Generate(*settings.Policies, policyConfig.Type)
if err != nil { if err != nil {
return "", err return "", err
} }
// create policy path (+ also get host path) // create policy path (+ also get host path)
policyPath := fmt.Sprintf("/%s-%s-policy.json", roomName, policyConfig.Type) policyPath := fmt.Sprintf("/%s-%s-policy.json", roomName, settings.BrowserPolicy.Type)
templateInternalPath := path.Join(manager.config.StorageInternal, templateStoragePath) templateInternalPath := path.Join(manager.config.StorageInternal, templateStoragePath)
policyInternalPath := path.Join(templateInternalPath, policyPath) policyInternalPath := path.Join(templateInternalPath, policyPath)
@@ -250,17 +258,8 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
settings.Mounts = append(settings.Mounts, types.RoomMount{ settings.Mounts = append(settings.Mounts, types.RoomMount{
Type: types.MountTemplate, Type: types.MountTemplate,
HostPath: policyPath, HostPath: policyPath,
ContainerPath: policyConfig.Path, ContainerPath: settings.BrowserPolicy.Path,
}) })
// mount persistent folder
if settings.Policies.PersistentData && policyConfig.Profile != "" {
settings.Mounts = append(settings.Mounts, types.RoomMount{
Type: types.MountPrivate,
HostPath: fmt.Sprintf("/%s-profile", policyConfig.Type),
ContainerPath: policyConfig.Profile,
})
}
} }
// //
@@ -471,12 +470,14 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
}) })
} }
var policiesData *types.Policies var browserPolicy *types.BrowserPolicy
policyConfig := policies.GetConfig(labels.NekoImage) if labels.BrowserPolicy != nil {
if policyConfig != nil { browserPolicy.Type = labels.BrowserPolicy.Type
browserPolicy.Path = labels.BrowserPolicy.Path
var policyMount *types.RoomMount var policyMount *types.RoomMount
for _, mount := range mounts { for _, mount := range mounts {
if mount.ContainerPath == policyConfig.Path { if mount.ContainerPath == labels.BrowserPolicy.Path {
policyMount = &mount policyMount = &mount
break break
} }
@@ -487,8 +488,8 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
templateInternalPath := path.Join(manager.config.StorageInternal, templateStoragePath, policyMount.HostPath) templateInternalPath := path.Join(manager.config.StorageInternal, templateStoragePath, policyMount.HostPath)
if _, err := os.Stat(templateInternalPath); !os.IsNotExist(err) { if _, err := os.Stat(templateInternalPath); !os.IsNotExist(err) {
if data, err := os.ReadFile(templateInternalPath); err == nil { if data, err := os.ReadFile(templateInternalPath); err == nil {
if pData, err := policies.Parse(string(data), policyConfig.Type); err == nil { if content, err := policies.Parse(string(data), labels.BrowserPolicy.Type); err == nil {
policiesData = pData browserPolicy.Content = *content
} }
} }
} }
@@ -500,7 +501,7 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
NekoImage: labels.NekoImage, NekoImage: labels.NekoImage,
MaxConnections: labels.Epr.Max - labels.Epr.Min + 1, MaxConnections: labels.Epr.Max - labels.Epr.Min + 1,
Mounts: mounts, Mounts: mounts,
Policies: policiesData, BrowserPolicy: browserPolicy,
} }
err = settings.FromEnv(container.Config.Env) err = settings.FromEnv(container.Config.Env)
+18 -5
View File
@@ -1,12 +1,25 @@
package types package types
type Policies struct { type BrowserPolicyType string
Extensions []Extension `json:"extensions"`
DeveloperTools bool `json:"developer_tools"` const (
PersistentData bool `json:"persistent_data"` ChromiumBrowserPolicy BrowserPolicyType = "chromium"
FirefoxBrowserPolicy BrowserPolicyType = "friefox"
)
type BrowserPolicy struct {
Type BrowserPolicyType `json:"type"`
Path string `json:"path"`
Content BrowserPolicyContent `json:"content"`
} }
type Extension struct { type BrowserPolicyContent struct {
Extensions []BrowserPolicyExtension `json:"extensions"`
DeveloperTools bool `json:"developer_tools"`
PersistentData bool `json:"persistent_data"`
}
type BrowserPolicyExtension struct {
ID string `json:"id"` ID string `json:"id"`
URL string `json:"url"` URL string `json:"url"`
} }
+1 -1
View File
@@ -76,7 +76,7 @@ type RoomSettings struct {
Envs map[string]string `json:"envs"` Envs map[string]string `json:"envs"`
Mounts []RoomMount `json:"mounts"` Mounts []RoomMount `json:"mounts"`
Policies *Policies `json:"policies,omitempty"` BrowserPolicy *BrowserPolicy `json:"browser_policy,omitempty"`
} }
func (settings *RoomSettings) ToEnv() []string { func (settings *RoomSettings) ToEnv() []string {