Skip to content

Commit

Permalink
Merge branch 'master' into project_max_quota
Browse files Browse the repository at this point in the history
  • Loading branch information
VoigtS authored Nov 13, 2024
2 parents 2e58b10 + 8b1b522 commit bca623e
Show file tree
Hide file tree
Showing 58 changed files with 231 additions and 24,262 deletions.
6 changes: 1 addition & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ require (
github.com/go-gorp/gorp/v3 v3.1.0
github.com/gofrs/uuid/v5 v5.3.0
github.com/gophercloud/gophercloud/v2 v2.2.0
github.com/gophercloud/utils/v2 v2.0.0-20241107125844-da754bc75cd6
github.com/gorilla/mux v1.8.1
github.com/majewsky/schwift/v2 v2.0.0
github.com/prometheus/client_golang v1.20.5
github.com/prometheus/common v0.60.1
github.com/rs/cors v1.11.1
github.com/sapcc/go-api-declarations v1.12.9
github.com/sapcc/go-bits v0.0.0-20241107000306-6eb1626e14d0
github.com/sapcc/go-bits v0.0.0-20241112121120-a312b675efd7
go.uber.org/automaxprocs v1.6.0
gopkg.in/yaml.v2 v2.4.0
)
Expand All @@ -31,7 +30,6 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
Expand All @@ -41,7 +39,5 @@ require (
github.com/sergi/go-diff v1.3.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
8 changes: 2 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gophercloud/gophercloud/v2 v2.2.0 h1:STqqnSXuhcg1OPBOZ14z6JDm8fKIN13H2bJg6bBuHp8=
github.com/gophercloud/gophercloud/v2 v2.2.0/go.mod h1:f2hMRC7Kakbv5vM7wSGHrIPZh6JZR60GVHryJlF/K44=
github.com/gophercloud/utils/v2 v2.0.0-20241107125844-da754bc75cd6 h1:Vikb1i71pW5yb/ayp+Cw6Z3Wc+3NtT+ui/t4LyJl7dY=
github.com/gophercloud/utils/v2 v2.0.0-20241107125844-da754bc75cd6/go.mod h1:9KHhEdDkA/4hTdwxS0sALJIp2hFSjrODlKMQcFU2GFw=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down Expand Up @@ -102,8 +100,6 @@ github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
Expand Down Expand Up @@ -163,8 +159,8 @@ github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/sapcc/go-api-declarations v1.12.9 h1:4CWkt333oQxGnbka1TH4qApC0bxZe+WIBduygEcxiNw=
github.com/sapcc/go-api-declarations v1.12.9/go.mod h1:83R3hTANhuRXt/pXDby37IJetw8l7DG41s33Tp9NXxI=
github.com/sapcc/go-bits v0.0.0-20241107000306-6eb1626e14d0 h1:4dDWf8AxpL1FGLrAAsTSSX0K7wB9Zkti2WxTj6xvGzQ=
github.com/sapcc/go-bits v0.0.0-20241107000306-6eb1626e14d0/go.mod h1:edzu9ZBNooNFNX1J70nkhV2cOibYvADvr4C39K0stbc=
github.com/sapcc/go-bits v0.0.0-20241112121120-a312b675efd7 h1:jp2NiKpUY5Jzlfw1oFqg/EkMtq72OgQGV3KCIVDGlH0=
github.com/sapcc/go-bits v0.0.0-20241112121120-a312b675efd7/go.mod h1:P4F8aMHla5I0gRW+eOEYrhM89h3heEg0nypTZZcKoBQ=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
Expand Down
4 changes: 2 additions & 2 deletions internal/api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ func Test_ClusterOperations(t *testing.T) {

func Test_DomainOperations(t *testing.T) {
s := setupTest(t, "fixtures/start-data.sql")
discovery := s.Cluster.DiscoveryPlugin.(*plugins.StaticDiscoveryPlugin) //nolint:errcheck
discovery := s.Cluster.DiscoveryPlugin.(*plugins.StaticDiscoveryPlugin)

// all reports are pulled at the same simulated time, `s.Clock().Now().Unix() == 3600`,
// to match the setup of active vs. expired commitments in `fixtures/start-data.sql`
Expand Down Expand Up @@ -366,7 +366,7 @@ func Test_DomainOperations(t *testing.T) {

func Test_ProjectOperations(t *testing.T) {
s := setupTest(t, "fixtures/start-data.sql")
discovery := s.Cluster.DiscoveryPlugin.(*plugins.StaticDiscoveryPlugin) //nolint:errcheck
discovery := s.Cluster.DiscoveryPlugin.(*plugins.StaticDiscoveryPlugin)

// all reports are pulled at the same simulated time, `s.Clock().Now().Unix() == 3600`,
// to match the setup of active vs. expired commitments in `fixtures/start-data.sql`
Expand Down
2 changes: 1 addition & 1 deletion internal/api/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func NewTokenValidator(provider *gophercloud.ProviderClient, eo gophercloud.Endp
IdentityV3: identityV3,
Cacher: gopherpolicy.InMemoryCacher(),
}
err = tv.LoadPolicyFile(osext.GetenvOrDefault("LIMES_API_POLICY_PATH", "/etc/limes/policy.yaml"))
err = tv.LoadPolicyFile(osext.GetenvOrDefault("LIMES_API_POLICY_PATH", "/etc/limes/policy.yaml"), nil)
return &tv, err
}

Expand Down
4 changes: 2 additions & 2 deletions internal/api/translation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func TestTranslateManilaSubcapacities(t *testing.T) {
func TestTranslateIronicSubcapacities(t *testing.T) {
extraSetup := func(s *test.Setup) {
// this subcapacity translation depends on ResourceInfo.Attributes on the respective resource
plugin := s.Cluster.QuotaPlugins["first"].(*plugins.GenericQuotaPlugin) //nolint:errcheck // it's okay to crash here on type mismatch
plugin := s.Cluster.QuotaPlugins["first"].(*plugins.GenericQuotaPlugin)
plugin.StaticResourceAttributes = map[liquid.ResourceName]map[string]any{"capacity": {
"cores": 5,
"ram_mib": 23,
Expand Down Expand Up @@ -283,7 +283,7 @@ func TestTranslateCinderSnapshotSubresources(t *testing.T) {
func TestTranslateIronicSubresources(t *testing.T) {
extraSetup := func(s *test.Setup) {
// this subcapacity translation depends on ResourceInfo.Attributes on the respective resource
plugin := s.Cluster.QuotaPlugins["first"].(*plugins.GenericQuotaPlugin) //nolint:errcheck // it's okay to crash here on type mismatch
plugin := s.Cluster.QuotaPlugins["first"].(*plugins.GenericQuotaPlugin)
plugin.StaticResourceAttributes = map[liquid.ResourceName]map[string]any{"capacity": {
"cores": 5,
"ram_mib": 23,
Expand Down
4 changes: 2 additions & 2 deletions internal/collector/capacity_scrape_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ func Test_ScanCapacity(t *testing.T) {
with_subcapacities: true
without_usage: true
`
subcapacityPlugin := s.AddCapacityPlugin(t, pluginConfig).(*plugins.StaticCapacityPlugin) //nolint:errcheck
subcapacityPlugin := s.AddCapacityPlugin(t, pluginConfig).(*plugins.StaticCapacityPlugin)
setClusterCapacitorsStale(t, s)
s.Clock.StepBy(5 * time.Minute) // to force a capacitor consistency check to run
mustT(t, jobloop.ProcessMany(job, s.Ctx, len(s.Cluster.CapacityPlugins)))
Expand Down Expand Up @@ -277,7 +277,7 @@ func Test_ScanCapacity(t *testing.T) {
resources: [ unshared2/things ]
with_capacity_per_az: true
`
azCapacityPlugin := s.AddCapacityPlugin(t, pluginConfig).(*plugins.StaticCapacityPlugin) //nolint:errcheck
azCapacityPlugin := s.AddCapacityPlugin(t, pluginConfig).(*plugins.StaticCapacityPlugin)
setClusterCapacitorsStale(t, s)
s.Clock.StepBy(5 * time.Minute) // to force a capacitor consistency check to run
mustT(t, jobloop.ProcessMany(job, s.Ctx, len(s.Cluster.CapacityPlugins)))
Expand Down
2 changes: 1 addition & 1 deletion internal/collector/keystone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func keystoneTestCluster(t *testing.T) (test.Setup, *core.Cluster) {
func Test_ScanDomains(t *testing.T) {
s, cluster := keystoneTestCluster(t)
c := getCollector(t, s)
discovery := cluster.DiscoveryPlugin.(*plugins.StaticDiscoveryPlugin) //nolint:errcheck
discovery := cluster.DiscoveryPlugin.(*plugins.StaticDiscoveryPlugin)

// construct expectation for return value
var expectedNewDomains []string
Expand Down
2 changes: 1 addition & 1 deletion internal/collector/ratescrape_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func Test_RateScrapeFailure(t *testing.T) {
tr0.AssertEqualToFile("fixtures/scrape0.sql")

// ScrapeRates should not touch the DB when scraping fails
plugin := s.Cluster.QuotaPlugins["unittest"].(*plugins.GenericQuotaPlugin) //nolint:errcheck
plugin := s.Cluster.QuotaPlugins["unittest"].(*plugins.GenericQuotaPlugin)
plugin.ScrapeFails = true
mustFailLikeT(t, job.ProcessOne(s.Ctx, withLabel), expectedErrorRx)

Expand Down
4 changes: 2 additions & 2 deletions internal/collector/scrape_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func Test_ScrapeSuccess(t *testing.T) {
job := c.ResourceScrapeJob(s.Registry)
withLabel := jobloop.WithLabel("service_type", "unittest")
syncJob := c.SyncQuotaToBackendJob(s.Registry)
plugin := s.Cluster.QuotaPlugins["unittest"].(*plugins.GenericQuotaPlugin) //nolint:errcheck
plugin := s.Cluster.QuotaPlugins["unittest"].(*plugins.GenericQuotaPlugin)

// check that ScanDomains created the domain, project and their services
tr, tr0 := easypg.NewTracker(t, s.DB.Db)
Expand Down Expand Up @@ -391,7 +391,7 @@ func Test_ScrapeFailure(t *testing.T) {
// Note that this does *not* set quota_desynced_at. We would rather not
// write any quotas while we cannot even get correct usage numbers.
s.Clock.StepBy(scrapeInterval)
plugin := s.Cluster.QuotaPlugins["unittest"].(*plugins.GenericQuotaPlugin) //nolint:errcheck
plugin := s.Cluster.QuotaPlugins["unittest"].(*plugins.GenericQuotaPlugin)
plugin.ScrapeFails = true
mustFailLikeT(t, job.ProcessOne(s.Ctx, withLabel), expectedErrorRx)
mustFailLikeT(t, job.ProcessOne(s.Ctx, withLabel), expectedErrorRx) // twice because there are two projects
Expand Down
2 changes: 1 addition & 1 deletion internal/collector/sync_quota_to_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func (c *Collector) performQuotaSync(ctx context.Context, srv db.ProjectService,
return err
}
targetQuotasInDB[resourceName] = targetQuota
if currentQuota == nil || *currentQuota < 0 || uint64(*currentQuota) != targetQuota { //nolint:gosec // negative backend quota is explicitly checked
if currentQuota == nil || *currentQuota < 0 || uint64(*currentQuota) != targetQuota {
needsApply = true
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion internal/plugins/capacity_nova.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (p *capacityNovaPlugin) PluginTypeID() string {
func (p *capacityNovaPlugin) Scrape(ctx context.Context, backchannel core.CapacityPluginBackchannel, allAZs []limes.AvailabilityZone) (result map[db.ServiceType]map[liquid.ResourceName]core.PerAZ[core.CapacityData], serializedMetrics []byte, err error) {
// collect info about flavors with separate instance quota
// (we are calling these "split flavors" here, as opposed to "pooled flavors" that share a common pool of CPU/instances/RAM capacity)
allSplitFlavorNames, err := p.FlavorAliases.ListFlavorsWithSeparateInstanceQuota(ctx, p.NovaV2, true) // true = ignore Ironic flavors
allSplitFlavorNames, _, err := p.FlavorAliases.ListFlavorsWithSeparateInstanceQuota(ctx, p.NovaV2, true) // true = ignore Ironic flavors
if err != nil {
return nil, nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/plugins/capacity_sapcc_ironic.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ var cpNodeNameRx = regexp.MustCompile(`^node(?:swift)?\d+-(cp\d+)$`)
// Scrape implements the core.CapacityPlugin interface.
func (p *capacitySapccIronicPlugin) Scrape(ctx context.Context, _ core.CapacityPluginBackchannel, allAZs []limes.AvailabilityZone) (result map[db.ServiceType]map[liquid.ResourceName]core.PerAZ[core.CapacityData], serializedMetrics []byte, err error) {
// collect info about flavors with separate instance quota
flavorNames, err := p.FlavorAliases.ListFlavorsWithSeparateInstanceQuota(ctx, p.NovaV2, false) // false = do not ignore Ironic flavors
flavorNames, _, err := p.FlavorAliases.ListFlavorsWithSeparateInstanceQuota(ctx, p.NovaV2, false) // false = do not ignore Ironic flavors
if err != nil {
return nil, nil, err
}
Expand Down
18 changes: 14 additions & 4 deletions internal/plugins/nova.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"maps"
"math/big"
"regexp"
"slices"

"github.com/gophercloud/gophercloud/v2"
"github.com/gophercloud/gophercloud/v2/openstack"
Expand All @@ -50,8 +51,9 @@ type novaPlugin struct {
WithSubresources bool `yaml:"with_subresources"`
LiquidIronicCompatibilityMode bool `yaml:"liquid_ironic_compat_mode"` // NOTE: if true, assume that liquid-ironic is in use and ignore Ironic flavors
// computed state
resources map[liquid.ResourceName]liquid.ResourceInfo `yaml:"-"`
hasPooledResource map[string]map[liquid.ResourceName]bool `yaml:"-"`
resources map[liquid.ResourceName]liquid.ResourceInfo `yaml:"-"`
hasPooledResource map[string]map[liquid.ResourceName]bool `yaml:"-"`
ignoredFlavorNames []string `yaml:"-"`
// connections
NovaV2 *gophercloud.ServiceClient `yaml:"-"`
OSTypeProber *nova.OSTypeProber `yaml:"-"`
Expand Down Expand Up @@ -130,11 +132,11 @@ func (p *novaPlugin) Init(ctx context.Context, provider *gophercloud.ProviderCli
}

// find per-flavor instance resources
flavorNames, err := p.SeparateInstanceQuotas.FlavorAliases.ListFlavorsWithSeparateInstanceQuota(ctx, p.NovaV2, p.LiquidIronicCompatibilityMode)
splitFlavorNames, ignoredFlavorNames, err := p.SeparateInstanceQuotas.FlavorAliases.ListFlavorsWithSeparateInstanceQuota(ctx, p.NovaV2, p.LiquidIronicCompatibilityMode)
if err != nil {
return err
}
for _, flavorName := range flavorNames {
for _, flavorName := range splitFlavorNames {
if p.SeparateInstanceQuotas.FlavorNameSelection.MatchFlavorName(flavorName) {
resName := p.SeparateInstanceQuotas.FlavorAliases.LimesResourceNameForFlavor(flavorName)
p.resources[resName] = liquid.ResourceInfo{
Expand All @@ -143,6 +145,7 @@ func (p *novaPlugin) Init(ctx context.Context, provider *gophercloud.ProviderCli
}
}
}
p.ignoredFlavorNames = ignoredFlavorNames

return p.HypervisorTypeRules.Validate()
}
Expand Down Expand Up @@ -259,6 +262,9 @@ func (p *novaPlugin) Scrape(ctx context.Context, project core.KeystoneProject, a
},
}
for flavorName, flavorLimits := range limitsData.Limits.AbsolutePerFlavor {
if slices.Contains(p.ignoredFlavorNames, flavorName) {
continue
}
if p.SeparateInstanceQuotas.FlavorNameSelection.MatchFlavorName(flavorName) {
result[p.SeparateInstanceQuotas.FlavorAliases.LimesResourceNameForFlavor(flavorName)] = core.ResourceData{
Quota: flavorLimits.MaxTotalInstances,
Expand Down Expand Up @@ -298,6 +304,10 @@ func (p *novaPlugin) Scrape(ctx context.Context, project core.KeystoneProject, a
for _, subres := range allSubresources {
az := subres.AZ

if slices.Contains(p.ignoredFlavorNames, subres.FlavorName) {
continue
}

// use separate instance resource if we have a matching "instances_$FLAVOR" resource
instanceResourceName := p.SeparateInstanceQuotas.FlavorAliases.LimesResourceNameForFlavor(subres.FlavorName)
isPooled := false
Expand Down
14 changes: 9 additions & 5 deletions internal/plugins/nova/flavor_translate.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,21 @@ func (t FlavorTranslationTable) NovaQuotaNameForLimesResourceName(resourceName l

// ListFlavorsWithSeparateInstanceQuota queries Nova for all separate instance
// quotas, and returns the flavor names that Nova prefers for each.
func (t FlavorTranslationTable) ListFlavorsWithSeparateInstanceQuota(ctx context.Context, computeV2 *gophercloud.ServiceClient, ignoreIronicFlavors bool) ([]string, error) {
var flavorNames []string
err := FlavorSelection{}.ForeachFlavor(ctx, computeV2, func(f flavors.Flavor) error {
//
// By default, the second return value (ignoredFlavorNames) will be empty.
// If ignoreIronicFlavors is given, it will contain the names of all Ironic flavors,
// which are then guaranteed to not be in the first list (splitFlavorNames).
func (t FlavorTranslationTable) ListFlavorsWithSeparateInstanceQuota(ctx context.Context, computeV2 *gophercloud.ServiceClient, ignoreIronicFlavors bool) (splitFlavorNames, ignoredFlavorNames []string, err error) {
err = FlavorSelection{}.ForeachFlavor(ctx, computeV2, func(f flavors.Flavor) error {
if ignoreIronicFlavors && f.ExtraSpecs["capabilities:hypervisor_type"] == "ironic" {
ignoredFlavorNames = append(ignoredFlavorNames, f.Name)
return nil
}
if f.ExtraSpecs["quota:separate"] == "true" {
flavorNames = append(flavorNames, f.Name)
splitFlavorNames = append(splitFlavorNames, f.Name)
t.recordNovaPreferredName(f.Name)
}
return nil
})
return flavorNames, err
return splitFlavorNames, ignoredFlavorNames, err
}
18 changes: 3 additions & 15 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@ import (

"github.com/dlmiddlecote/sqlstats"
"github.com/gophercloud/gophercloud/v2"
"github.com/gophercloud/gophercloud/v2/openstack"
"github.com/gophercloud/utils/v2/openstack/clientconfig"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/rs/cors"
"github.com/sapcc/go-api-declarations/bininfo"
"github.com/sapcc/go-api-declarations/limes"
"github.com/sapcc/go-api-declarations/liquid"
"github.com/sapcc/go-bits/errext"
"github.com/sapcc/go-bits/gophercloudext"
"github.com/sapcc/go-bits/httpapi"
"github.com/sapcc/go-bits/httpapi/pprofapi"
"github.com/sapcc/go-bits/httpext"
Expand Down Expand Up @@ -143,19 +142,8 @@ func main() {
wrap.SetOverrideUserAgent(bininfo.Component(), bininfo.VersionOr("rolling"))

// connect to OpenStack
ao, err := clientconfig.AuthOptions(nil)
if err != nil {
logg.Fatal("cannot find OpenStack credentials: " + err.Error())
}
ao.AllowReauth = true
provider, err := openstack.AuthenticatedClient(ctx, *ao)
if err != nil {
logg.Fatal("cannot initialize OpenStack client: " + err.Error())
}
eo := gophercloud.EndpointOpts{
Availability: gophercloud.Availability(os.Getenv("OS_INTERFACE")),
Region: os.Getenv("OS_REGION_NAME"),
}
provider, eo, err := gophercloudext.NewProviderClient(ctx, nil)
must.Succeed(err)

// load configuration and connect to cluster
cluster, errs := core.NewClusterFromYAML(must.Return(os.ReadFile(configPath)))
Expand Down
Loading

0 comments on commit bca623e

Please sign in to comment.