• Где сисадмину хранить информацию?

    @mr-spouk
    использую luks-контейнер под .home/ раздел + отдельный luks-контейнер размером 1гиг под всякую приватную информацию, связанную с сисадминством/ключами/сертификатами/куками и прочее. Контейнер синхронизирую с домашним компом/ноутбуком/переносной жесткий диск. +контейнер VeraCrypt с аналогичными данными. Покрывает все запросы и позволяет не рвать на голове волосы в случае пропажи/воровства винта/ноутбука/компа.
    Ответ написан
    Комментировать
  • Как инициализировать конфиг для всего проекта?

    @mr-spouk
    В Go один из вариантов использование обобщенной структуры, в которой связываются остальные компоненты и модули. Для примера с собственного проекта пример обобщенной структуры
    type Server struct {
    	sync.WaitGroup
    	Mux          *chi.Mux
    	Log          *log.Logger
    	LogFile      *log.Logger
    	DB           *gorm.DB
    	Render       *render.Render
    	Convert      *convert.Convert
    	Transliter   *transliter.Transliter
    	Mailer       *mailer.Mail
    	Flash        *flash.Flash
    	Config       *Config
    	StaticStock  map[string]string //key = filesDir, []string = workDir
    	pool         sync.Pool
    	Forms        *forms.Form
    	Support      *support.Support
    	LogReaders   []LogReader
    	LogStock     []string
    	LogFH        *os.File
    	Paginator    *paginate.Paginate
    	Gobdump      *gobdump.Configdump
    	ConfigOrigin *Config
    	Uploader     *uploader.Uploader
    	Datetime    *Datetime
    }
    //иницализация для примера 
    func NewServer(originConfigUse bool) *Server {
    	//instance
    	s := new(Server)
    	//logger
    	s.Log = log.New(os.Stdout, SERVER, log.Ldate|log.Ltime|log.Lshortfile)
    	//gobdump
    	s.Gobdump = gobdump.NewConfigdump()
    	//config
    	cc := config.NewConf("config/dumpconfig.dmp", os.Stdout)
    	ci := new(Config)
    	if err := cc.ReadConfig("config/config.yaml", ci); err != nil {
    		s.Log.Fatal(err)
    	}
    	s.Config = ci
    
    	//assign config intance to SERVER
    	if originConfigUse == false {
    		s.ConfigOrigin = ci
    		s.Config = s.ConfigDumpRead(false)
    	}
    	//logfile
    	err := s.openLogs("logs")
    	if err != nil {
    		panic(err)
    	}
    	s.LogFile = log.New(s.LogFH, SERVER, log.Ldate|log.Ltime|log.Lshortfile)
    	//database
    
    	s.DatabaseConnect(ListTables)
    	//render
    	s.Render = render.NewRender(s.Config.TemplatePath, s.Config.TemplateDebug, s.Log, s.Config.TemplateDebugFatal)
    	//add user functions
    	s.Render.AddUserFilter("loop", s.Loop)
    	s.Render.AddUserFilter("loopstr", s.LoopStr)
    	s.Render.AddUserFilter("addstr", s.AddStr)
    	//s.Render.AddUserFilter("substr", s.SubStr)
    	//s.Render.AddUserFilter("intstr", s.IntToStr)
    	//transliter
    	s.Transliter = transliter.NewTransliter()
    	//mailer
    	s.Mailer = mailer.NewMail()
    	//flash
    	s.Flash = flash.NewFlash(s.Config.FlashSalt)
    	//converter
    	s.Convert = convert.NewConverter(s.Log)
    	//staticstock
    	s.StaticStock = make(map[string]string)
    	//chi router
    	s.Mux = chi.NewRouter()
    
    	//pool
    	s.pool = sync.Pool{}
    	s.pool.New = func() interface{} {
    		return &Data{
    			Server: s,
    			Flash:  flash.NewFlash(s.Config.FlashSalt),
    			Stock:  databox.NewData(),
    		}
    	}
    	//forms
    	s.Forms = forms.NewForm()
    	s.Forms.LoadFieldForms(formsdata)
    	//support
    	s.Support = support.NewSupport()
    	//добавление админа по умолчанию на основе данных из конфига
    	if err := s.addDefaultAdmin(); err != nil {
    		s.Log.Fatal(err)
    	}
    	//запуск горутин
    	s.Add(2)
    	go s.gorExpiredLogedUser(time.Minute * 60)
    	go s.gorPulicatePostLaterData(time.Minute * 2)
    
    	//paginator
    	pagparams := &paginate.Params{
    		Limit:      s.Config.PaginateCountOnPage,
    		DBS:        s.DB,
    		DebugQuery: s.Config.PaginateDebug,
    		SortTypes:  s.Config.PaginateSortType,
    		CountLinks: s.Config.PaginateCountLinks,
    	}
    	s.Paginator = paginate.NewPaginate(pagparams)
    
    	//uploader
    	s.Uploader = uploader.NewUploader()
    
    	//datetime
    	s.Datetime = NewDateTimeList(2019)
    
    	//back result
    	return s
    }


    Привязка конфига идет к ConfigOrigin *Config
    Структура конфига + пакет для обработки его

    package lib
    
    import "time"
    
    type Config struct {
    	//global
    	TemplatePath          string        `yaml:"templatepath"`
    	TemplateDebug         bool          `yaml:"templatedebug"`
    	TemplateDebugFatal    bool          `yaml:"teamplatedebugfatal"`
    	AdressHTTP            string        `yaml:"adresshttp"`
    	ReadTimeout           time.Duration `yaml:"readtimeout"`
    	WriteTimeout          time.Duration `yaml:"writetimeout"`
    	CertFile              string        `yaml:"certfile"`
    	KeyFile               string        `yaml:"keyfile"`
    	RedirectTrailingSlash bool          `yaml:"redirecttrailingslash"`
    	RedirectFixedPath     bool          `yaml:"redirectfixedpath"`
    	Logfile               string        `yaml:"logfile"`
    	//roles
    	Roles      []string `yaml:"roles"`
    	RolesAdmin []string `yaml:"rolesadmin"`
    	//database
    	DBTypeDB             string `yaml:"dbtypedb"`
    	DBHost               string `yaml:"dbhost"`
    	DBPort               int    `yaml:"dbport"`
    	DBUser               string `yaml:"dbuser"`
    	DBPassword           string `yaml:"dbpassword"`
    	DBDatabase           string `yaml:"dbdatabase"`
    	DBSSLMode            bool   `yaml:"dbsslmode"`
    	DBSetMaxIdleConns    int    `yaml:"dbsetmaxidleconns"`
    	DBSetMaxOpenConns    int    `yaml:"dbsetmaxopenconns"`
    	DBSetConnMaxLifetime int    `yaml:"dbsetconnmaxlifetime"`
    	//project
    	PaginateCountOnPage int      `yaml:"paginatecountonpage"`
    	PaginateCountLinks  int      `yaml:"paginatecountlinks"`
    	PaginateSortType    []string `yaml:"paginatesorttype"`
    	PaginateDebug       bool     `yaml:"paginatedebug"`
    	UploadPath          string   `yaml:"uploadpath"`
    	SitemapPath         string   `yaml:"sitemappath"`
    	SitemapHost         string   `yaml:"sitemaphost"`
    	HostFullPathHTTP    string   `yaml:"hostfullpathhttp"`
    	HostFullPathHTTPS   string   `yaml:"hostfullpathhttps"`
    	SeoTitle            string   `yaml:"seotitle"`
    	SeoDesc             string   `yaml:"seodesc"`
    	SeoKeys             string   `yaml:"seokeys"`
    	SeoRobot            string   `yaml:"seorobot"`
    	LaterPostTimePeriod int      `yaml:"laterposttimeperiod"`
    	//session
    	MailTo               string        `yaml:"mailto"`
    	MailFrom             string        `yaml:"mailfrom"`
    	MailHost             string        `yaml:"mailhost"`
    	MailPort             int           `yaml:"mailport"`
    	MailUsername         string        `yaml:"mailusername"`
    	MailPassword         string        `yaml:"mailpassword"`
    	CSRFTimeActive       int           `yaml:"csrftimeactive"`
    	CSRFSalt             string        `yaml:"csrfsalt"`
    	CookieName           string        `yaml:"cookiename"`
    	CookieDomain         string        `yaml:"cookiedomain"`
    	CookieExpired        int64         `yaml:"cookieexpired"`
    	CookieSalt           string        `yaml:"cookiesalt"`
    	RoleDefaultUser      string        `yaml:"roledefaultuser"`
    	SessionTime          time.Duration `yaml:"sessiontime"`
    	SessionTimeExpired   time.Duration `yaml:"sessiontimeexpired"`
    	SessionTimeSave      time.Duration `yaml:"sessiontimesave"`
    	SessionPathSave      string        `yaml:"pathsavesession"`
    	TimerTime            time.Duration `yaml:"timertime"`
    	SleepTimeCatcher     time.Duration `yaml:"sleeptimecatcher"`
    	DeferPostSleepTime   time.Duration `yaml:"deferpostsleeptime"`
    	DeferPostTime        time.Duration `yaml:"deferposttime"`
    	ContactReview        []string      `yaml:"contactreview"`
    	FlashSalt            string        `yaml:"flashsatl"`
    	DefaultUserCookie    string        `yaml:"defaultusercookie"`
    	DefaultAdminEmail    string        `yaml:"defaultadminemail"`
    	DefaultAdminPassword string        `yaml:"defaultadminpassword"`
    	DefaultAdminRole     string        `yaml:"defaultadminrole"`
    	RedisAdress          string        `yaml:"redisadress"`
    	RedisDB              int           `yaml:"redisdb"`
    	RedisPassword        string        `yaml:"redispassword"`
    	DumpConfigFile       string        `yaml:"dumpconfigfile"`
    	//oauth2 authorization
    	// +vk+
    	O2vkid       string `yaml:"o2vkid"`
    	O2vkkey      string `yaml:"o2vkkey"`
    	O2vkcallback string `yaml:"o2vkcallback"`
    	o2vkscope    []string `yaml:"o2vkscope"`
    	// +yandex+
    	O2yandexid       string `yaml:"o2yandexid"`
    	O2yandexkey      string `yaml:"o2yandexkey"`
    	O2yandexcallback string `yaml:"o2yandexcallback"`
    	o2yandexscope    []string `yaml:"o2yandexscope"`
    	// +google+
    	O2googleid       string   `yaml:"o2googleid"`
    	O2googlekey      string   `yaml:"o2googlekey"`
    	O2googlecallback string   `yaml:"o2googlecallback"`
    	O2googlescope    []string `yaml"o2googlescope"`
    }
    
    package config
    
    import (
    	"os"
    	"log"
    	"io/ioutil"
    	"encoding/gob"
    	"github.com/go-yaml/yaml"
    	"io"
    )
    
    const (
    	logConfigPrefix           = "[config-log] "
    	logConfigFlags            = log.Ldate | log.Ltime | log.Lshortfile
    	msgsuccessReadDumpConfig  = "дамп конфига успешно прочитан"
    	msgsuccessWriteDumpConfig = "дамп конфига успешно записан"
    
    	dumpfileflag = os.O_CREATE | os.O_RDWR | os.O_TRUNC
    	dumpfileperm = 0666
    )
    
    //---------------------------------------------------------------------------
    //  example other config
    //---------------------------------------------------------------------------
    type Conf struct {
    	Log            *log.Logger
    	PathDumpconfig string
    }
    
    func (c *Conf) ReadConfig(fileConfig string, exConf interface{}) (error) {
    	//открываю файл конфигурации
    	f, err := os.Open(fileConfig)
    	if err != nil {
    		return err
    	}
    	//читаю файл конфига
    	b, err := ioutil.ReadAll(f)
    	if err != nil {
    		return err
    	}
    	//конвертирую его в структуру
    	err = yaml.Unmarshal(b, exConf)
    	if err != nil {
    		return err
    	}
    	return nil
    }
    func NewConf(pathDumpconfig string, logout io.Writer) *Conf {
    	n := &Conf{
    		PathDumpconfig: pathDumpconfig,
    	}
    	if logout == nil {
    		n.Log = log.New(os.Stdout, logConfigPrefix, logConfigFlags)
    	} else {
    		n.Log = log.New(logout, logConfigPrefix, logConfigFlags)
    	}
    	return n
    }
    
    //запись дампа конфигурационного файла
    func (c *Conf) WriteDumpConfig(config interface{}) error {
    	f, err := os.OpenFile(c.PathDumpconfig, dumpfileflag, dumpfileperm)
    	if err != nil {
    		return err
    	}
    	defer f.Close()
    	enc := gob.NewEncoder(f)
    	err = enc.Encode(config)
    	if err != nil {
    		return err
    	}
    	if c.Log != nil {
    		c.Log.Printf(msgsuccessWriteDumpConfig)
    		return err
    	}
    	return nil
    }
    
    
    
    //читаем дамп конфигурационного файла
    func (c *Conf) ReadDumpConfig(config interface{}) (error) {
    	f, err := os.Open(c.PathDumpconfig)
    	if err != nil {
    		return err
    	}
    	defer f.Close()
    	dec := gob.NewDecoder(f)
    	err = dec.Decode(config)
    	if err != nil {
    		return err
    	}
    	c.Log.Printf(msgsuccessReadDumpConfig)
    	return nil
    }
    Ответ написан
    Комментировать