-
Notifications
You must be signed in to change notification settings - Fork 1.5k
operators scaffolding #198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,7 @@ import ( | |
| var ( | ||
| installConfigCommand = kingpin.Command("install-config", "Generate the Install Config asset") | ||
| ignitionConfigsCommand = kingpin.Command("ignition-configs", "Generate the Ignition Config assets") | ||
| operatorsCommand = kingpin.Command("operators", "Generate the Operator assets") | ||
|
|
||
| dirFlag = kingpin.Flag("dir", "assets directory").Default(".").String() | ||
| logLevel = kingpin.Flag("log-level", "log level (e.g. \"debug\")").Default("info").Enum("debug", "info", "warn", "error", "fatal", "panic") | ||
|
|
@@ -33,6 +34,10 @@ func main() { | |
| assetStock.MasterIgnition(), | ||
| assetStock.WorkerIgnition(), | ||
| } | ||
| case operatorsCommand.FullCommand(): | ||
| targetAssets = []asset.Asset{ | ||
| assetStock.Operators(), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about all of the other manifests? This only renders |
||
| } | ||
| } | ||
|
|
||
| l, err := log.ParseLevel(*logLevel) | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,110 @@ | ||||
| package operators | ||||
|
|
||||
| import ( | ||||
| "crypto/rand" | ||||
| "encoding/base64" | ||||
| "errors" | ||||
| "fmt" | ||||
| "path/filepath" | ||||
|
|
||||
| "github.com/ghodss/yaml" | ||||
|
|
||||
| kubeaddon "github.com/coreos/tectonic-config/config/kube-addon" | ||||
| "github.com/openshift/installer/pkg/asset" | ||||
| "github.com/openshift/installer/pkg/asset/installconfig" | ||||
| "github.com/openshift/installer/pkg/types" | ||||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| ) | ||||
|
|
||||
| // kubeAddonOperator generates the network-operator-*.yml files | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||||
| type kubeAddonOperator struct { | ||||
| installConfigAsset asset.Asset | ||||
| installConfig *types.InstallConfig | ||||
| directory string | ||||
| } | ||||
|
|
||||
| var _ asset.Asset = (*kubeAddonOperator)(nil) | ||||
|
|
||||
| // Dependencies returns all of the dependencies directly needed by an | ||||
| // kubeAddonOperator asset. | ||||
| func (kao *kubeAddonOperator) Dependencies() []asset.Asset { | ||||
| return []asset.Asset{ | ||||
| kao.installConfigAsset, | ||||
| } | ||||
| } | ||||
|
|
||||
| // Generate generates the network-operator-config.yml and network-operator-manifest.yml files | ||||
| func (kao *kubeAddonOperator) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { | ||||
| ic, err := installconfig.GetInstallConfig(kao.installConfigAsset, dependencies) | ||||
| if err != nil { | ||||
| return nil, err | ||||
| } | ||||
| kao.installConfig = ic | ||||
|
|
||||
| // installconfig is ready, we can create the addon config from it now | ||||
| addonConfig, err := kao.addonConfig() | ||||
| if err != nil { | ||||
| return nil, err | ||||
| } | ||||
|
|
||||
| addonManifest, err := kao.manifest() | ||||
| if err != nil { | ||||
| return nil, err | ||||
| } | ||||
| state := &asset.State{ | ||||
| Contents: []asset.Content{ | ||||
| { | ||||
| Name: filepath.Join(kao.directory, "kube-addon-operator-config.yml"), | ||||
| Data: addonConfig, | ||||
| }, | ||||
| { | ||||
| Name: filepath.Join(kao.directory, "kube-addon-operator-manifests.yml"), | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Singular manifest. |
||||
| Data: []byte(addonManifest), | ||||
| }, | ||||
| }, | ||||
| } | ||||
| return state, nil | ||||
| } | ||||
|
|
||||
| func (kao *kubeAddonOperator) addonConfig() ([]byte, error) { | ||||
| addonConfig := kubeaddon.OperatorConfig{ | ||||
| TypeMeta: metav1.TypeMeta{ | ||||
| APIVersion: kubeaddon.APIVersion, | ||||
| Kind: kubeaddon.Kind, | ||||
| }, | ||||
| } | ||||
| addonConfig.CloudProvider = tectonicCloudProvider(kao.installConfig.Platform) | ||||
| addonConfig.ClusterConfig.APIServerURL = kao.getAPIServerURL() | ||||
| registrySecret, err := generateRandomID(16) | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just use
|
||||
| if err != nil { | ||||
| return nil, err | ||||
| } | ||||
| addonConfig.RegistryHTTPSecret = registrySecret | ||||
| return yaml.Marshal(addonConfig) | ||||
| } | ||||
|
|
||||
| func (kao *kubeAddonOperator) manifest() (string, error) { | ||||
| return "", nil | ||||
| } | ||||
|
|
||||
| func (kao *kubeAddonOperator) getAPIServerURL() string { | ||||
| return fmt.Sprintf("https://%s-api.%s:6443", kao.installConfig.ClusterName, kao.installConfig.BaseDomain) | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This ends up as |
||||
| } | ||||
|
|
||||
| // generateRandomID reproduce tf random_id behaviour | ||||
| // TODO: re-evaluate solution | ||||
| func generateRandomID(byteLength int) (string, error) { | ||||
| bytes := make([]byte, byteLength) | ||||
|
|
||||
| n, err := rand.Reader.Read(bytes) | ||||
| if n != byteLength { | ||||
| return "", errors.New("generated insufficient random bytes") | ||||
| } | ||||
| if err != nil { | ||||
| return "", err | ||||
| } | ||||
|
|
||||
| b64Str := base64.RawURLEncoding.EncodeToString(bytes) | ||||
|
|
||||
| return b64Str, nil | ||||
| } | ||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| package operators | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "net" | ||
| "path/filepath" | ||
|
|
||
| "github.com/ghodss/yaml" | ||
|
|
||
| "github.com/apparentlymart/go-cidr/cidr" | ||
| kubecore "github.com/coreos/tectonic-config/config/kube-core" | ||
| "github.com/openshift/installer/pkg/asset" | ||
| "github.com/openshift/installer/pkg/asset/installconfig" | ||
| "github.com/openshift/installer/pkg/types" | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| ) | ||
|
|
||
| const ( | ||
| authConfigOIDCClientID = "tectonic-kubectl" | ||
| authConfigOIDCGroupsClaim = "groups" | ||
| authConfigOIDCUsernameClaim = "email" | ||
| networkConfigAdvertiseAddress = "0.0.0.0" | ||
| ) | ||
|
|
||
| // kubeCoreOperator generates the kube-core-operator.yaml files | ||
| type kubeCoreOperator struct { | ||
| installConfigAsset asset.Asset | ||
| installConfig *types.InstallConfig | ||
| directory string | ||
| } | ||
|
|
||
| var _ asset.Asset = (*kubeCoreOperator)(nil) | ||
|
|
||
| // Dependencies returns all of the dependencies directly needed by an | ||
| // kubeCoreOperator asset. | ||
| func (kco *kubeCoreOperator) Dependencies() []asset.Asset { | ||
| return []asset.Asset{ | ||
| kco.installConfigAsset, | ||
| } | ||
| } | ||
|
|
||
| // Generate generates the kube-core-operator-config.yml files | ||
| func (kco *kubeCoreOperator) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { | ||
| ic, err := installconfig.GetInstallConfig(kco.installConfigAsset, dependencies) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| kco.installConfig = ic | ||
|
|
||
| // installconfig is ready, we can create the core config from it now | ||
| coreConfig, err := kco.coreConfig() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| data, err := yaml.Marshal(coreConfig) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to marshal core config: %v", err) | ||
| } | ||
| state := &asset.State{ | ||
| Contents: []asset.Content{ | ||
| { | ||
| Name: filepath.Join(kco.directory, "kube-core-operator-config.yml"), | ||
| Data: data, | ||
| }, | ||
| }, | ||
| } | ||
| return state, nil | ||
| } | ||
|
|
||
| func (kco *kubeCoreOperator) coreConfig() (*kubecore.OperatorConfig, error) { | ||
| coreConfig := kubecore.OperatorConfig{ | ||
| TypeMeta: metav1.TypeMeta{ | ||
| APIVersion: kubecore.APIVersion, | ||
| Kind: kubecore.Kind, | ||
| }, | ||
| } | ||
| coreConfig.ClusterConfig.APIServerURL = kco.getAPIServerURL() | ||
| coreConfig.AuthConfig.OIDCClientID = authConfigOIDCClientID | ||
| coreConfig.AuthConfig.OIDCIssuerURL = kco.getOicdIssuerURL() | ||
| coreConfig.AuthConfig.OIDCGroupsClaim = authConfigOIDCGroupsClaim | ||
| coreConfig.AuthConfig.OIDCUsernameClaim = authConfigOIDCUsernameClaim | ||
|
|
||
| svcCidr := kco.installConfig.Networking.ServiceCIDR | ||
| ip, err := cidr.Host(&net.IPNet{IP: svcCidr.IP, Mask: svcCidr.Mask}, 10) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| coreConfig.DNSConfig.ClusterIP = ip.String() | ||
|
|
||
| coreConfig.CloudProviderConfig.CloudConfigPath = "" | ||
| coreConfig.CloudProviderConfig.CloudProviderProfile = k8sCloudProvider(kco.installConfig.Platform) | ||
|
|
||
| coreConfig.RoutingConfig.Subdomain = kco.getBaseAddress() | ||
|
|
||
| coreConfig.NetworkConfig.ClusterCIDR = kco.installConfig.Networking.PodCIDR.String() | ||
| coreConfig.NetworkConfig.ServiceCIDR = kco.installConfig.Networking.ServiceCIDR.String() | ||
| coreConfig.NetworkConfig.AdvertiseAddress = networkConfigAdvertiseAddress | ||
| coreConfig.NetworkConfig.EtcdServers = kco.getEtcdServersURLs() | ||
|
|
||
| return &coreConfig, nil | ||
| } | ||
|
|
||
| func (kco *kubeCoreOperator) getAPIServerURL() string { | ||
| return fmt.Sprintf("https://%s-api.%s:6443", kco.installConfig.ClusterName, kco.installConfig.BaseDomain) | ||
| } | ||
|
|
||
| func (kco *kubeCoreOperator) getEtcdServersURLs() string { | ||
| return fmt.Sprintf("https://%s-etcd.%s:2379", kco.installConfig.ClusterName, kco.installConfig.BaseDomain) | ||
| } | ||
|
|
||
| func (kco *kubeCoreOperator) getOicdIssuerURL() string { | ||
| return fmt.Sprintf("https://%s.%s/identity", kco.installConfig.ClusterName, kco.installConfig.BaseDomain) | ||
| } | ||
|
|
||
| func (kco *kubeCoreOperator) getBaseAddress() string { | ||
| return fmt.Sprintf("%s.%s", kco.installConfig.ClusterName, kco.installConfig.BaseDomain) | ||
| } | ||
|
|
||
| // Converts a platform to the cloudProvider that k8s understands | ||
| func k8sCloudProvider(platform types.Platform) string { | ||
| if platform.AWS != nil { | ||
| return "aws" | ||
| } | ||
| if platform.Libvirt != nil { | ||
| //return "libvirt" | ||
| } | ||
| return "" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| package operators | ||
|
|
||
| import ( | ||
| "path/filepath" | ||
|
|
||
| "github.com/ghodss/yaml" | ||
|
|
||
| "github.com/openshift/installer/pkg/asset" | ||
| "github.com/openshift/installer/pkg/asset/installconfig" | ||
| "github.com/openshift/installer/pkg/types" | ||
|
|
||
| tectonicnetwork "github.com/coreos/tectonic-config/config/tectonic-network" | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| //"github.com/openshift/openshift-network-operator/pkg/apis/networkoperator" | ||
| ) | ||
|
|
||
| const ( | ||
| defaultMTU = "1450" | ||
| ) | ||
|
|
||
| // networkOperator generates the network-operator-*.yml files | ||
| type networkOperator struct { | ||
| installConfigAsset asset.Asset | ||
| installConfig *types.InstallConfig | ||
| directory string | ||
| } | ||
|
|
||
| var _ asset.Asset = (*networkOperator)(nil) | ||
|
|
||
| // Dependencies returns all of the dependencies directly needed by an | ||
| // networkOperator asset. | ||
| func (no *networkOperator) Dependencies() []asset.Asset { | ||
| return []asset.Asset{ | ||
| no.installConfigAsset, | ||
| } | ||
| } | ||
|
|
||
| // Generate generates the network-operator-config.yml and network-operator-manifest.yml files | ||
| func (no *networkOperator) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { | ||
| ic, err := installconfig.GetInstallConfig(no.installConfigAsset, dependencies) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| no.installConfig = ic | ||
|
|
||
| // installconfig is ready, we can create the core config from it now | ||
| netConfig, err := no.netConfig() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| netManifest, err := no.manifest() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| state := &asset.State{ | ||
| Contents: []asset.Content{ | ||
| { | ||
| Name: filepath.Join(no.directory, "network-operator-config.yml"), | ||
| Data: netConfig, | ||
| }, | ||
| { | ||
| Name: filepath.Join(no.directory, "network-operator-manifests.yml"), | ||
| Data: netManifest, | ||
| }, | ||
| }, | ||
| } | ||
| return state, nil | ||
| } | ||
|
|
||
| func (no *networkOperator) netConfig() ([]byte, error) { | ||
| networkConfig := tectonicnetwork.OperatorConfig{ | ||
| TypeMeta: metav1.TypeMeta{ | ||
| APIVersion: tectonicnetwork.APIVersion, | ||
| Kind: tectonicnetwork.Kind, | ||
| }, | ||
| } | ||
|
|
||
| networkConfig.PodCIDR = no.installConfig.Networking.PodCIDR.String() | ||
| networkConfig.CalicoConfig.MTU = defaultMTU | ||
| networkConfig.NetworkProfile = tectonicnetwork.NetworkType(no.installConfig.Networking.Type) | ||
|
|
||
| return yaml.Marshal(networkConfig) | ||
| } | ||
|
|
||
| func (no *networkOperator) manifest() ([]byte, error) { | ||
| return []byte(""), nil | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be called "manifests".