rename folder extensions -> services

Signed-off-by: Christian Richter <crichter@owncloud.com>
This commit is contained in:
Christian Richter
2022-06-27 14:05:36 +02:00
parent 1aea93d8cd
commit 78064e6bab
926 changed files with 0 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
SHELL := bash
NAME := idm
TAGS := disable_crypt
include ../../.make/recursion.mk
############ tooling ############
ifneq (, $(shell command -v go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI
include ../../.bingo/Variables.mk
endif
############ go tooling ############
include ../../.make/go.mk
############ release ############
include ../../.make/release.mk
############ docs generate ############
include ../../.make/docs.mk
.PHONY: docs-generate
docs-generate: config-docs-generate
############ generate ############
include ../../.make/generate.mk
.PHONY: ci-go-generate
ci-go-generate: # CI runs ci-node-generate automatically before this target
.PHONY: ci-node-generate
ci-node-generate:
############ licenses ############
.PHONY: ci-node-check-licenses
ci-node-check-licenses:
.PHONY: ci-node-save-licenses
ci-node-save-licenses:
+14
View File
@@ -0,0 +1,14 @@
package main
import (
"os"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/command"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config/defaults"
)
func main() {
if err := command.Execute(defaults.DefaultConfig()); err != nil {
os.Exit(1)
}
}
+11
View File
@@ -0,0 +1,11 @@
package idm
import (
_ "embed"
)
//go:embed ldif/base.ldif.tmpl
var BaseLDIF string
//go:embed ldif/demousers.ldif
var DemoUsersLDIF string
+43
View File
@@ -0,0 +1,43 @@
dn: o=libregraph-idm
o: libregraph-idm
objectClass: organization
dn: ou=users,o=libregraph-idm
objectClass: organizationalUnit
ou: users
dn: ou=sysusers,o=libregraph-idm
objectClass: organizationalUnit
ou: users
dn: ou=groups,o=libregraph-idm
objectClass: organizationalUnit
ou: groups
{{ range . -}}
{{ if eq .Name "admin" -}}
dn: uid=admin,ou=users,o=libregraph-idm
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: ownCloud
objectClass: person
objectClass: top
uid: admin
givenName: Admin
sn: Admin
cn: admin
displayName: Admin
description: An admin for this oCIS instance.
mail: admin@example.org
ownCloudUUID: {{ .ID }}
{{ else -}}
dn: uid={{ .Name }},ou=sysusers,o=libregraph-idm
objectClass: account
objectClass: simpleSecurityObject
uid: {{ .Name }}
{{ end -}}
userPassword:: {{ .Password }}
{{ end -}}
+162
View File
@@ -0,0 +1,162 @@
dn: uid=einstein,ou=users,o=libregraph-idm
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: ownCloud
objectClass: person
objectClass: top
uid: einstein
givenName: Albert
sn: Einstein
cn: einstein
displayName: Albert Einstein
description: A German-born theoretical physicist who developed the theory of relativity, one of the two pillars of modern physics (alongside quantum mechanics).
mail: einstein@example.org
ownCloudUUID: 4c510ada-c86b-4815-8820-42cdf82c3d51
userPassword:: e0FSR09OMn0kYXJnb24yaWQkdj0xOSRtPTY1NTM2LHQ9MSxwPTIkOFpyclR0NXA1a0VmVlhL
akNHaVBEUSRnemZCWWwrTHdzTUhXQWJSMEJ2NnRiZk1XZjZaOVJ0Mms5Z3VkSWJ5bzg4
dn: uid=marie,ou=users,o=libregraph-idm
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: ownCloud
objectClass: person
objectClass: top
uid: marie
givenName: Marie
sn: Curie
cn: marie
displayName: Marie Skłodowska Curie
description: A Polish and naturalized-French physicist and chemist who conducted pioneering research on radioactivity.
mail: marie@example.org
ownCloudUUID: f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c
userPassword:: e0FSR09OMn0kYXJnb24yaWQkdj0xOSRtPTY1NTM2LHQ9MSxwPTIkUHJzWkpQQW9pMkFwZHlJ
a2Q1NGkzQSRnalZzR3doTmk2K0djenJ4SVdPalN2UlBpWXhKSXpHVG4vcnpQZzkvSlZN
dn: uid=katherine,ou=users,o=libregraph-idm
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: ownCloud
objectClass: person
objectClass: top
uid: katherine
givenName: Katherine
sn: Johnson
cn: katherine
displayName: Katherine Johnson
description: An American mathematician whose calculations of orbital mechanics as a NASA employee were critical to the success of the first and subsequent U.S. crewed spaceflights.
mail: katherine@example.org
ownCloudUUID: 534bb038-6f9d-4093-946f-133be61fa4e7
userPassword:: e0FSR09OMn0kYXJnb24yaWQkdj0xOSRtPTY1NTM2LHQ9MSxwPTIkYVd0b1RXdHdZblZuYjB4
Nk0wRm1adyRyeXVESVg0a3JSNGdmcnduZEh3aVpaSjVDUQ==
dn: uid=richard,ou=users,o=libregraph-idm
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: ownCloud
objectClass: person
objectClass: top
uid: richard
givenName: Richard
sn: Feynman
cn: richard
displayName: Richard Phillips Feynman
description: An American theoretical physicist, known for his work in the path integral formulation of quantum mechanics, the theory of quantum electrodynamics, the physics of the superfluidity of supercooled liquid helium, as well as his work in particle physics for which he proposed the parton model.
mail: richard@example.org
ownCloudUUID: 932b4540-8d16-481e-8ef4-588e4b6b151c
userPassword:: e0FSR09OMn0kYXJnb24yaWQkdj0xOSRtPTY1NTM2LHQ9MSxwPTIkNjlNcUQxem5sUUZ2SUha
d2dxU00xQSRVQmNEa2NDZktMemVpQnlyb0JjOTdCSVRhTFo2WjZIL2dhbytSTVh6OHhn
dn: uid=moss,ou=users,o=libregraph-idm
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: ownCloud
objectClass: person
objectClass: top
uid: moss
givenName: Maurice
sn: Moss
cn: moss
displayName: Maurice Moss
description: A worker in the IT Department of Reynholm Industries. Of all the working staff in the IT Department, he is the most hard-working, the most experienced, and the most capable of doing his job well. He puts a lot of effort into his work, however he does not get the credit he deserves.
mail: moss@example.org
ownCloudUUID: 058bff95-6708-4fe5-91e4-9ea3d377588b
userPassword:: e0FSR09OMn0kYXJnb24yaWQkdj0xOSRtPTY1NTM2LHQ9MSxwPTIkZU0xaXR6amQ2dlNSSERx
NlZCbXBlQSQxNzBhcTB3YjJZZ2NLU2cwWDhHY3l6ckZwMUllcGplMTNraDdVNjUyNXk4
dn: cn=users,ou=groups,o=libregraph-idm
objectClass: groupOfNames
objectClass: ownCloud
objectClass: top
cn: users
description: Users
ownCloudUUID: 509a9dcd-bb37-4f4f-a01a-19dca27d9cfa
member: uid=einstein,ou=users,o=libregraph-idm
member: uid=marie,ou=users,o=libregraph-idm
member: uid=richard,ou=users,o=libregraph-idm
member: uid=moss,ou=users,o=libregraph-idm
member: uid=admin,ou=users,o=libregraph-idm
dn: cn=sailing-lovers,ou=groups,o=libregraph-idm
objectClass: groupOfNames
objectClass: ownCloud
objectClass: top
cn: sailing-lovers
description: Sailing lovers
ownCloudUUID: 6040aa17-9c64-4fef-9bd0-77234d71bad0
member: uid=einstein,ou=users,o=libregraph-idm
dn: cn=violin-haters,ou=groups,o=libregraph-idm
objectClass: groupOfNames
objectClass: ownCloud
objectClass: top
cn: violin-haters
description: Violin haters
ownCloudUUID: dd58e5ec-842e-498b-8800-61f2ec6f911f
member: uid=einstein,ou=users,o=libregraph-idm
dn: cn=radium-lovers,ou=groups,o=libregraph-idm
objectClass: groupOfNames
objectClass: ownCloud
objectClass: top
cn: radium-lovers
description: Radium lovers
ownCloudUUID: 7b87fd49-286e-4a5f-bafd-c535d5dd997a
member: uid=marie,ou=users,o=libregraph-idm
dn: cn=polonium-lovers,ou=groups,o=libregraph-idm
objectClass: groupOfNames
objectClass: ownCloud
objectClass: top
cn: polonium-lovers
description: Polonium lovers
ownCloudUUID: cedc21aa-4072-4614-8676-fa9165f598ff
member: uid=marie,ou=users,o=libregraph-idm
dn: cn=quantum-lovers,ou=groups,o=libregraph-idm
objectClass: groupOfNames
objectClass: ownCloud
objectClass: top
cn: quantum-lovers
description: Quantum lovers
ownCloudUUID: a1726108-01f8-4c30-88df-2b1a9d1cba1a
member: uid=richard,ou=users,o=libregraph-idm
dn: cn=philosophy-haters,ou=groups,o=libregraph-idm
objectClass: groupOfNames
objectClass: ownCloud
objectClass: top
cn: philosophy-haters
description: Philosophy haters
ownCloudUUID: 167cbee2-0518-455a-bfb2-031fe0621e5d
member: uid=richard,ou=users,o=libregraph-idm
dn: cn=physics-lovers,ou=groups,o=libregraph-idm
objectClass: groupOfNames
objectClass: ownCloud
objectClass: top
cn: physics-lovers
description: Physics lovers
ownCloudUUID: 262982c1-2362-4afa-bfdf-8cbfef64a06e
member: uid=einstein,ou=users,o=libregraph-idm
member: uid=marie,ou=users,o=libregraph-idm
member: uid=richard,ou=users,o=libregraph-idm
+57
View File
@@ -0,0 +1,57 @@
package command
import (
"fmt"
"net/http"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config/parser"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/logging"
"github.com/urfave/cli/v2"
)
// Health is the entrypoint for the health command.
func Health(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "health",
Usage: "check health status",
Category: "info",
Before: func(c *cli.Context) error {
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
resp, err := http.Get(
fmt.Sprintf(
"http://%s/healthz",
cfg.Debug.Addr,
),
)
if err != nil {
logger.Fatal().
Err(err).
Msg("Failed to request health check")
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
logger.Fatal().
Int("code", resp.StatusCode).
Msg("Health seems to be in bad state")
}
logger.Debug().
Int("code", resp.StatusCode).
Msg("Health got a good state")
return nil
},
}
}
+64
View File
@@ -0,0 +1,64 @@
package command
import (
"context"
"os"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config"
"github.com/owncloud/ocis/v2/ocis-pkg/clihelper"
ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
"github.com/thejerf/suture/v4"
"github.com/urfave/cli/v2"
)
// GetCommands provides all commands for this service
func GetCommands(cfg *config.Config) cli.Commands {
return []*cli.Command{
// start this service
Server(cfg),
// interaction with this service
// infos about this service
Health(cfg),
Version(cfg),
}
}
// Execute is the entry point for the ocis-idm command.
func Execute(cfg *config.Config) error {
app := clihelper.DefaultApp(&cli.App{
Name: "idm",
Usage: "Embedded LDAP service for oCIS",
Commands: GetCommands(cfg),
})
cli.HelpFlag = &cli.BoolFlag{
Name: "help,h",
Usage: "Show the help",
}
return app.Run(os.Args)
}
// SutureService allows for the idm command to be embedded and supervised by a suture supervisor tree.
type SutureService struct {
cfg *config.Config
}
// NewSutureService creates a new idm.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
cfg.IDM.Commons = cfg.Commons
return SutureService{
cfg: cfg.IDM,
}
}
func (s SutureService) Serve(ctx context.Context) error {
s.cfg.Context = ctx
if err := Execute(s.cfg); err != nil {
return err
}
return nil
}
+174
View File
@@ -0,0 +1,174 @@
package command
import (
"context"
"encoding/base64"
"errors"
"fmt"
"html/template"
"os"
"strings"
"github.com/go-ldap/ldif"
"github.com/libregraph/idm/pkg/ldappassword"
"github.com/libregraph/idm/pkg/ldbbolt"
"github.com/libregraph/idm/server"
"github.com/owncloud/ocis/v2/extensions/idm"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config/parser"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/logging"
pkgcrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/urfave/cli/v2"
)
// Server is the entrypoint for the server command.
func Server(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "server",
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
ctx, cancel := func() (context.Context, context.CancelFunc) {
if cfg.Context == nil {
return context.WithCancel(context.Background())
}
return context.WithCancel(cfg.Context)
}()
defer cancel()
return start(ctx, logger, cfg)
},
}
}
func start(ctx context.Context, logger log.Logger, cfg *config.Config) error {
servercfg := server.Config{
Logger: log.LogrusWrap(logger.Logger),
LDAPHandler: "boltdb",
LDAPSListenAddr: cfg.IDM.LDAPSAddr,
TLSCertFile: cfg.IDM.Cert,
TLSKeyFile: cfg.IDM.Key,
LDAPBaseDN: "o=libregraph-idm",
LDAPAdminDN: "uid=libregraph,ou=sysusers,o=libregraph-idm",
BoltDBFile: cfg.IDM.DatabasePath,
}
if cfg.IDM.LDAPSAddr != "" {
// Generate a self-signing cert if no certificate is present
if err := pkgcrypto.GenCert(cfg.IDM.Cert, cfg.IDM.Key, logger); err != nil {
logger.Fatal().Err(err).Msgf("Could not generate test-certificate")
}
}
if _, err := os.Stat(servercfg.BoltDBFile); errors.Is(err, os.ErrNotExist) {
logger.Debug().Msg("Bootstrapping IDM database")
if err = bootstrap(logger, cfg, servercfg); err != nil {
logger.Error().Err(err).Msg("failed to bootstrap idm database")
}
}
svc, err := server.NewServer(&servercfg)
if err != nil {
return err
}
return svc.Serve(ctx)
}
func bootstrap(logger log.Logger, cfg *config.Config, srvcfg server.Config) error {
// Hash password if the config does not supply a hash already
var err error
type svcUser struct {
Name string
Password string
ID string
}
serviceUsers := []svcUser{
{
Name: "admin",
Password: cfg.ServiceUserPasswords.OcisAdmin,
ID: cfg.AdminUserID,
},
{
Name: "libregraph",
Password: cfg.ServiceUserPasswords.Idm,
},
{
Name: "idp",
Password: cfg.ServiceUserPasswords.Idp,
},
{
Name: "reva",
Password: cfg.ServiceUserPasswords.Reva,
},
}
bdb := &ldbbolt.LdbBolt{}
if err := bdb.Configure(srvcfg.Logger, srvcfg.LDAPBaseDN, srvcfg.BoltDBFile, nil); err != nil {
return err
}
defer bdb.Close()
if err := bdb.Initialize(); err != nil {
return err
}
// Prepare the initial Data from template. To be able to set the
// supplied service user passwords
tmpl, err := template.New("baseldif").Parse(idm.BaseLDIF)
if err != nil {
return err
}
for i := range serviceUsers {
if strings.HasPrefix(serviceUsers[i].Password, "$argon2id$") {
// password is alread hashed
serviceUsers[i].Password = "{ARGON2}" + serviceUsers[i].Password
} else {
if serviceUsers[i].Password, err = ldappassword.Hash(serviceUsers[i].Password, "{ARGON2}"); err != nil {
return err
}
}
// We need to treat the hash as binary in the LDIF template to avoid
// go-ldap/ldif to to any fancy escaping
serviceUsers[i].Password = base64.StdEncoding.EncodeToString([]byte(serviceUsers[i].Password))
}
var tmplWriter strings.Builder
err = tmpl.Execute(&tmplWriter, serviceUsers)
if err != nil {
return err
}
bootstrapData := tmplWriter.String()
if cfg.CreateDemoUsers {
bootstrapData = bootstrapData + "\n" + idm.DemoUsersLDIF
}
s := strings.NewReader(bootstrapData)
lf := &ldif.LDIF{}
err = ldif.Unmarshal(s, lf)
if err != nil {
return err
}
for _, entry := range lf.AllEntries() {
logger.Debug().Str("dn", entry.DN).Msg("Adding entry")
if err := bdb.EntryPut(entry); err != nil {
return fmt.Errorf("error adding Entry '%s': %w", entry.DN, err)
}
}
return nil
}
+19
View File
@@ -0,0 +1,19 @@
package command
import (
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config"
"github.com/urfave/cli/v2"
)
// Version prints the service versions of all running instances.
func Version(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "version",
Usage: "print the version of this binary and the running extension instances",
Category: "info",
Action: func(c *cli.Context) error {
// not implemented
return nil
},
}
}
+40
View File
@@ -0,0 +1,40 @@
package config
import (
"context"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
)
// Config combines all available configuration parts.
type Config struct {
Commons *shared.Commons `yaml:"-"` // don't use this directly as configuration for a service
Service Service `yaml:"-"`
Tracing *Tracing `yaml:"tracing"`
Log *Log `yaml:"log"`
Debug Debug `yaml:"debug"`
IDM Settings `yaml:"idm"`
CreateDemoUsers bool `yaml:"create_demo_users" env:"IDM_CREATE_DEMO_USERS;ACCOUNTS_DEMO_USERS_AND_GROUPS" desc:"Flag to enabe/disable the creation of the demo users"`
ServiceUserPasswords ServiceUserPasswords `yaml:"service_user_passwords"`
AdminUserID string `yaml:"admin_user_id" env:"OCIS_ADMIN_USER_ID;IDM_ADMIN_USER_ID" desc:"ID of a user, that should receive admin privileges."`
Context context.Context `yaml:"-"`
}
type Settings struct {
LDAPSAddr string `yaml:"ldaps_addr" env:"IDM_LDAPS_ADDR" desc:"Listen address for the ldaps listener (ip-addr:port)"`
Cert string `yaml:"cert" env:"IDM_LDAPS_CERT" desc:"File name of the TLS server certificate for the ldaps listener"`
Key string `yaml:"key" env:"IDM_LDAPS_KEY" desc:"File name for the TLS certificate key for the server certificate"`
DatabasePath string `yaml:"database" env:"IDM_DATABASE_PATH" desc:"Full path to the idm backend database"`
}
type ServiceUserPasswords struct {
OcisAdmin string `yaml:"admin_password" env:"IDM_ADMIN_PASSWORD" desc:"Password to set for the ocis \"admin\" user. Either cleartext or an argon2id hash"`
Idm string `yaml:"idm_password" env:"IDM_SVC_PASSWORD" desc:"Password to set for the \"idm\" service user. Either cleartext or an argon2id hash"`
Reva string `yaml:"reva_password" env:"IDM_REVASVC_PASSWORD" desc:"Password to set for the \"reva\" service user. Either cleartext or an argon2id hash"`
Idp string `yaml:"idp_password" env:"IDM_IDPSVC_PASSWORD" desc:"Password to set for the \"idp\" service user. Either cleartext or an argon2id hash"`
}
+9
View File
@@ -0,0 +1,9 @@
package config
// Debug defines the available debug configuration.
type Debug struct {
Addr string `yaml:"addr" env:"IDM_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
Token string `yaml:"token" env:"IDM_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
Pprof bool `yaml:"pprof" env:"IDM_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
Zpages bool `yaml:"zpages" env:"IDM_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
}
@@ -0,0 +1,66 @@
package defaults
import (
"path"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config"
"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
)
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
func DefaultConfig() *config.Config {
return &config.Config{
Debug: config.Debug{
Addr: "127.0.0.1:9239",
},
Service: config.Service{
Name: "idm",
},
CreateDemoUsers: false,
IDM: config.Settings{
LDAPSAddr: "127.0.0.1:9235",
Cert: path.Join(defaults.BaseDataPath(), "idm", "ldap.crt"),
Key: path.Join(defaults.BaseDataPath(), "idm", "ldap.key"),
DatabasePath: path.Join(defaults.BaseDataPath(), "idm", "ocis.boltdb"),
},
}
}
func EnsureDefaults(cfg *config.Config) {
// provide with defaults for shared logging, since we need a valid destination address for BindEnv.
if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
cfg.Log = &config.Log{
Level: cfg.Commons.Log.Level,
Pretty: cfg.Commons.Log.Pretty,
Color: cfg.Commons.Log.Color,
File: cfg.Commons.Log.File,
}
} else if cfg.Log == nil {
cfg.Log = &config.Log{}
}
// provide with defaults for shared tracing, since we need a valid destination address for BindEnv.
if cfg.Tracing == nil && cfg.Commons != nil && cfg.Commons.Tracing != nil {
cfg.Tracing = &config.Tracing{
Enabled: cfg.Commons.Tracing.Enabled,
Type: cfg.Commons.Tracing.Type,
Endpoint: cfg.Commons.Tracing.Endpoint,
Collector: cfg.Commons.Tracing.Collector,
}
} else if cfg.Tracing == nil {
cfg.Tracing = &config.Tracing{}
}
if cfg.AdminUserID == "" && cfg.Commons != nil {
cfg.AdminUserID = cfg.Commons.AdminUserID
}
}
func Sanitize(cfg *config.Config) {
// nothing to sanitize here
}
+9
View File
@@ -0,0 +1,9 @@
package config
// Log defines the available log configuration.
type Log struct {
Level string `mapstructure:"level" env:"OCIS_LOG_LEVEL;IDM_LOG_LEVEL" desc:"The log level. Valid values are: \"panic\", \"fatal\", \"error\", \"warn\", \"info\", \"debug\", \"trace\"."`
Pretty bool `mapstructure:"pretty" env:"OCIS_LOG_PRETTY;IDM_LOG_PRETTY" desc:"Activates pretty log output."`
Color bool `mapstructure:"color" env:"OCIS_LOG_COLOR;IDM_LOG_COLOR" desc:"Activates colorized log output."`
File string `mapstructure:"file" env:"OCIS_LOG_FILE;IDM_LOG_FILE" desc:"The path to the log file. Activates logging to this file if set."`
}
+57
View File
@@ -0,0 +1,57 @@
package parser
import (
"errors"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
"github.com/owncloud/ocis/v2/ocis-pkg/config/envdecode"
)
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
return err
}
defaults.EnsureDefaults(cfg)
// load all env variables relevant to the config in the current context.
if err := envdecode.Decode(cfg); err != nil {
// no environment variable set for this config is an expected "error"
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
return err
}
}
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.AdminUserID == "" {
return shared.MissingAdminUserID(cfg.Service.Name)
}
if cfg.ServiceUserPasswords.Idm == "" {
return shared.MissingServiceUserPassword(cfg.Service.Name, "IDM")
}
if cfg.ServiceUserPasswords.OcisAdmin == "" {
return shared.MissingServiceUserPassword(cfg.Service.Name, "admin")
}
if cfg.ServiceUserPasswords.Idp == "" {
return shared.MissingServiceUserPassword(cfg.Service.Name, "IDP")
}
if cfg.ServiceUserPasswords.Reva == "" {
return shared.MissingServiceUserPassword(cfg.Service.Name, "REVA")
}
return nil
}
+6
View File
@@ -0,0 +1,6 @@
package config
// Service defines the available service configuration.
type Service struct {
Name string `yaml:"-"`
}
+9
View File
@@ -0,0 +1,9 @@
package config
// Tracing defines the available tracing configuration.
type Tracing struct {
Enabled bool `yaml:"enabled" env:"OCIS_TRACING_ENABLED;IDM_TRACING_ENABLED" desc:"Activates tracing."`
Type string `yaml:"type" env:"OCIS_TRACING_TYPE;IDM_TRACING_TYPE" desc:"The type of tracing. Defaults to \"\", which is the same as \"jaeger\". Allowed tracing types are \"jaeger\" and \"\" as of now."`
Endpoint string `yaml:"endpoint" env:"OCIS_TRACING_ENDPOINT;IDM_TRACING_ENDPOINT" desc:"The endpoint of the tracing agent."`
Collector string `yaml:"collector" env:"OCIS_TRACING_COLLECTOR;IDM_TRACING_COLLECTOR" desc:"The HTTP endpoint for sending spans directly to a collector, i.e. http://jaeger-collector:14268/api/traces. Only used if the tracing endpoint is unset."`
}
+17
View File
@@ -0,0 +1,17 @@
package logging
import (
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
)
// LoggerFromConfig initializes a service-specific logger instance.
func Configure(name string, cfg *config.Log) log.Logger {
return log.NewLogger(
log.Name(name),
log.Level(cfg.Level),
log.Pretty(cfg.Pretty),
log.Color(cfg.Color),
log.File(cfg.File),
)
}
+50
View File
@@ -0,0 +1,50 @@
package debug
import (
"context"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
)
// Option defines a single option function.
type Option func(o *Options)
// Options defines the available options for this package.
type Options struct {
Logger log.Logger
Context context.Context
Config *config.Config
}
// newOptions initializes the available default options.
func newOptions(opts ...Option) Options {
opt := Options{}
for _, o := range opts {
o(&opt)
}
return opt
}
// Logger provides a function to set the logger option.
func Logger(val log.Logger) Option {
return func(o *Options) {
o.Logger = val
}
}
// Context provides a function to set the context option.
func Context(val context.Context) Option {
return func(o *Options) {
o.Context = val
}
}
// Config provides a function to set the config option.
func Config(val *config.Config) Option {
return func(o *Options) {
o.Config = val
}
}
+59
View File
@@ -0,0 +1,59 @@
package debug
import (
"io"
"net/http"
"github.com/owncloud/ocis/v2/extensions/idm/pkg/config"
"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
)
// Server initializes the debug service and server.
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)
return debug.NewService(
debug.Logger(options.Logger),
debug.Name(options.Config.Service.Name),
debug.Version(version.GetString()),
debug.Address(options.Config.Debug.Addr),
debug.Token(options.Config.Debug.Token),
debug.Pprof(options.Config.Debug.Pprof),
debug.Zpages(options.Config.Debug.Zpages),
debug.Health(health(options.Config)),
debug.Ready(ready(options.Config)),
), nil
}
// health implements the health check.
func health(cfg *config.Config) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
// TODO: check if services are up and running
_, err := io.WriteString(w, http.StatusText(http.StatusOK))
// io.WriteString should not fail but if it does we want to know.
if err != nil {
panic(err)
}
}
}
// ready implements the ready check.
func ready(cfg *config.Config) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
// TODO: check if services are up and running
_, err := io.WriteString(w, http.StatusText(http.StatusOK))
// io.WriteString should not fail but if it does we want to know.
if err != nil {
panic(err)
}
}
}