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

     1  package azure
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  
     7  	typesazure "github.com/openshift/installer/pkg/types/azure"
     8  )
     9  
    10  // Metadata holds additional metadata for InstallConfig resources that
    11  // does not need to be user-supplied (e.g. because it can be retrieved
    12  // from external APIs).
    13  type Metadata struct {
    14  	session *Session
    15  	client  *Client
    16  	dnsCfg  *DNSConfig
    17  
    18  	// CloudName indicates the Azure cloud environment (e.g. public, gov't).
    19  	CloudName typesazure.CloudEnvironment `json:"cloudName,omitempty"`
    20  
    21  	// ARMEndpoint indicates the resource management API endpoint used by AzureStack.
    22  	ARMEndpoint string `json:"armEndpoint,omitempty"`
    23  
    24  	// Credentials hold prepopulated Azure credentials.
    25  	// At the moment the installer doesn't use it and reads credentials
    26  	// from the file system, but external consumers of the package can
    27  	// provide credentials. This is useful when we run the installer
    28  	// as a service (Azure Red Hat OpenShift, for example): in this case
    29  	// we do not want to rely on the filesystem or user input as we
    30  	// serve multiple users with different credentials via a web server.
    31  	Credentials *Credentials `json:"credentials,omitempty"`
    32  
    33  	mutex sync.Mutex
    34  }
    35  
    36  // NewMetadata initializes a new Metadata object.
    37  func NewMetadata(cloudName typesazure.CloudEnvironment, armEndpoint string) *Metadata {
    38  	return NewMetadataWithCredentials(cloudName, armEndpoint, nil)
    39  }
    40  
    41  // NewMetadataWithCredentials initializes a new Metadata object
    42  // with prepopulated Azure credentials.
    43  func NewMetadataWithCredentials(cloudName typesazure.CloudEnvironment, armEndpoint string, credentials *Credentials) *Metadata {
    44  	return &Metadata{
    45  		CloudName:   cloudName,
    46  		ARMEndpoint: armEndpoint,
    47  		Credentials: credentials,
    48  	}
    49  }
    50  
    51  // Session holds an Azure session which can be used for Azure API calls
    52  // during asset generation.
    53  func (m *Metadata) Session() (*Session, error) {
    54  	m.mutex.Lock()
    55  	defer m.mutex.Unlock()
    56  
    57  	return m.unlockedSession()
    58  }
    59  
    60  func (m *Metadata) unlockedSession() (*Session, error) {
    61  	if m.session == nil {
    62  		var err error
    63  		m.session, err = GetSessionWithCredentials(m.CloudName, m.ARMEndpoint, m.Credentials)
    64  		if err != nil {
    65  			return nil, fmt.Errorf("creating Azure session: %w", err)
    66  		}
    67  	}
    68  
    69  	return m.session, nil
    70  }
    71  
    72  // Client holds an Azure Client that implements calls to the Azure API.
    73  func (m *Metadata) Client() (*Client, error) {
    74  	if m.client == nil {
    75  		ssn, err := m.Session()
    76  		if err != nil {
    77  			return nil, err
    78  		}
    79  		m.client = NewClient(ssn)
    80  	}
    81  	return m.client, nil
    82  }
    83  
    84  // DNSConfig holds an Azure DNSConfig Client that implements calls to the Azure API.
    85  func (m *Metadata) DNSConfig() (*DNSConfig, error) {
    86  	if m.dnsCfg == nil {
    87  		ssn, err := m.Session()
    88  		if err != nil {
    89  			return nil, err
    90  		}
    91  		m.dnsCfg = NewDNSConfig(ssn)
    92  	}
    93  	return m.dnsCfg, nil
    94  }