consul/command/services/config.go

112 lines
3.3 KiB
Go
Raw Permalink Normal View History

// Copyright (c) HashiCorp, Inc.
[COMPLIANCE] License changes (#18443) * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-11 13:12:13 +00:00
// SPDX-License-Identifier: BUSL-1.1
package services
2018-09-28 06:52:17 +00:00
import (
"reflect"
"time"
"github.com/mitchellh/cli"
"github.com/mitchellh/mapstructure"
"github.com/hashicorp/consul/agent/config"
"github.com/hashicorp/consul/agent/structs"
2018-09-28 06:52:17 +00:00
"github.com/hashicorp/consul/api"
)
// ServicesFromFiles returns the list of agent service registration structs
// from a set of file arguments.
func ServicesFromFiles(ui cli.Ui, files []string) ([]*api.AgentServiceRegistration, error) {
// We set devMode to true so we can get the basic valid default
// configuration. devMode doesn't set any services by default so this
// is okay since we only look at services.
devMode := true
r, err := config.Load(config.LoadOpts{
ConfigFiles: files,
DevMode: &devMode,
})
if err != nil {
return nil, err
}
for _, w := range r.Warnings {
ui.Warn(w)
}
// The services are now in "structs.ServiceDefinition" form and we need
// them in "api.AgentServiceRegistration" form so do the conversion.
services := r.RuntimeConfig.Services
result := make([]*api.AgentServiceRegistration, 0, len(services))
for _, svc := range services {
apiSvc, err := serviceToAgentService(svc)
if err != nil {
return nil, err
}
result = append(result, apiSvc)
}
return result, nil
}
// serviceToAgentService converts a ServiceDefinition struct to an
2018-09-28 06:52:17 +00:00
// AgentServiceRegistration API struct.
func serviceToAgentService(svc *structs.ServiceDefinition) (*api.AgentServiceRegistration, error) {
// mapstructure can do this for us, but we encapsulate it in this
// helper function in case we need to change the logic in the future.
2018-09-28 06:52:17 +00:00
var result api.AgentServiceRegistration
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Result: &result,
DecodeHook: timeDurationToStringHookFunc(),
WeaklyTypedInput: true,
})
if err != nil {
return nil, err
}
if err := d.Decode(svc); err != nil {
return nil, err
}
// The structs version has non-pointer checks and the destination
// has pointers, so we need to set the destination to nil if there
// is a zero-value Check field.
if result.Check != nil && reflect.DeepEqual(*result.Check, api.AgentServiceCheck{}) {
result.Check = nil
}
// The structs version has non-pointer Proxy.TransparentProxy and Proxy.AccessLogs
// The destination has pointers, so we need to set the destination to nil if there
// is a zero-value field.
if result.Proxy != nil && result.Proxy.TransparentProxy != nil && reflect.DeepEqual(*result.Proxy.TransparentProxy, api.TransparentProxyConfig{}) {
result.Proxy.TransparentProxy = nil
}
if result.Proxy != nil && result.Proxy.AccessLogs != nil && reflect.DeepEqual(*result.Proxy.AccessLogs, api.AccessLogsConfig{}) {
result.Proxy.AccessLogs = nil
}
return &result, nil
}
// timeDurationToStringHookFunc returns a DecodeHookFunc that converts
// time.Duration to string.
func timeDurationToStringHookFunc() mapstructure.DecodeHookFunc {
return func(
f reflect.Type,
t reflect.Type,
data interface{}) (interface{}, error) {
dur, ok := data.(time.Duration)
if !ok {
return data, nil
}
if t.Kind() != reflect.String {
return data, nil
}
if dur == 0 {
return "", nil
}
// Convert it by parsing
return data.(time.Duration).String(), nil
}
2018-09-28 06:52:17 +00:00
}