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 }