github.com/openshift/installer@v1.4.17/pkg/agent/rest.go (about)

     1  package agent
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"net/url"
     7  
     8  	"github.com/go-openapi/strfmt"
     9  	"github.com/pkg/errors"
    10  	"github.com/sirupsen/logrus"
    11  
    12  	"github.com/openshift/assisted-service/api/v1beta1"
    13  	"github.com/openshift/assisted-service/client"
    14  	"github.com/openshift/assisted-service/client/events"
    15  	"github.com/openshift/assisted-service/client/installer"
    16  	"github.com/openshift/assisted-service/models"
    17  	"github.com/openshift/installer/pkg/asset/agent/agentconfig"
    18  	"github.com/openshift/installer/pkg/asset/agent/gencrypto"
    19  	"github.com/openshift/installer/pkg/asset/agent/image"
    20  	"github.com/openshift/installer/pkg/asset/agent/manifests"
    21  	"github.com/openshift/installer/pkg/asset/installconfig"
    22  	assetstore "github.com/openshift/installer/pkg/asset/store"
    23  	"github.com/openshift/installer/pkg/types/agent"
    24  )
    25  
    26  // NodeZeroRestClient is a struct to interact with the Agent Rest API that is on node zero.
    27  type NodeZeroRestClient struct {
    28  	Client     *client.AssistedInstall
    29  	ctx        context.Context
    30  	config     client.Config
    31  	NodeZeroIP string
    32  	NodeSSHKey []string
    33  }
    34  
    35  // NewNodeZeroRestClient Initialize a new rest client to interact with the Agent Rest API on node zero.
    36  func NewNodeZeroRestClient(ctx context.Context, rendezvousIP, sshKey, token string) *NodeZeroRestClient {
    37  	restClient := &NodeZeroRestClient{}
    38  
    39  	// Get SSH Keys which can be used to determine if Rest API failures are due to network connectivity issues
    40  	if sshKey != "" {
    41  		restClient.NodeSSHKey = append(restClient.NodeSSHKey, sshKey)
    42  	}
    43  
    44  	config := client.Config{}
    45  	config.URL = &url.URL{
    46  		Scheme: "http",
    47  		Host:   net.JoinHostPort(rendezvousIP, "8090"),
    48  		Path:   client.DefaultBasePath,
    49  	}
    50  
    51  	config.AuthInfo = gencrypto.UserAuthHeaderWriter(token)
    52  
    53  	client := client.New(config)
    54  
    55  	restClient.Client = client
    56  	restClient.ctx = ctx
    57  	restClient.config = config
    58  	restClient.NodeZeroIP = rendezvousIP
    59  
    60  	return restClient
    61  }
    62  
    63  // FindRendezvouIPAndSSHKeyFromAssetStore returns the rendezvousIP and public ssh key.
    64  func FindRendezvouIPAndSSHKeyFromAssetStore(assetDir string) (string, string, error) {
    65  	agentConfigAsset := &agentconfig.AgentConfig{}
    66  	agentManifestsAsset := &manifests.AgentManifests{}
    67  	installConfigAsset := &installconfig.InstallConfig{}
    68  	agentHostsAsset := &agentconfig.AgentHosts{}
    69  
    70  	assetStore, err := assetstore.NewStore(assetDir)
    71  	if err != nil {
    72  		return "", "", errors.Wrap(err, "failed to create asset store")
    73  	}
    74  
    75  	agentConfig, agentConfigError := assetStore.Load(agentConfigAsset)
    76  	agentManifests, manifestError := assetStore.Load(agentManifestsAsset)
    77  	installConfig, installConfigError := assetStore.Load(installConfigAsset)
    78  	agentHosts, agentHostsError := assetStore.Load(agentHostsAsset)
    79  
    80  	if agentConfigError != nil {
    81  		logrus.Debug(errors.Wrapf(agentConfigError, "failed to load %s", agentConfigAsset.Name()))
    82  	}
    83  	if manifestError != nil {
    84  		logrus.Debug(errors.Wrapf(manifestError, "failed to load %s", agentManifestsAsset.Name()))
    85  	}
    86  	if installConfigError != nil {
    87  		logrus.Debug(errors.Wrapf(installConfigError, "failed to load %s", installConfigAsset.Name()))
    88  	}
    89  	if agentHostsError != nil {
    90  		logrus.Debug(errors.Wrapf(agentConfigError, "failed to load %s", agentHostsAsset.Name()))
    91  	}
    92  	if agentConfigError != nil || manifestError != nil || installConfigError != nil || agentHostsError != nil {
    93  		return "", "", errors.New("failed to load AgentConfig, NMStateConfig, InstallConfig, or AgentHosts")
    94  	}
    95  
    96  	var rendezvousIP string
    97  	var rendezvousIPError error
    98  	var emptyNMStateConfigs []*v1beta1.NMStateConfig
    99  
   100  	if agentConfig != nil && agentManifests != nil {
   101  		rendezvousIP, rendezvousIPError = image.RetrieveRendezvousIP(agentConfig.(*agentconfig.AgentConfig).Config, agentHosts.(*agentconfig.AgentHosts).Hosts, agentManifests.(*manifests.AgentManifests).NMStateConfigs)
   102  	} else if agentConfig == nil && agentManifests != nil {
   103  		rendezvousIP, rendezvousIPError = image.RetrieveRendezvousIP(&agent.Config{}, agentHosts.(*agentconfig.AgentHosts).Hosts, agentManifests.(*manifests.AgentManifests).NMStateConfigs)
   104  	} else if agentConfig != nil && agentManifests == nil {
   105  		rendezvousIP, rendezvousIPError = image.RetrieveRendezvousIP(agentConfig.(*agentconfig.AgentConfig).Config, agentHosts.(*agentconfig.AgentHosts).Hosts, emptyNMStateConfigs)
   106  	} else {
   107  		return "", "", errors.New("both AgentConfig and NMStateConfig are empty")
   108  	}
   109  	if rendezvousIPError != nil {
   110  		return "", "", rendezvousIPError
   111  	}
   112  
   113  	var sshKey string
   114  	// Get SSH Keys which can be used to determine if Rest API failures are due to network connectivity issues
   115  	if installConfig != nil {
   116  		sshKey = installConfig.(*installconfig.InstallConfig).Config.SSHKey
   117  	}
   118  
   119  	return rendezvousIP, sshKey, nil
   120  }
   121  
   122  // FindAuthTokenFromAssetStore returns the auth token from asset store.
   123  func FindAuthTokenFromAssetStore(assetDir string) (string, error) {
   124  	authConfigAsset := &gencrypto.AuthConfig{}
   125  
   126  	assetStore, err := assetstore.NewStore(assetDir)
   127  	if err != nil {
   128  		return "", errors.Wrap(err, "failed to create asset store")
   129  	}
   130  
   131  	authConfig, authConfigError := assetStore.Load(authConfigAsset)
   132  
   133  	if authConfigError != nil {
   134  		logrus.Debug(errors.Wrapf(authConfigError, "failed to load %s", authConfigAsset.Name()))
   135  		return "", errors.New("failed to load AuthConfig")
   136  	}
   137  
   138  	var authToken string
   139  	if authConfig != nil {
   140  		authToken = authConfig.(*gencrypto.AuthConfig).AgentAuthToken
   141  	}
   142  
   143  	return authToken, nil
   144  }
   145  
   146  // IsRestAPILive Determine if the Agent Rest API on node zero has initialized
   147  func (rest *NodeZeroRestClient) IsRestAPILive() bool {
   148  	// GET /v2/infraenvs
   149  	listInfraEnvsParams := installer.NewListInfraEnvsParams()
   150  	_, err := rest.Client.Installer.ListInfraEnvs(rest.ctx, listInfraEnvsParams)
   151  	return err == nil
   152  }
   153  
   154  // GetRestAPIServiceBaseURL Return the url of the Agent Rest API on node zero
   155  func (rest *NodeZeroRestClient) GetRestAPIServiceBaseURL() *url.URL {
   156  	return rest.config.URL
   157  }
   158  
   159  // GetInfraEnvEvents Return the event list for the provided infraEnvID from the Agent Rest API
   160  func (rest *NodeZeroRestClient) GetInfraEnvEvents(infraEnvID *strfmt.UUID) (models.EventList, error) {
   161  	listEventsParams := &events.V2ListEventsParams{InfraEnvID: infraEnvID}
   162  	clusterEventsResult, err := rest.Client.Events.V2ListEvents(rest.ctx, listEventsParams)
   163  	if err != nil {
   164  		return nil, err
   165  	}
   166  	return clusterEventsResult.Payload, nil
   167  }
   168  
   169  // getClusterID Return the cluster ID assigned by the Agent Rest API
   170  func (rest *NodeZeroRestClient) getClusterID() (*strfmt.UUID, error) {
   171  	// GET /v2/clusters and return first result
   172  	listClusterParams := installer.NewV2ListClustersParams()
   173  	clusterResult, err := rest.Client.Installer.V2ListClusters(rest.ctx, listClusterParams)
   174  	if err != nil {
   175  		return nil, err
   176  	}
   177  	clusterList := clusterResult.Payload
   178  	if len(clusterList) == 1 {
   179  		clusterID := clusterList[0].ID
   180  		return clusterID, nil
   181  	} else if len(clusterList) == 0 {
   182  		logrus.Debug("cluster is not registered in rest API")
   183  		return nil, nil
   184  	} else {
   185  		logrus.Infof("found too many clusters. number of clusters found: %d", len(clusterList))
   186  		return nil, nil
   187  	}
   188  }
   189  
   190  // getClusterID Return the infraEnv ID associated with the cluster in the Agent Rest API
   191  func (rest *NodeZeroRestClient) getClusterInfraEnvID() (*strfmt.UUID, error) {
   192  	// GET /v2/infraenvs and return first result
   193  	listInfraEnvParams := installer.NewListInfraEnvsParams()
   194  	infraEnvResult, err := rest.Client.Installer.ListInfraEnvs(rest.ctx, listInfraEnvParams)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  	infraEnvList := infraEnvResult.Payload
   199  	if len(infraEnvList) == 1 {
   200  		clusterInfraEnvID := infraEnvList[0].ID
   201  		return clusterInfraEnvID, nil
   202  	} else if len(infraEnvList) == 0 {
   203  		logrus.Debug("infraenv is not registered in rest API")
   204  		return nil, nil
   205  	} else {
   206  		logrus.Infof("found too many infraenvs. number of infraenvs found: %d", len(infraEnvList))
   207  		return nil, nil
   208  	}
   209  }