airshipctl/pkg/cluster/initinfra/infra.go
Kostiantyn Kalynovskyi e1bc8ee07d [AIR-97] Adding initinfra subcommand
Command will deploy initial inftrastructure that is identified by
airshipctl document module, bundle interface, documents will be fitered
based on label and annotation, which will indicate that it belongs to
initial infrastructure.

After the documents are identified, they will be labeled
indicating that these resources are deployed by initinfra, if flag
`prune` is specified, resources that have initinfra annotation and
deployedBy initinfra label, but are not part of the documents supplied
by bundle interface will be deleted. If user wants to avoid pruning of
some resources he can remove label deployBy manually from the kubernetes
resources that should not prunned.

Change-Id: I143835291d449be420bfcb2944ba7eaec37c3411
2020-02-27 08:38:51 -06:00

102 lines
2.6 KiB
Go

package initinfra
import (
"sigs.k8s.io/kustomize/v3/pkg/fs"
"sigs.k8s.io/kustomize/v3/pkg/types"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/k8s/client"
"opendev.org/airship/airshipctl/pkg/k8s/kubectl"
)
// Infra is an abstraction used to initialize base infrastructure
type Infra struct {
FileSystem fs.FileSystem
RootSettings *environment.AirshipCTLSettings
Client client.Interface
DryRun bool
Prune bool
ClusterType string
}
// NewInfra return instance of Infra
func NewInfra(rs *environment.AirshipCTLSettings) *Infra {
// At this point AirshipCTLSettings may not be fully initialized
infra := &Infra{RootSettings: rs}
return infra
}
// Run intinfra subcommand logic
func (infra *Infra) Run() error {
infra.FileSystem = kubectl.Buffer{FileSystem: fs.MakeRealFS()}
var err error
infra.Client, err = client.NewClient(infra.RootSettings)
if err != nil {
return err
}
return infra.Deploy()
}
// Deploy method deploys documents
func (infra *Infra) Deploy() error {
kctl := infra.Client.Kubectl()
var err error
ao, err := kctl.ApplyOptions()
if err != nil {
return err
}
ao.SetDryRun(infra.DryRun)
// If prune is true, set selector for purning
if infra.Prune {
ao.SetPrune(document.DeployedByLabel + "=" + document.InitinfraIdentifier)
}
globalConf := infra.RootSettings.Config()
if err = globalConf.EnsureComplete(); err != nil {
return err
}
var manifest *config.Manifest
manifest, err = globalConf.CurrentContextManifest()
if err != nil {
return err
}
b, err := document.NewBundle(infra.FileSystem, manifest.TargetPath, "")
if err != nil {
return err
}
filterSelector := types.Selector{
LabelSelector: document.EphemeralClusterSelector,
}
// Get documents that are annotated to belong to initinfra
docs, err := b.Select(filterSelector)
if err != nil {
return err
}
// Label every document indicating that it was deployed by initinfra module for further reference
// This may be used later to get all resources that are part of initinfra module, for monitoring, alerting
// upgrading etc...
// also if prune is set to true, this fulfills requirement for all labeled document to be labeled.
// Pruning by annotation is not available, therefore we need to use label.
for _, doc := range docs {
res := doc.GetKustomizeResource()
labels := res.GetLabels()
labels[document.DeployedByLabel] = document.InitinfraIdentifier
res.SetLabels(labels)
err := doc.SetKustomizeResource(&res)
if err != nil {
return err
}
}
return kctl.Apply(docs, ao)
}