Moved v3 code from NginxProxyManager/nginx-proxy-manager-3 to NginxProxyManager/nginx-proxy-manager

This commit is contained in:
Jamie Curnow
2022-05-12 08:47:31 +10:00
parent 4db34f5894
commit 2110ecc382
830 changed files with 38168 additions and 36635 deletions

View File

@ -0,0 +1,25 @@
package dnsprovider
import (
"npm/internal/entity"
)
var filterMapFunctions = make(map[string]entity.FilterMapFunction)
// getFilterMapFunctions is a map of functions that should be executed
// during the filtering process, if a field is defined here then the value in
// the filter will be given to the defined function and it will return a new
// value for use in the sql query.
func getFilterMapFunctions() map[string]entity.FilterMapFunction {
// if len(filterMapFunctions) == 0 {
// TODO: See internal/model/file_item.go:620 for an example
// }
return filterMapFunctions
}
// GetFilterSchema returns filter schema
func GetFilterSchema() string {
var m Model
return entity.GetFilterSchema(m)
}

View File

@ -0,0 +1,134 @@
package dnsprovider
import (
"database/sql"
goerrors "errors"
"fmt"
"npm/internal/database"
"npm/internal/entity"
"npm/internal/errors"
"npm/internal/logger"
"npm/internal/model"
)
// GetByID finds a row by ID
func GetByID(id int) (Model, error) {
var m Model
err := m.LoadByID(id)
return m, err
}
// Create will create a row from this model
func Create(provider *Model) (int, error) {
if provider.ID != 0 {
return 0, goerrors.New("Cannot create dns provider when model already has an ID")
}
provider.Touch(true)
db := database.GetInstance()
// nolint: gosec
result, err := db.NamedExec(`INSERT INTO `+fmt.Sprintf("`%s`", tableName)+` (
created_on,
modified_on,
user_id,
name,
acmesh_name,
dns_sleep,
meta,
is_deleted
) VALUES (
:created_on,
:modified_on,
:user_id,
:name,
:acmesh_name,
:dns_sleep,
:meta,
:is_deleted
)`, provider)
if err != nil {
return 0, err
}
last, lastErr := result.LastInsertId()
if lastErr != nil {
return 0, lastErr
}
return int(last), nil
}
// Update will Update a row from this model
func Update(provider *Model) error {
if provider.ID == 0 {
return goerrors.New("Cannot update dns provider when model doesn't have an ID")
}
provider.Touch(false)
db := database.GetInstance()
// nolint: gosec
_, err := db.NamedExec(`UPDATE `+fmt.Sprintf("`%s`", tableName)+` SET
created_on = :created_on,
modified_on = :modified_on,
user_id = :user_id,
name = :name,
acmesh_name = :acmesh_name,
dns_sleep = :dns_sleep,
meta = :meta,
is_deleted = :is_deleted
WHERE id = :id`, provider)
return err
}
// List will return a list of certificates
func List(pageInfo model.PageInfo, filters []model.Filter) (ListResponse, error) {
var result ListResponse
var exampleModel Model
defaultSort := model.Sort{
Field: "name",
Direction: "ASC",
}
db := database.GetInstance()
if db == nil {
return result, errors.ErrDatabaseUnavailable
}
// Get count of items in this search
query, params := entity.ListQueryBuilder(exampleModel, tableName, &pageInfo, defaultSort, filters, getFilterMapFunctions(), true)
countRow := db.QueryRowx(query, params...)
var totalRows int
queryErr := countRow.Scan(&totalRows)
if queryErr != nil && queryErr != sql.ErrNoRows {
logger.Error("ListDnsProvidersError", queryErr)
logger.Debug("%s -- %+v", query, params)
return result, queryErr
}
// Get rows
var items []Model
query, params = entity.ListQueryBuilder(exampleModel, tableName, &pageInfo, defaultSort, filters, getFilterMapFunctions(), false)
err := db.Select(&items, query, params...)
if err != nil {
logger.Error("ListDnsProvidersError", err)
logger.Debug("%s -- %+v", query, params)
return result, err
}
result = ListResponse{
Items: items,
Total: totalRows,
Limit: pageInfo.Limit,
Offset: pageInfo.Offset,
Sort: pageInfo.Sort,
Filter: filters,
}
return result, nil
}

View File

@ -0,0 +1,101 @@
package dnsprovider
import (
"fmt"
"time"
"npm/internal/database"
"npm/internal/dnsproviders"
"npm/internal/logger"
"npm/internal/types"
)
const (
tableName = "dns_provider"
)
// Model is the user model
// Also see: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
type Model struct {
ID int `json:"id" db:"id" filter:"id,integer"`
CreatedOn types.DBDate `json:"created_on" db:"created_on" filter:"created_on,integer"`
ModifiedOn types.DBDate `json:"modified_on" db:"modified_on" filter:"modified_on,integer"`
UserID int `json:"user_id" db:"user_id" filter:"user_id,integer"`
Name string `json:"name" db:"name" filter:"name,string"`
AcmeshName string `json:"acmesh_name" db:"acmesh_name" filter:"acmesh_name,string"`
DNSSleep int `json:"dns_sleep" db:"dns_sleep" filter:"dns_sleep,integer"`
Meta types.JSONB `json:"meta" db:"meta"`
IsDeleted bool `json:"is_deleted,omitempty" db:"is_deleted"`
}
func (m *Model) getByQuery(query string, params []interface{}) error {
return database.GetByQuery(m, query, params)
}
// LoadByID will load from an ID
func (m *Model) LoadByID(id int) error {
query := fmt.Sprintf("SELECT * FROM `%s` WHERE id = ? AND is_deleted = ? LIMIT 1", tableName)
params := []interface{}{id, 0}
return m.getByQuery(query, params)
}
// Touch will update model's timestamp(s)
func (m *Model) Touch(created bool) {
var d types.DBDate
d.Time = time.Now()
if created {
m.CreatedOn = d
}
m.ModifiedOn = d
}
// Save will save this model to the DB
func (m *Model) Save() error {
var err error
if m.UserID == 0 {
return fmt.Errorf("User ID must be specified")
}
if m.ID == 0 {
m.ID, err = Create(m)
} else {
err = Update(m)
}
return err
}
// Delete will mark a certificate as deleted
func (m *Model) Delete() bool {
m.Touch(false)
m.IsDeleted = true
if err := m.Save(); err != nil {
return false
}
return true
}
// GetAcmeShEnvVars returns the env vars required for acme.sh dns cert requests
func (m *Model) GetAcmeShEnvVars() ([]string, error) {
logger.Debug("GetAcmeShEnvVars for: %s", m.AcmeshName)
// First, fetch the provider obj with this AcmeShName
acmeDNSProvider, err := dnsproviders.Get(m.AcmeshName)
logger.Debug("acmeDNSProvider: %+v", acmeDNSProvider)
if err != nil {
logger.Error("GetAcmeShEnvVarsError", err)
return nil, err
}
envs := make([]string, 0)
// Then, using the meta, convert to env vars
envPairs := acmeDNSProvider.GetAcmeEnvVars(m.Meta.Decoded)
logger.Debug("meta: %+v", m.Meta)
logger.Debug("envPairs: %+v", envPairs)
for envName, envValue := range envPairs {
envs = append(envs, fmt.Sprintf(`%s=%v`, envName, envValue))
}
return envs, nil
}

View File

@ -0,0 +1,82 @@
package dnsprovider
import (
"encoding/json"
"npm/internal/types"
"testing"
"github.com/stretchr/testify/assert"
)
func TestModelGetAcmeShEnvVars(t *testing.T) {
type want struct {
envs []string
err error
}
tests := []struct {
name string
dnsProvider Model
metaJSON string
want want
}{
{
name: "dns_aws",
dnsProvider: Model{
AcmeshName: "dns_aws",
},
metaJSON: `{"access_key_id":"sdfsdfsdfljlbjkljlkjsdfoiwje","access_key":"xxxxxxx"}`,
want: want{
envs: []string{
`AWS_ACCESS_KEY_ID=sdfsdfsdfljlbjkljlkjsdfoiwje`,
`AWS_SECRET_ACCESS_KEY=xxxxxxx`,
},
err: nil,
},
},
{
name: "dns_cf",
dnsProvider: Model{
AcmeshName: "dns_cf",
},
metaJSON: `{"api_key":"sdfsdfsdfljlbjkljlkjsdfoiwje","email":"me@example.com","token":"dkfjghdk","account_id":"hgbdjfg","zone_id":"ASDASD"}`,
want: want{
envs: []string{
`CF_Token=dkfjghdk`,
`CF_Account_ID=hgbdjfg`,
`CF_Zone_ID=ASDASD`,
`CF_Key=sdfsdfsdfljlbjkljlkjsdfoiwje`,
`CF_Email=me@example.com`,
},
err: nil,
},
},
{
name: "dns_duckdns",
dnsProvider: Model{
AcmeshName: "dns_duckdns",
},
metaJSON: `{"api_key":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"}`,
want: want{
envs: []string{
`DuckDNS_Token=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee`,
},
err: nil,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var meta types.JSONB
err := json.Unmarshal([]byte(tt.metaJSON), &meta.Decoded)
assert.Equal(t, nil, err)
tt.dnsProvider.Meta = meta
envs, err := tt.dnsProvider.GetAcmeShEnvVars()
assert.Equal(t, tt.want.err, err)
for _, i := range tt.want.envs {
assert.Contains(t, envs, i)
}
})
}
}

View File

@ -0,0 +1,15 @@
package dnsprovider
import (
"npm/internal/model"
)
// ListResponse is the JSON response for the list
type ListResponse struct {
Total int `json:"total"`
Offset int `json:"offset"`
Limit int `json:"limit"`
Sort []model.Sort `json:"sort"`
Filter []model.Filter `json:"filter,omitempty"`
Items []Model `json:"items,omitempty"`
}