github.com/openshift/installer@v1.4.17/pkg/asset/installconfig/openstack/session.go (about)

     1  // Package openstack collects OpenStack-specific configuration.
     2  package openstack
     3  
     4  import (
     5  	"fmt"
     6  	"sync"
     7  
     8  	"github.com/gophercloud/utils/v2/openstack/clientconfig"
     9  	"github.com/sirupsen/logrus"
    10  	"sigs.k8s.io/yaml"
    11  
    12  	openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults"
    13  )
    14  
    15  var onceLoggers = map[string]*sync.Once{}
    16  
    17  // Session is an object representing session for OpenStack.
    18  type Session struct {
    19  	CloudConfig *clientconfig.Cloud
    20  	ClientOpts  *clientconfig.ClientOpts
    21  }
    22  
    23  // GetSession returns an OpenStack session for a given cloud name in clouds.yaml.
    24  func GetSession(cloudName string) (*Session, error) {
    25  	opts := openstackdefaults.DefaultClientOpts(cloudName)
    26  	opts.YAMLOpts = new(yamlLoadOpts)
    27  
    28  	cloudConfig, err := clientconfig.GetCloudFromYAML(opts)
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	return &Session{
    33  		CloudConfig: cloudConfig,
    34  		ClientOpts:  opts,
    35  	}, nil
    36  }
    37  
    38  type yamlLoadOpts struct{}
    39  
    40  func (opts yamlLoadOpts) LoadCloudsYAML() (map[string]clientconfig.Cloud, error) {
    41  	var clouds clientconfig.Clouds
    42  	content, err := loadAndLog(clientconfig.FindAndReadCloudsYAML)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  	err = yaml.Unmarshal(content, &clouds)
    47  	if err != nil {
    48  		return nil, fmt.Errorf("failed to unmarshal yaml: %w", err)
    49  	}
    50  
    51  	return clouds.Clouds, nil
    52  }
    53  
    54  func (opts yamlLoadOpts) LoadSecureCloudsYAML() (map[string]clientconfig.Cloud, error) {
    55  	var clouds clientconfig.Clouds
    56  	content, err := loadAndLog(clientconfig.FindAndReadSecureCloudsYAML)
    57  	if err != nil {
    58  		if err.Error() == "no secure.yaml file found" {
    59  			// secure.yaml is optional so just ignore read error
    60  			return clouds.Clouds, nil
    61  		}
    62  	}
    63  	err = yaml.Unmarshal(content, &clouds)
    64  	if err != nil {
    65  		return nil, fmt.Errorf("failed to unmarshal yaml: %w", err)
    66  	}
    67  	return clouds.Clouds, err
    68  }
    69  
    70  func (opts yamlLoadOpts) LoadPublicCloudsYAML() (map[string]clientconfig.Cloud, error) {
    71  	var publicClouds clientconfig.PublicClouds
    72  	content, err := loadAndLog(clientconfig.FindAndReadPublicCloudsYAML)
    73  	if err != nil {
    74  		if err.Error() == "no clouds-public.yaml file found" {
    75  			// clouds-public.yaml is optional so just ignore read error
    76  			return publicClouds.Clouds, nil
    77  		}
    78  	}
    79  	err = yaml.Unmarshal(content, &publicClouds)
    80  	if err != nil {
    81  		return nil, fmt.Errorf("failed to unmarshal yaml: %w", err)
    82  	}
    83  	return publicClouds.Clouds, err
    84  }
    85  
    86  func loadAndLog(fn func() (string, []byte, error)) ([]byte, error) {
    87  	filename, content, err := fn()
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  
    92  	if _, has := onceLoggers[filename]; !has {
    93  		onceLoggers[filename] = new(sync.Once)
    94  	}
    95  	onceLoggers[filename].Do(func() {
    96  		logrus.Infof("Credentials loaded from file %q", filename)
    97  	})
    98  
    99  	return content, nil
   100  }