Skip to content

Commit

Permalink
fix: skip bad cloud-config in OpenStack platform
Browse files Browse the repository at this point in the history
Sometimes we cannot redefine user-data in the openstack.
we need to catch this and allow user to apply configuration
through api.

Signed-off-by: Serge Logvinov <serge.logvinov@sinextra.dev>
Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
  • Loading branch information
sergelogvinov authored and smira committed Sep 15, 2021
1 parent a394d1e commit 3de505c
Showing 1 changed file with 36 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
package openstack

import (
"bytes"
"context"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"

"github.com/talos-systems/go-procfs/procfs"

Expand All @@ -34,82 +32,73 @@ const (
type Openstack struct{}

// Name implements the runtime.Platform interface.
func (a *Openstack) Name() string {
func (o *Openstack) Name() string {
return "openstack"
}

// Configuration implements the runtime.Platform interface.
func (a *Openstack) Configuration(ctx context.Context) ([]byte, error) {
func (o *Openstack) Configuration(ctx context.Context) ([]byte, error) {
log.Printf("fetching machine config from: %q", OpenstackUserDataEndpoint)

return download.Download(ctx, OpenstackUserDataEndpoint,
machineConfigDl, err := download.Download(ctx, OpenstackUserDataEndpoint,
download.WithErrorOnNotFound(errors.ErrNoConfigSource),
download.WithErrorOnEmptyResponse(errors.ErrNoConfigSource))
if err != nil {
return nil, err
}

// Some openstack setups does not allow you to change user-data,
// so skip this case.
if bytes.HasPrefix(machineConfigDl, []byte("#cloud-config")) {
return nil, errors.ErrNoConfigSource
}

return machineConfigDl, nil
}

// Mode implements the runtime.Platform interface.
func (a *Openstack) Mode() runtime.Mode {
func (o *Openstack) Mode() runtime.Mode {
return runtime.ModeCloud
}

// Hostname implements the runtime.Platform interface.
func (a *Openstack) Hostname(ctx context.Context) (hostname []byte, err error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, OpenstackHostnameEndpoint, nil)
if err != nil {
return nil, err
}
func (o *Openstack) Hostname(ctx context.Context) (hostname []byte, err error) {
log.Printf("fetching hostname from: %q", OpenstackHostnameEndpoint)

resp, err := http.DefaultClient.Do(req)
hostname, err = download.Download(ctx, OpenstackHostnameEndpoint,
download.WithErrorOnNotFound(errors.ErrNoHostname),
download.WithErrorOnEmptyResponse(errors.ErrNoHostname))
if err != nil {
return nil, err
}
//nolint:errcheck
defer resp.Body.Close()
// Platform cannot support this endpoint, or return timeout.
// ApplyDynamicConfig can crash in this situation.
log.Printf("failed to fetch hostname, ignored: %s", err)

if resp.StatusCode != http.StatusOK {
return hostname, fmt.Errorf("failed to fetch hostname from metadata service: %d", resp.StatusCode)
return nil, nil
}

return ioutil.ReadAll(resp.Body)
return hostname, nil
}

// ExternalIPs implements the runtime.Platform interface.
func (a *Openstack) ExternalIPs(ctx context.Context) (addrs []net.IP, err error) {
var (
body []byte
req *http.Request
resp *http.Response
)

if req, err = http.NewRequestWithContext(ctx, "GET", OpenstackExternalIPEndpoint, nil); err != nil {
return
}

client := &http.Client{}
if resp, err = client.Do(req); err != nil {
return
}

//nolint:errcheck
defer resp.Body.Close()
func (o *Openstack) ExternalIPs(ctx context.Context) (addrs []net.IP, err error) {
log.Printf("fetching externalIP from: %q", OpenstackExternalIPEndpoint)

if resp.StatusCode != http.StatusOK {
return addrs, fmt.Errorf("failed to retrieve external addresses for instance")
}

if body, err = ioutil.ReadAll(resp.Body); err != nil {
return
exIP, err := download.Download(ctx, OpenstackExternalIPEndpoint,
download.WithErrorOnNotFound(errors.ErrNoExternalIPs),
download.WithErrorOnEmptyResponse(errors.ErrNoExternalIPs))
if err != nil {
return nil, err
}

if addr := net.ParseIP(string(body)); addr != nil {
if addr := net.ParseIP(string(exIP)); addr != nil {
addrs = append(addrs, addr)
}

return addrs, err
return addrs, nil
}

// KernelArgs implements the runtime.Platform interface.
func (a *Openstack) KernelArgs() procfs.Parameters {
func (o *Openstack) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty1").Append("ttyS0"),
}
Expand Down

0 comments on commit 3de505c

Please sign in to comment.