Skip to content

Commit

Permalink
UPSTREAM: 89885: allow to read openstack cloud provider config from a…
Browse files Browse the repository at this point in the history
… secret

This patch brings back the downstream changes that were introduced
to allow reading openstack cloud provider config from a secret.
They are available in release-4.4, but were reverted in master with
openshift/origin#24719

This change includes:

- Ability to read metadata values for kubelet. Since the service
does not have access to the secret to read the configuration, but
it needs data to download (e.g. hostname or flavor), we are trying
to get it from the metadata server.

- Deprecation of kubeConfig parameter. Now we read the file that
was provided with --kubeconfig option.

Origin-commit: f95edc26155a29769b3c5b80c03755a01a87b5fc

UPSTREAM: 89885: legacy-cloud-provider/openstack: include / prefix in instance ID output

When we want to read an instance ID from the metadata service, cloud provider
doesn't include "/" prefix, which is required for successful parsing of
provider the ID later.
This commit adds the missing "/" prefix to the output.

UPSTREAM: 89885: SQUASH: Fix Cinder provisioning crashing on nil cloud provider

OpenStack cloud provider must not use nil when provisioning a Cinder
volume.

UPSTREAM: 89885: SQUASH: Report OpenStack cloud initialization errors

openshift-rebase(v1.24):source=dbe70e455ee

UPSTREAM: <carry>: Set informer for openstack

Set informer for the openstack cloud provider to ensure it is properly
initialized when reading config from a secret.

Upstream 89885 was closed in favor of 96750.

Co-authored-by: Hemant Kumar <hekumar@redhat.com>

openshift-rebase(v1.24):source=d7ecbd903e2

UPSTREAM: 89885: SQUASH: Retry fetching clouds.conf

The OpenStack secret is not guaranteed to be present at the time
kube-controller-manager is initialised.

Co-authored-by: Martin André <m.andre@redhat.com>
Co-authored-by: Pierre Prinetti <pierreprinetti@redhat.com>

openshift-rebase(v1.24):source=8bc9dd29ef0

UPSTREAM: 89885: Fix panic in openstack.InstanceExistsByProviderID()

... when provider is uninitialised.

This is a fix to downstream-only code which was originally proposed
upstream as kubernetes#89885 but did
not merge. It is therefore not relevant upstream. Given that we will
replace the openstack legacy cloud provider in 4.12 we will not
re-propose kubernetes#89885 or this fix to it.

Causes all openstack.Instances() methods which require more than the
local metadata service to return NotImplemented instead of crashing if
the provider is not initialised.
  • Loading branch information
Fedosin authored and soltysh committed Aug 19, 2022
1 parent ac867ee commit 7992bf8
Show file tree
Hide file tree
Showing 4 changed files with 296 additions and 60 deletions.
24 changes: 24 additions & 0 deletions plugin/pkg/admission/storage/persistentvolume/label/admission.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ import (
"io"
"sync"

genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission"
"k8s.io/client-go/informers"
cloudprovider "k8s.io/cloud-provider"
cloudvolume "k8s.io/cloud-provider/volume"
volumehelpers "k8s.io/cloud-provider/volume/helpers"
Expand All @@ -51,12 +54,14 @@ func Register(plugins *admission.Plugins) {
}

var _ = admission.Interface(&persistentVolumeLabel{})
var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&persistentVolumeLabel{})

type persistentVolumeLabel struct {
*admission.Handler

mutex sync.Mutex
cloudConfig []byte
sharedInformer informers.SharedInformerFactory
awsPVLabeler cloudprovider.PVLabeler
gcePVLabeler cloudprovider.PVLabeler
azurePVLabeler cloudprovider.PVLabeler
Expand Down Expand Up @@ -86,6 +91,20 @@ func (l *persistentVolumeLabel) SetCloudConfig(cloudConfig []byte) {
l.cloudConfig = cloudConfig
}

func (l *persistentVolumeLabel) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
secretInformer := f.Core().V1().Secrets()
l.sharedInformer = f
l.SetReadyFunc(secretInformer.Informer().HasSynced)
}

// ValidateInitialization ensures lister is set.
func (l *persistentVolumeLabel) ValidateInitialization() error {
if l.sharedInformer == nil {
return fmt.Errorf("missing shared informer")
}
return nil
}

func nodeSelectorRequirementKeysExistInNodeSelectorTerms(reqs []api.NodeSelectorRequirement, terms []api.NodeSelectorTerm) bool {
for _, req := range reqs {
for _, term := range terms {
Expand Down Expand Up @@ -396,6 +415,11 @@ func (l *persistentVolumeLabel) getOpenStackPVLabeler() (cloudprovider.PVLabeler
return nil, err
}

cloudProviderWithInformer, ok := cloudProvider.(cloudprovider.InformerUser)
if ok {
cloudProviderWithInformer.SetInformers(l.sharedInformer)
}

openStackPVLabeler, ok := cloudProvider.(cloudprovider.PVLabeler)
if !ok {
return nil, errors.New("OpenStack cloud provider does not implement PV labeling")
Expand Down
67 changes: 65 additions & 2 deletions staging/src/k8s.io/legacy-cloud-providers/openstack/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ const (

// configDriveID is used as an identifier on the metadata search order configuration.
configDriveID = "configDrive"

// We have to use AWS compatible metadata for the next urls, because OpenStack doesn't
// provide this information.

// instanceTypeURL contains url to get the instance type from metadata server.
instanceTypeURL = "http://169.254.169.254/2009-04-04/meta-data/instance-type"

// localAddressURL contains url to get the instance local ip address from metadata server.
localAddressURL = "http://169.254.169.254/2009-04-04/meta-data/local-ipv4"

// publicAddressURL contains url to get the instance public ip address from metadata server.
publicAddressURL = "http://169.254.169.254/2009-04-04/meta-data/public-ipv4"
)

// ErrBadMetadata is used to indicate a problem parsing data from metadata server
Expand Down Expand Up @@ -160,13 +172,64 @@ func getMetadataFromMetadataService(metadataVersion string) (*Metadata, error) {
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("unexpected status code when reading metadata from %s: %s", metadataURL, resp.Status)
return nil, err
return nil, fmt.Errorf("unexpected status code when reading metadata from %s: %s", metadataURL, resp.Status)
}

return parseMetadata(resp.Body)
}

func getIntanceType() (string, error) {
klog.V(4).Infof("Attempting to fetch instance type from %s", instanceTypeURL)
resp, err := http.Get(instanceTypeURL)
if err != nil {
return "", fmt.Errorf("error fetching %s: %v", instanceTypeURL, err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("unexpected status code when reading instance type from %s: %s", instanceTypeURL, resp.Status)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("cannot read the response body %s: %v", instanceTypeURL, err)
}

return string(body), nil
}

func getNodeAddress(url string) (string, error) {
klog.V(4).Infof("Attempting to fetch instance address from %s", url)
resp, err := http.Get(url)
if err != nil {
return "", fmt.Errorf("error fetching %s: %v", url, err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("unexpected status code when reading instance address from %s: %s", url, resp.Status)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("cannot read the response body %s: %v", url, err)
}

return string(body), nil
}

func getNodeAddresses() (string, string, error) {
localAddess, err := getNodeAddress(localAddressURL)
if err != nil {
return "", "", err
}

publicAddress, err := getNodeAddress(publicAddressURL)
if err != nil {
return "", "", err
}

return localAddess, publicAddress, nil
}

// Metadata is fixed for the current host, so cache the value process-wide
var metadataCache *Metadata

Expand Down

0 comments on commit 7992bf8

Please sign in to comment.