From 43fd8f233fe8c0fe731250a2e77697da4818105c Mon Sep 17 00:00:00 2001 From: easter1007 Date: Tue, 8 Aug 2023 15:08:19 +0800 Subject: [PATCH 1/2] new nkd --- .gitignore | 2 + nkd/app/cmd/check.go | 20 + nkd/app/cmd/cmd.go | 25 + nkd/app/cmd/config.go | 22 + nkd/app/cmd/deploy.go | 23 + nkd/app/cmd/destroy.go | 21 + nkd/app/cmd/extend.go | 22 + nkd/app/cmd/init.go | 28 ++ nkd/app/cmd/upgrade.go | 1 + nkd/app/nkd.go | 13 + nkd/app/phase/config/print.go | 431 ++++++++++++++++++ nkd/app/phase/deploy/deploy.go | 15 + nkd/app/phase/deploy/infra/assets/assets.go | 22 + .../deploy/infra/assets/cluster/cluster.go | 150 ++++++ .../deploy/infra/assets/cluster/tfvars.go | 83 ++++ nkd/app/phase/deploy/infra/terraform/init.go | 41 ++ .../phase/deploy/infra/terraform/logger.go | 37 ++ .../infra/terraform/providers/providers.go | 35 ++ nkd/app/phase/deploy/infra/terraform/stage.go | 26 ++ .../terraform/stages/openstack/stages.go | 19 + .../infra/terraform/stages/platform/stages.go | 19 + .../deploy/infra/terraform/stages/split.go | 43 ++ nkd/app/phase/deploy/infra/terraform/state.go | 51 +++ .../phase/deploy/infra/terraform/terraform.go | 98 ++++ .../deploy/infra/tfvars/openstack/tfvars.go | 44 ++ nkd/app/phase/init/.DS_Store | Bin 0 -> 6148 bytes nkd/app/phase/init/config/cert/cacert.go | 37 ++ nkd/app/phase/init/config/cert/certapi.go | 58 +++ nkd/app/phase/init/config/cert/etcd.go | 31 ++ .../phase/init/config/cert/selfsignedcert.go | 101 ++++ nkd/app/phase/init/config/cert/signedcerts.go | 130 ++++++ nkd/app/phase/init/config/cert/tools.go | 103 +++++ nkd/app/phase/init/config/certs.go | 15 + nkd/app/phase/init/config/infra.go | 17 + nkd/app/phase/init/config/k8s.go | 15 + nkd/app/phase/workflow/Phase.go | 8 + nkd/app/phase/workflow/runner.go | 91 ++++ nkd/nkd.go | 7 + nkd/resource/assert/terrafrom/terraform | 0 nkd/resource/templates/config.json | 83 ++++ nkd/resource/templates/k8s/k8s-master.bu | 0 nkd/resource/templates/openstack.json | 56 +++ .../templates/terraform/master/main.tf | 0 nkd/resource/templates/terraform/node/main.tf | 0 44 files changed, 2043 insertions(+) create mode 100644 .gitignore create mode 100644 nkd/app/cmd/check.go create mode 100644 nkd/app/cmd/cmd.go create mode 100644 nkd/app/cmd/config.go create mode 100644 nkd/app/cmd/deploy.go create mode 100644 nkd/app/cmd/destroy.go create mode 100644 nkd/app/cmd/extend.go create mode 100644 nkd/app/cmd/init.go create mode 100644 nkd/app/cmd/upgrade.go create mode 100644 nkd/app/nkd.go create mode 100644 nkd/app/phase/config/print.go create mode 100644 nkd/app/phase/deploy/deploy.go create mode 100755 nkd/app/phase/deploy/infra/assets/assets.go create mode 100644 nkd/app/phase/deploy/infra/assets/cluster/cluster.go create mode 100644 nkd/app/phase/deploy/infra/assets/cluster/tfvars.go create mode 100644 nkd/app/phase/deploy/infra/terraform/init.go create mode 100644 nkd/app/phase/deploy/infra/terraform/logger.go create mode 100644 nkd/app/phase/deploy/infra/terraform/providers/providers.go create mode 100644 nkd/app/phase/deploy/infra/terraform/stage.go create mode 100644 nkd/app/phase/deploy/infra/terraform/stages/openstack/stages.go create mode 100644 nkd/app/phase/deploy/infra/terraform/stages/platform/stages.go create mode 100644 nkd/app/phase/deploy/infra/terraform/stages/split.go create mode 100644 nkd/app/phase/deploy/infra/terraform/state.go create mode 100644 nkd/app/phase/deploy/infra/terraform/terraform.go create mode 100644 nkd/app/phase/deploy/infra/tfvars/openstack/tfvars.go create mode 100644 nkd/app/phase/init/.DS_Store create mode 100644 nkd/app/phase/init/config/cert/cacert.go create mode 100644 nkd/app/phase/init/config/cert/certapi.go create mode 100755 nkd/app/phase/init/config/cert/etcd.go create mode 100644 nkd/app/phase/init/config/cert/selfsignedcert.go create mode 100644 nkd/app/phase/init/config/cert/signedcerts.go create mode 100644 nkd/app/phase/init/config/cert/tools.go create mode 100644 nkd/app/phase/init/config/certs.go create mode 100644 nkd/app/phase/init/config/infra.go create mode 100644 nkd/app/phase/init/config/k8s.go create mode 100644 nkd/app/phase/workflow/Phase.go create mode 100644 nkd/app/phase/workflow/runner.go create mode 100644 nkd/nkd.go create mode 100644 nkd/resource/assert/terrafrom/terraform create mode 100644 nkd/resource/templates/config.json create mode 100644 nkd/resource/templates/k8s/k8s-master.bu create mode 100644 nkd/resource/templates/openstack.json create mode 100644 nkd/resource/templates/terraform/master/main.tf create mode 100644 nkd/resource/templates/terraform/node/main.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6e8bef9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +./nkd/nkd +test.yaml diff --git a/nkd/app/cmd/check.go b/nkd/app/cmd/check.go new file mode 100644 index 0000000..f302929 --- /dev/null +++ b/nkd/app/cmd/check.go @@ -0,0 +1,20 @@ +package cmd + +import ( + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" + + "github.com/spf13/cobra" +) + +func NewCheckCommand() *cobra.Command { + checkRunner := workflow.NewRunner() + cmd := &cobra.Command{ + Use: "check", + Short: "Use this command to check assert", + RunE: func(cmd *cobra.Command, args []string) error { + return checkRunner.Run() + }, + } + + return cmd +} diff --git a/nkd/app/cmd/cmd.go b/nkd/app/cmd/cmd.go new file mode 100644 index 0000000..3880a35 --- /dev/null +++ b/nkd/app/cmd/cmd.go @@ -0,0 +1,25 @@ +package cmd + +import ( + "io" + + "github.com/spf13/cobra" +) + +func NewNkdCommand(in io.Reader, out, err io.Writer) *cobra.Command { + cmds := &cobra.Command{ + Use: "nkd", + Short: "nkd: easily bootstrap a secure Kubernetes cluster", + } + + cmds.ResetFlags() + // TODO: 修改名称 + cmds.AddCommand(NewConfigCommand()) + cmds.AddCommand(NewCheckCommand()) + cmds.AddCommand(NewInitCommand()) + cmds.AddCommand(NewDeployCommand()) + //添加 NewDeployCommand + cmds.AddCommand(NewExtendCommand()) + //添加 NewDestroyCommand + return cmds +} diff --git a/nkd/app/cmd/config.go b/nkd/app/cmd/config.go new file mode 100644 index 0000000..98efb51 --- /dev/null +++ b/nkd/app/cmd/config.go @@ -0,0 +1,22 @@ +package cmd + +import ( + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/config" + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" + + "github.com/spf13/cobra" +) + +func NewConfigCommand() *cobra.Command { + initRunner := workflow.NewRunner() + cmd := &cobra.Command{ + Use: "config", + Short: "Manage a k8s cluster", + RunE: func(cmd *cobra.Command, args []string) error { + return initRunner.Run() + }, + } + cmd.AddCommand(config.NewConfigNkdCommand()) + + return cmd +} diff --git a/nkd/app/cmd/deploy.go b/nkd/app/cmd/deploy.go new file mode 100644 index 0000000..43ea64f --- /dev/null +++ b/nkd/app/cmd/deploy.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/deploy" + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" + + "github.com/spf13/cobra" +) + +func NewDeployCommand() *cobra.Command { + deployRunner := workflow.NewRunner() + cmd := &cobra.Command{ + Use: "deploy", + Short: "Use this command to deploy cluster", + RunE: func(cmd *cobra.Command, args []string) error { + + return deployRunner.Run() + }, + } + deployRunner.AppendPhase(deploy.NewDeployClusterCmd()) + + return cmd +} diff --git a/nkd/app/cmd/destroy.go b/nkd/app/cmd/destroy.go new file mode 100644 index 0000000..e8e5c7c --- /dev/null +++ b/nkd/app/cmd/destroy.go @@ -0,0 +1,21 @@ +package cmd + +import ( + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" + + "github.com/spf13/cobra" +) + +func NewDestroyCommand() *cobra.Command { + destroyRunner := workflow.NewRunner() + cmd := &cobra.Command{ + Use: "destroy", + Short: "Use this command to destroy a config or a cluster", + RunE: func(cmd *cobra.Command, args []string) error { + + return destroyRunner.Run() + }, + } + + return cmd +} diff --git a/nkd/app/cmd/extend.go b/nkd/app/cmd/extend.go new file mode 100644 index 0000000..287e66b --- /dev/null +++ b/nkd/app/cmd/extend.go @@ -0,0 +1,22 @@ +package cmd + +import ( + "fmt" + + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" + + "github.com/spf13/cobra" +) + +func NewExtendCommand() *cobra.Command { + extendRunner := workflow.NewRunner() + cmd := &cobra.Command{ + Use: "extend", + Short: "Use join to join a node to a cluster", + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println("hello world") + return extendRunner.Run() + }, + } + return cmd +} diff --git a/nkd/app/cmd/init.go b/nkd/app/cmd/init.go new file mode 100644 index 0000000..89fb97e --- /dev/null +++ b/nkd/app/cmd/init.go @@ -0,0 +1,28 @@ +package cmd + +import ( + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/init/config" + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" + + "github.com/spf13/cobra" +) + +type initData struct { +} + +func NewInitCommand() *cobra.Command { + initRunner := workflow.NewRunner() + cmd := &cobra.Command{ + Use: "init", + Short: "Use this command to init insert or config", + RunE: func(cmd *cobra.Command, args []string) error { + return initRunner.Run() + }, + } + // TODO: 暂时不需要证书,生成证书的方式,控制生成 + initRunner.AppendPhase(config.NewGenerateCertsCmd()) + initRunner.AppendPhase(config.NewGenerateK8sCmd()) + initRunner.AppendPhase(config.NewGenerateInfraCmd()) + + return cmd +} diff --git a/nkd/app/cmd/upgrade.go b/nkd/app/cmd/upgrade.go new file mode 100644 index 0000000..1d619dd --- /dev/null +++ b/nkd/app/cmd/upgrade.go @@ -0,0 +1 @@ +package cmd diff --git a/nkd/app/nkd.go b/nkd/app/nkd.go new file mode 100644 index 0000000..52ec8fc --- /dev/null +++ b/nkd/app/nkd.go @@ -0,0 +1,13 @@ +package app + +import ( + "os" + + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/cmd" +) + +func Run() error { + cmd := cmd.NewNkdCommand(os.Stdin, os.Stdout, os.Stderr) + // pflag.CommandLine.MarkHidden("version") + return cmd.Execute() +} diff --git a/nkd/app/phase/config/print.go b/nkd/app/phase/config/print.go new file mode 100644 index 0000000..d6d45dd --- /dev/null +++ b/nkd/app/phase/config/print.go @@ -0,0 +1,431 @@ +package config + +// { +// "cluster": { +// "name": "" +// }, +// "system":{ +// "hostname": [], +// "user_name": "", +// "password": "", +// "certs": { +// "timeout": "" +// } +// }, +// "repo": { +// "secret": {}, +// "registry": {} +// }, +// "k8s":{ +// "kubeadm": {} +// }, +// "infra":{ +// "platform": "", +// "vm_size": { +// "master": { +// "vcpus": "4", +// "ram": "8192", +// "disk": "64" +// }, +// "node": { +// "vcpus": "4", +// "ram": "8192", +// "disk": "64" +// } +// }, +// "openstack": { +// "user_name": "admin", +// "password": "qwer1234", +// "tenant_name": "admin", +// "auth_url": "", +// "region": "RegionOne", +// "master_instance_name": [], +// "worker_instance_name": [], +// "network_name": "", +// "master_ip": [], +// "worker_ip": [], +// "float_ip_pool": "" +// }, +// "libvirt": {}, +// "aliyun": {} +// }, +// "addon": [ +// {"name": "", "path": ""}, +// {} +// ] +// } + +import ( + "fmt" + "io/ioutil" + "time" + + "github.com/spf13/cobra" + "gopkg.in/yaml.v2" +) + +type System struct { + Hostname string `yaml:"hostname"` + Username string `yaml:"username"` + Password string `yaml:"password"` +} + +type Openstack struct { + User_name string + Password string + Tenant_name string + Auth_url string + Region string + Master_instance_name []string + Worker_instance_name []string + Internal_network string + External_network string + Master_ip []string + Worker_ip []string +} + +type Libvirt struct { +} + +type Size struct { + Vcpus int + Ram int + Disk int +} + +type Vmsize struct { + Master Size + Worker Size +} + +type Infra struct { + Platform string + openstack Openstack + vmsize Vmsize +} + +type Cluster struct { + Name string `yaml:"cluster-name"` +} + +type Repo struct { + Secret []map[string]string `yaml:"secret"` + Registry string `yaml:"registry"` +} + +type TypeMeta struct { + Kind string + ApiVersion string +} + +type BootstrapTokenString struct { + ID string `json:"-"` + Secret string `json:"-" datapolicy:"token"` +} + +type Duration struct { + time.Duration `protobuf:"varint,1,opt,name=duration,casttype=time.Duration"` +} + +type APIEndpoint struct { + AdvertiseAddress string + BindPort int32 +} + +type BootstrapToken struct { + Token *BootstrapTokenString + Groups []string + TTL *Duration + Usages []string +} +type TaintEffect string + +type PullPolicy string + +type Time struct { + time.Time `protobuf:"-"` +} +type Taint struct { + // Required. The taint key to be applied to a node. + Key string `json:"key" protobuf:"bytes,1,opt,name=key"` + // The taint value corresponding to the taint key. + // +optional + Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` + // Required. The effect of the taint on pods + // that do not tolerate the taint. + // Valid effects are NoSchedule, PreferNoSchedule and NoExecute. + Effect TaintEffect `json:"effect" protobuf:"bytes,3,opt,name=effect,casttype=TaintEffect"` + // TimeAdded represents the time at which the taint was added. + // It is only written for NoExecute taints. + // +optional + TimeAdded *Time `json:"timeAdded,omitempty" protobuf:"bytes,4,opt,name=timeAdded"` +} +type NodeRegistrationOptions struct { + Name string + CRISocket string + Taints []Taint + KubeletExtraArgs map[string]string + IgnorePreflightErrors []string + ImagePullPolicy PullPolicy `json:"imagePullPolicy,omitempty"` +} + +type ComponentConfigMap map[string]ComponentConfig + +type ComponentConfig interface { + // DeepCopy should create a new deep copy of the component config in place + DeepCopy() ComponentConfig + + // Marshal is marshalling the config into a YAML document returned as a byte slice + Marshal() ([]byte, error) + + // Unmarshal loads the config from a document map. No config in the document map is no error. + + // Default patches the component config with kubeadm preferred defaults + Default(cfg *ClusterConfiguration, localAPIEndpoint *APIEndpoint, nodeRegOpts *NodeRegistrationOptions) + + // IsUserSupplied indicates if the component config was supplied or modified by a user or was kubeadm generated + IsUserSupplied() bool + + // SetUserSupplied sets the state of the component config "user supplied" flag to, either true, or false. + SetUserSupplied(userSupplied bool) + + // Mutate allows applying pre-defined modifications to the config before it's marshaled. + Mutate() error + + // Set can be used to set the internal configuration in the ComponentConfig + Set(interface{}) + + // Get can be used to get the internal configuration in the ComponentConfig + Get() interface{} +} + +type Etcd struct { + + // Local provides configuration knobs for configuring the local etcd instance + // Local and External are mutually exclusive + Local *LocalEtcd + + // External describes how to connect to an external etcd cluster + // Local and External are mutually exclusive + External *ExternalEtcd +} + +type ImageMeta struct { + // ImageRepository sets the container registry to pull images from. + // if not set, the ImageRepository defined in ClusterConfiguration will be used instead. + ImageRepository string + + // ImageTag allows to specify a tag for the image. + // In case this value is set, kubeadm does not change automatically the version of the above components during upgrades. + ImageTag string + + //TODO: evaluate if we need also a ImageName based on user feedbacks +} + +// LocalEtcd describes that kubeadm should run an etcd cluster locally +type LocalEtcd struct { + // ImageMeta allows to customize the container used for etcd + ImageMeta `json:",inline"` + + // DataDir is the directory etcd will place its data. + // Defaults to "/var/lib/etcd". + DataDir string + + // ExtraArgs are extra arguments provided to the etcd binary + // when run inside a static pod. + // A key in this map is the flag name as it appears on the + // command line except without leading dash(es). + ExtraArgs map[string]string + + // ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert. + ServerCertSANs []string + // PeerCertSANs sets extra Subject Alternative Names for the etcd peer signing cert. + PeerCertSANs []string +} + +// ExternalEtcd describes an external etcd cluster +type ExternalEtcd struct { + + // Endpoints of etcd members. Useful for using external etcd. + // If not provided, kubeadm will run etcd in a static pod. + Endpoints []string + // CAFile is an SSL Certificate Authority file used to secure etcd communication. + CAFile string + // CertFile is an SSL certification file used to secure etcd communication. + CertFile string + // KeyFile is an SSL key file used to secure etcd communication. + KeyFile string +} + +type Networking struct { + // ServiceSubnet is the subnet used by k8s services. Defaults to "10.96.0.0/12". + ServiceSubnet string + // PodSubnet is the subnet used by pods. + PodSubnet string + // DNSDomain is the dns domain used by k8s services. Defaults to "cluster.local". + DNSDomain string +} +type HostPathType string +type HostPathMount struct { + // Name of the volume inside the pod template. + Name string + // HostPath is the path in the host that will be mounted inside + // the pod. + HostPath string + // MountPath is the path inside the pod where hostPath will be mounted. + MountPath string + // ReadOnly controls write access to the volume + ReadOnly bool + // PathType is the type of the HostPath. + PathType HostPathType +} +type ControlPlaneComponent struct { + // ExtraArgs is an extra set of flags to pass to the control plane component. + // A key in this map is the flag name as it appears on the + // command line except without leading dash(es). + // TODO: This is temporary and ideally we would like to switch all components to + // use ComponentConfig + ConfigMaps. + ExtraArgs map[string]string + + // ExtraVolumes is an extra set of host volumes, mounted to the control plane component. + ExtraVolumes []HostPathMount +} +type APIServer struct { + ControlPlaneComponent + + // CertSANs sets extra Subject Alternative Names for the API Server signing cert. + CertSANs []string + + // TimeoutForControlPlane controls the timeout that we use for API server to appear + TimeoutForControlPlane Duration +} +type DNS struct { + // ImageMeta allows to customize the image used for the DNS component + ImageMeta `json:",inline"` +} +type ClusterConfiguration struct { + TypeMeta + + // ComponentConfigs holds component configs known to kubeadm, should long-term only exist in the internal kubeadm API + // +k8s:conversion-gen=false + ComponentConfigs ComponentConfigMap + + // Etcd holds configuration for etcd. + Etcd Etcd + + // Networking holds configuration for the networking topology of the cluster. + Networking Networking + + // KubernetesVersion is the target version of the control plane. + KubernetesVersion string + + // CIKubernetesVersion is the target CI version of the control plane. + // Useful for running kubeadm with CI Kubernetes version. + // +k8s:conversion-gen=false + CIKubernetesVersion string + + // ControlPlaneEndpoint sets a stable IP address or DNS name for the control plane; it + // can be a valid IP address or a RFC-1123 DNS subdomain, both with optional TCP port. + // In case the ControlPlaneEndpoint is not specified, the AdvertiseAddress + BindPort + // are used; in case the ControlPlaneEndpoint is specified but without a TCP port, + // the BindPort is used. + // Possible usages are: + // e.g. In a cluster with more than one control plane instances, this field should be + // assigned the address of the external load balancer in front of the + // control plane instances. + // e.g. in environments with enforced node recycling, the ControlPlaneEndpoint + // could be used for assigning a stable DNS to the control plane. + ControlPlaneEndpoint string + + // APIServer contains extra settings for the API server control plane component + APIServer APIServer + + // ControllerManager contains extra settings for the controller manager control plane component + ControllerManager ControlPlaneComponent + + // Scheduler contains extra settings for the scheduler control plane component + Scheduler ControlPlaneComponent + + // DNS defines the options for the DNS add-on installed in the cluster. + DNS DNS + + // CertificatesDir specifies where to store or look for all required certificates. + CertificatesDir string + + // ImageRepository sets the container registry to pull images from. + // If empty, `registry.k8s.io` will be used by default; in case of kubernetes version is a CI build (kubernetes version starts with `ci/`) + // `gcr.io/k8s-staging-ci-images` will be used as a default for control plane components and for kube-proxy, while `registry.k8s.io` + // will be used for all the other images. + ImageRepository string + + // CIImageRepository is the container registry for core images generated by CI. + // Useful for running kubeadm with images from CI builds. + // +k8s:conversion-gen=false + CIImageRepository string + + // FeatureGates enabled by the user. + FeatureGates map[string]bool + + // The cluster name + ClusterName string +} + +type Patches struct { + // Directory is a path to a directory that contains files named "target[suffix][+patchtype].extension". + // For example, "kube-apiserver0+merge.yaml" or just "etcd.json". "target" can be one of + // "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". + // "patchtype" can be one of "strategic" "merge" or "json" and they match the patch formats supported by kubectl. + // The default "patchtype" is "strategic". "extension" must be either "json" or "yaml". + // "suffix" is an optional string that can be used to determine which patches are applied + // first alpha-numerically. + Directory string +} + +type Kubeadm struct { + ClusterConfiguration + TypeMeta + BootstrapTokens []BootstrapToken + LocalAPIEndpoint APIEndpoint + NodeRegistration NodeRegistrationOptions + CertificateKey string + Patches *Patches +} + +type Addon struct { + Addons []map[string]string +} +type Nkd struct { + Cluster Cluster + System System + Repo Repo + Kubeadm Kubeadm + Addon Addon + Infra Infra +} + +func NewConfigNkdCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "print", + Short: "use this command to print nkd config", + RunE: func(cmd *cobra.Command, args []string) error { + return printDefaultNkdConfig() + }, + } + return cmd +} + +func printDefaultNkdConfig() error { + system := System{Hostname: "master1", Username: "root", Password: "string"} + cluster := Cluster{Name: "cluster1"} + nkd := Nkd{System: system, Cluster: cluster} + conf, err := yaml.Marshal(&nkd) + fmt.Println(string(conf)) + if err != nil { + return err + } + err = ioutil.WriteFile("test.yaml", conf, 644) + if err != nil { + return err + } + return err +} diff --git a/nkd/app/phase/deploy/deploy.go b/nkd/app/phase/deploy/deploy.go new file mode 100644 index 0000000..8218cbc --- /dev/null +++ b/nkd/app/phase/deploy/deploy.go @@ -0,0 +1,15 @@ +package deploy + +import "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" + +func NewDeployClusterCmd() workflow.Phase { + return workflow.Phase{ + Name: "deploy", + Short: "run deploy to deploy k8s cluster", + Run: runDeployK8sCluster, + } +} + +func runDeployK8sCluster() error { + return nil +} diff --git a/nkd/app/phase/deploy/infra/assets/assets.go b/nkd/app/phase/deploy/infra/assets/assets.go new file mode 100755 index 0000000..81fa8cd --- /dev/null +++ b/nkd/app/phase/deploy/infra/assets/assets.go @@ -0,0 +1,22 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package assets + +type File struct { + Filename string + Data []byte +} diff --git a/nkd/app/phase/deploy/infra/assets/cluster/cluster.go b/nkd/app/phase/deploy/infra/assets/cluster/cluster.go new file mode 100644 index 0000000..5b38e6a --- /dev/null +++ b/nkd/app/phase/deploy/infra/assets/cluster/cluster.go @@ -0,0 +1,150 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cluster + +import ( + "os" + "path/filepath" + + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/assets" + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform" + "github.com/hashicorp/terraform-exec/tfexec" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +/* + installDir:自定义工作目录,在该路径下自动创建terraform文件夹 + dir:该路径存放tf配置文件 + terraformDir:该路径包含bin、plugins目录,存放terraform执行文件以及所需plugins +*/ + +type InfraProvider interface { + Create() + Destroy() +} + +type Cluster struct { + InstallDir string + Platform string + Name string +} + +// TODO: 配置文件准备阶段 + +func (c *Cluster) Create() error { + terraformDir := filepath.Join(c.InstallDir, "terraform") + dir := filepath.Join(terraformDir, c.Platform, c.Name) + + terraformVariables := &TerraformVariables{} + tfvarsFiles := make([]*assets.File, 0, len(terraformVariables.Files())+len(c.Platform)+len(c.Name)) + tfvarsFiles = append(tfvarsFiles, terraformVariables.Files()...) + + logrus.Infof("start to create %s in %s", c.Name, c.Platform) + + outputs, err := c.applyStage(dir, terraformDir, tfvarsFiles) + if err != nil { + return errors.Wrapf(err, "failed to create %s in %s", c.Name, c.Platform) + } + + logrus.Info(string(outputs.Data)) + logrus.Infof("succeed in creating %s in %s", c.Name, c.Platform) + + return nil +} + +func (c *Cluster) applyStage(dir string, terraformDir string, tfvarsFiles []*assets.File) (*assets.File, error) { + var applyOpts []tfexec.ApplyOption + for _, file := range tfvarsFiles { + if err := os.WriteFile(filepath.Join(dir, file.Filename), file.Data, 0o600); err != nil { + return nil, err + } + applyOpts = append(applyOpts, tfexec.VarFile(filepath.Join(dir, file.Filename))) + } + + return c.applyTerraform(dir, terraformDir, applyOpts...) +} + +func (c *Cluster) applyTerraform(dir string, terraformDir string, applyOpts ...tfexec.ApplyOption) (*assets.File, error) { + applyErr := terraform.TFApply(dir, terraformDir, applyOpts...) + + _, err := os.Stat(filepath.Join(dir, "terraform.tfstate")) + if os.IsNotExist(err) { + logrus.Errorf("Failed to read tfstate: %v", err) + return nil, errors.Wrap(err, "failed to read tfstate") + } + + if applyErr != nil { + return nil, errors.WithMessage(applyErr, "failed to apply Terraform") + } + + outputs, err := terraform.Outputs(dir, terraformDir) + if err != nil { + return nil, errors.Wrap(err, "could not get outputs file") + } + + outputsFile := &assets.File{ + Filename: "outputs", + Data: outputs, + } + + return outputsFile, nil +} + +func (c *Cluster) Destroy() error { + terraformDir := filepath.Join(c.InstallDir, "terraform") + dir := filepath.Join(terraformDir, c.Platform, c.Name) + + logrus.Infof("start to destroy %s in %s", c.Name, c.Platform) + + // Question: Destroy的tfvarsFiles的获取 + + terraformVariables := &TerraformVariables{} + tfvarsFiles := make([]*assets.File, 0, len(terraformVariables.Files())+len(c.Platform)+len(c.Name)) + tfvarsFiles = append(tfvarsFiles, terraformVariables.Files()...) + + err := c.destroyStage(dir, terraformDir, tfvarsFiles) + if err != nil { + return errors.Wrapf(err, "failed to destroy %s in %s", c.Name, c.Platform) + } + os.Remove(dir) + + logrus.Infof("succeed in destroying %s in %s", c.Name, c.Platform) + + return nil +} + +func (c *Cluster) destroyStage(dir string, terraformDir string, tfvarsFiles []*assets.File) error { + var destroyOpts []tfexec.DestroyOption + for _, file := range tfvarsFiles { + if err := os.WriteFile(filepath.Join(dir, file.Filename), file.Data, 0o600); err != nil { + return err + } + destroyOpts = append(destroyOpts, tfexec.VarFile(filepath.Join(dir, file.Filename))) + } + + return destroyTerraform(dir, terraformDir, destroyOpts...) +} + +func destroyTerraform(dir string, terraformDir string, destroyOpts ...tfexec.DestroyOption) error { + destroyErr := terraform.TFDestroy(dir, terraformDir, destroyOpts...) + if destroyErr != nil { + return errors.WithMessage(destroyErr, "failed to destroy Terraform") + } + + return nil +} diff --git a/nkd/app/phase/deploy/infra/assets/cluster/tfvars.go b/nkd/app/phase/deploy/infra/assets/cluster/tfvars.go new file mode 100644 index 0000000..a2f1b17 --- /dev/null +++ b/nkd/app/phase/deploy/infra/assets/cluster/tfvars.go @@ -0,0 +1,83 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cluster + +import ( + "encoding/json" + "html/template" + "os" + "path/filepath" + + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/assets" + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/tfvars/openstack" + "github.com/pkg/errors" +) + +type TerraformVariables struct { + FileList []*assets.File +} + +func (t *TerraformVariables) Files() []*assets.File { + return t.FileList +} + +func Generate() error { + // 从文件中读取 jsonData + jsonData, err := os.ReadFile("data/json/openstack/main.tf.json") + if err != nil { + return errors.Wrap(err, "error reading json data") + } + + // 解析 JSON 数据 + var terraformData openstack.TerraformData + err = json.Unmarshal(jsonData, &terraformData) + if err != nil { + return errors.Wrap(err, "error parsing json data") + } + + // 从文件中读取 terraformConfig + terraformConfig, err := os.ReadFile("data/templates/openstack/main.tf.template") + if err != nil { + return errors.Wrap(err, "error reading terraform config template") + } + + // 使用模板填充数据 + tmpl, err := template.New("terraform").Parse(string(terraformConfig)) + if err != nil { + return errors.Wrap(err, "error creating terraform config template") + } + + // 创建一个新的文件用于写入填充后的数据 + tfDir := filepath.Join("/root", "terraform") + if err := os.MkdirAll(tfDir, os.ModePerm); err != nil { + return errors.Wrap(err, "could not create the terraform directory") + } + + outputFile, err := os.Create(filepath.Join(tfDir, "main.tf")) + if err != nil { + return errors.Wrap(err, "error creating terraform config") + } + defer outputFile.Close() + + // 将填充后的数据写入文件 + err = tmpl.Execute(outputFile, terraformData) + if err != nil { + return errors.Wrap(err, "error executing terraform config") + } + + return nil +} diff --git a/nkd/app/phase/deploy/infra/terraform/init.go b/nkd/app/phase/deploy/infra/terraform/init.go new file mode 100644 index 0000000..cbd3ad3 --- /dev/null +++ b/nkd/app/phase/deploy/infra/terraform/init.go @@ -0,0 +1,41 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package terraform + +import ( + "context" + "path/filepath" + + "github.com/hashicorp/terraform-exec/tfexec" + "github.com/pkg/errors" +) + +// terraform init +func TFInit(dir string, terraformDir string) error { + tf, err := newTFExec(dir, terraformDir) + if err != nil { + return errors.Wrap(err, "failed to create a new tfexec") + } + + // 使用本地terraform插件 + err = tf.Init(context.Background(), tfexec.PluginDir(filepath.Join(terraformDir, "plugins"))) + if err != nil { + return errors.Wrap(err, "failed to init terraform") + } + + return nil +} diff --git a/nkd/app/phase/deploy/infra/terraform/logger.go b/nkd/app/phase/deploy/infra/terraform/logger.go new file mode 100644 index 0000000..54add90 --- /dev/null +++ b/nkd/app/phase/deploy/infra/terraform/logger.go @@ -0,0 +1,37 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package terraform + +import ( + "github.com/sirupsen/logrus" +) + +type printfer struct { + logger *logrus.Logger + level logrus.Level +} + +func newPrintfer() *printfer { + return &printfer{ + logger: logrus.StandardLogger(), + level: logrus.DebugLevel, + } +} + +func (p *printfer) Printf(format string, ifs ...interface{}) { + p.logger.Logf(p.level, format, ifs...) +} diff --git a/nkd/app/phase/deploy/infra/terraform/providers/providers.go b/nkd/app/phase/deploy/infra/terraform/providers/providers.go new file mode 100644 index 0000000..986ee8a --- /dev/null +++ b/nkd/app/phase/deploy/infra/terraform/providers/providers.go @@ -0,0 +1,35 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package providers + +import "fmt" + +var ( + OpenStack = provider("openstack") +) + +type Provider struct { + Name string + Source string +} + +func provider(name string) Provider { + return Provider{ + Name: name, + Source: fmt.Sprintf("nkd/local/%s", name), + } +} diff --git a/nkd/app/phase/deploy/infra/terraform/stage.go b/nkd/app/phase/deploy/infra/terraform/stage.go new file mode 100644 index 0000000..dabe48f --- /dev/null +++ b/nkd/app/phase/deploy/infra/terraform/stage.go @@ -0,0 +1,26 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package terraform + +import "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform/providers" + +type Stage interface { + Name() string + + // the list of providers that are used for the stage + Providers() []providers.Provider +} diff --git a/nkd/app/phase/deploy/infra/terraform/stages/openstack/stages.go b/nkd/app/phase/deploy/infra/terraform/stages/openstack/stages.go new file mode 100644 index 0000000..1b1f18a --- /dev/null +++ b/nkd/app/phase/deploy/infra/terraform/stages/openstack/stages.go @@ -0,0 +1,19 @@ +package openstack + +import ( + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform" + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform/providers" + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform/stages" +) + +var PlatformStages = []terraform.Stage{} + +func AddPlatformStage(name string) { + newStage := stages.NewStage( + "openstack", + name, + []providers.Provider{providers.OpenStack}, + ) + + PlatformStages = append(PlatformStages, newStage) +} diff --git a/nkd/app/phase/deploy/infra/terraform/stages/platform/stages.go b/nkd/app/phase/deploy/infra/terraform/stages/platform/stages.go new file mode 100644 index 0000000..7a99cad --- /dev/null +++ b/nkd/app/phase/deploy/infra/terraform/stages/platform/stages.go @@ -0,0 +1,19 @@ +package platform + +import ( + "errors" + "fmt" + + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform" + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform/stages/openstack" +) + +func StagesForPlatform(platform string, stage string) ([]terraform.Stage, error) { + switch platform { + case "openstack": + openstack.AddPlatformStage(stage) + return openstack.PlatformStages, nil + default: + return nil, errors.New(fmt.Sprintf("unsupported platform %q", platform)) + } +} diff --git a/nkd/app/phase/deploy/infra/terraform/stages/split.go b/nkd/app/phase/deploy/infra/terraform/stages/split.go new file mode 100644 index 0000000..caf0de7 --- /dev/null +++ b/nkd/app/phase/deploy/infra/terraform/stages/split.go @@ -0,0 +1,43 @@ +package stages + +import ( + "fmt" + + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform/providers" +) + +type StageOption func(*SplitStage) + +func NewStage(platform, name string, providers []providers.Provider, opts ...StageOption) SplitStage { + s := SplitStage{ + platform: platform, + name: name, + providers: providers, + } + for _, opt := range opts { + opt(&s) + } + return s +} + +type SplitStage struct { + platform string + name string + providers []providers.Provider +} + +func (s SplitStage) Name() string { + return s.name +} + +func (s SplitStage) Providers() []providers.Provider { + return s.providers +} + +func (s SplitStage) StateFilename() string { + return fmt.Sprintf("terraform.%s.tfstate", s.name) +} + +func (s SplitStage) OutputsFilename() string { + return fmt.Sprintf("%s.tfvars.json", s.name) +} diff --git a/nkd/app/phase/deploy/infra/terraform/state.go b/nkd/app/phase/deploy/infra/terraform/state.go new file mode 100644 index 0000000..9509abc --- /dev/null +++ b/nkd/app/phase/deploy/infra/terraform/state.go @@ -0,0 +1,51 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package terraform + +import ( + "context" + "encoding/json" + + "github.com/pkg/errors" +) + +const StateFilename = "terraform.tfstate" + +// Reads the terraform state file. +func Outputs(workingDir string, terraformBinary string) ([]byte, error) { + tf, err := newTFExec(workingDir, terraformBinary) + if err != nil { + return nil, err + } + + tfoutput, err := tf.Output(context.Background()) + if err != nil { + return nil, errors.Wrap(err, "failed to read terraform state file") + } + + outputs := make(map[string]interface{}, len(tfoutput)) + for key, value := range tfoutput { + outputs[key] = value.Value + } + + data, err := json.Marshal(outputs) + if err != nil { + return nil, errors.Wrap(err, "could not marshal outputs") + } + + return data, nil +} diff --git a/nkd/app/phase/deploy/infra/terraform/terraform.go b/nkd/app/phase/deploy/infra/terraform/terraform.go new file mode 100644 index 0000000..6bb6a9c --- /dev/null +++ b/nkd/app/phase/deploy/infra/terraform/terraform.go @@ -0,0 +1,98 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package terraform + +import ( + "context" + "os" + "path/filepath" + "runtime" + + "github.com/hashicorp/terraform-exec/tfexec" + "github.com/openshift/installer/pkg/lineprinter" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +func newTFExec(dir string, terraformDir string) (*tfexec.Terraform, error) { + tfPath := filepath.Join(terraformDir, "bin", runtime.GOOS+"_"+runtime.GOARCH, "terraform") + tf, err := tfexec.NewTerraform(dir, tfPath) + if err != nil { + return nil, err + } + + // If the log path is not set, terraform will not receive debug logs. + if logPath, ok := os.LookupEnv("TERRAFORM_LOG_PATH"); ok { + if err := tf.SetLog(os.Getenv("TERRAFORM_LOG")); err != nil { + logrus.Infof("Skipping setting terraform log levels: %v", err) + } else { + tf.SetLogCore(os.Getenv("TERRAFORM_LOG_CORE")) //nolint:errcheck + tf.SetLogProvider(os.Getenv("TERRAFORM_LOG_PROVIDER")) //nolint:errcheck + tf.SetLogPath(logPath) //nolint:errcheck + } + } + + // Add terraform info logs to the installer log + lpDebug := &lineprinter.LinePrinter{Print: (&lineprinter.Trimmer{WrappedPrint: logrus.Debug}).Print} + lpError := &lineprinter.LinePrinter{Print: (&lineprinter.Trimmer{WrappedPrint: logrus.Error}).Print} + defer lpDebug.Close() + defer lpError.Close() + + tf.SetStdout(lpDebug) + tf.SetStderr(lpError) + tf.SetLogger(newPrintfer()) + + return tf, nil +} + +// terraform apply +func TFApply(dir string, terraformDir string, applyOpts ...tfexec.ApplyOption) error { + if err := TFInit(dir, terraformDir); err != nil { + return err + } + + tf, err := newTFExec(dir, terraformDir) + if err != nil { + return errors.Wrap(err, "failed to create a new tfexec") + } + + err = tf.Apply(context.Background(), applyOpts...) + if err != nil { + return errors.Wrap(err, "failed to apply Terraform") + } + + return nil +} + +// terraform destroy +func TFDestroy(dir string, terraformDir string, destroyOpts ...tfexec.DestroyOption) error { + if err := TFInit(dir, terraformDir); err != nil { + return err + } + + tf, err := newTFExec(dir, terraformDir) + if err != nil { + return errors.Wrap(err, "failed to destroy a new tfexec") + } + + err = tf.Destroy(context.Background(), destroyOpts...) + if err != nil { + return errors.Wrap(err, "failed to destroy terraform") + } + + return nil +} diff --git a/nkd/app/phase/deploy/infra/tfvars/openstack/tfvars.go b/nkd/app/phase/deploy/infra/tfvars/openstack/tfvars.go new file mode 100644 index 0000000..693bee2 --- /dev/null +++ b/nkd/app/phase/deploy/infra/tfvars/openstack/tfvars.go @@ -0,0 +1,44 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package openstack + +// 定义 JSON 数据的结构 +type TerraformData struct { + Openstack struct { + User_name string `json:"user_name"` + Password string `json:"password"` + Tenant_name string `json:"tenant_name"` + Auth_url string `json:"auth_url"` + Region string `json:"region"` + } `json:"openstack"` + Flavor struct { + Name string `json:"name"` + Ram string `json:"ram"` + Vcpus string `json:"vcpus"` + Disk string `json:"disk"` + Is_public string `json:"is_public"` + } `json:"flavor"` + Instance struct { + Count string `json:"count"` + Name string `json:"name"` + Image_name string `json:"image_name"` + Key_pair string `json:"key_pair"` + } `json:"instance"` + Floatip struct { + Pool string `json:"pool"` + } `json:"floatip"` +} diff --git a/nkd/app/phase/init/.DS_Store b/nkd/app/phase/init/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b54f3e5947f13a2a169c68e548b4bbf1d8a784d2 GIT binary patch literal 6148 zcmeHK%}T>S5Z-NTn^J@v6nb3nTClcKEM7vaFJMFuDz!1S24l7~sXdfJ&iX<=iO=KA z?&c5-coVTRu=~x<&u->}>x63aJDBnQrw>>AAB9h5>%uihe#WIO|Vo|DHC5(C5l zF+dD#9|Ptruv*(!I#o;z5CcCjfct}hhUgf~G^(uwI=nukzlMkcI=&?kg+a$)rV%_K zT&Du+RBoOaT&IIwm^jB^rctLeu2zP5%*y%Wg{#%UE>t+w@SO09*4+6951J literal 0 HcmV?d00001 diff --git a/nkd/app/phase/init/config/cert/cacert.go b/nkd/app/phase/init/config/cert/cacert.go new file mode 100644 index 0000000..0e1227e --- /dev/null +++ b/nkd/app/phase/init/config/cert/cacert.go @@ -0,0 +1,37 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cert + +import ( + "crypto/x509" + "crypto/x509/pkix" +) + +type RootCA struct { + SelfSignedCertKey +} + +func (c *RootCA) Generate() error { + cfg := &CertConfig{ + Subject: pkix.Name{CommonName: "rootca", OrganizationalUnit: []string{"NestOS"}}, + KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, + Validity: 3650, + IsCA: true, + } + + return c.SelfSignedCertKey.Generate(cfg, "rootca") +} diff --git a/nkd/app/phase/init/config/cert/certapi.go b/nkd/app/phase/init/config/cert/certapi.go new file mode 100644 index 0000000..4c7c642 --- /dev/null +++ b/nkd/app/phase/init/config/cert/certapi.go @@ -0,0 +1,58 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cert + +import ( + "crypto/x509" + "crypto/x509/pkix" + "net" + "time" +) + +type CertInterface interface { + // Cert returns the certificate. + Cert() []byte +} + +// CertKeyInterface contains a private key and the associated cert. +type CertKeyInterface interface { + CertInterface + // Key returns the private key. + Key() []byte +} + +type CertificateGenerator interface { + GenerateCACertificate() error + GenerateSignedCertificate(commonName string) error +} + +// CertKey 包含证书和私钥 +type CertKey struct { + CertRaw []byte + KeyRaw []byte + SavePath string +} + +type CertConfig struct { + DNSNames []string + ExtKeyUsages []x509.ExtKeyUsage + IPAddresses []net.IP + KeyUsages x509.KeyUsage + Subject pkix.Name + Validity time.Duration + IsCA bool +} diff --git a/nkd/app/phase/init/config/cert/etcd.go b/nkd/app/phase/init/config/cert/etcd.go new file mode 100755 index 0000000..57a64f5 --- /dev/null +++ b/nkd/app/phase/init/config/cert/etcd.go @@ -0,0 +1,31 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cert + +import ( + "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra" +) + +type EtcdCaGenerator struct { +} + +func (e EtcdCaGenerator) GenerateAssets() infra.Assets { + return nil +} + +func init() { +} diff --git a/nkd/app/phase/init/config/cert/selfsignedcert.go b/nkd/app/phase/init/config/cert/selfsignedcert.go new file mode 100644 index 0000000..91f9d4c --- /dev/null +++ b/nkd/app/phase/init/config/cert/selfsignedcert.go @@ -0,0 +1,101 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cert + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "math/big" + "time" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +// SelfSignedCertificate 只负责创建自签名的证书,这里只传入cfg和privatekey +func SelfSignedCertificate(cfg *CertConfig, key *rsa.PrivateKey) (*x509.Certificate, error) { + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + logrus.Errorf("Failed to generate serialNumber: %v", err) + return nil, err + } + certTemplate := x509.Certificate{ + BasicConstraintsValid: true, + IsCA: cfg.IsCA, + KeyUsage: cfg.KeyUsages, + NotAfter: time.Now().Add(cfg.Validity), + NotBefore: time.Now(), + SerialNumber: serialNumber, + Subject: cfg.Subject, + } + // 判断subject字段中CommonName和OrganizationalUnit是否为空 + if len(cfg.Subject.CommonName) == 0 || len(cfg.Subject.OrganizationalUnit) == 0 { + return nil, errors.Errorf("certification's subject is not set, or invalid") + } + + //certBytes是生成证书的中间步骤,它用于将证书的二进制表示存储在内存中,以便后续操作可以使用它 + certBytes, err := x509.CreateCertificate(rand.Reader, &certTemplate, &certTemplate, key.Public(), key) + if err != nil { + return nil, errors.Wrap(err, "failed to create certificate") + } + + return x509.ParseCertificate(certBytes) +} + +/*GenerateSelfSignedCertificate负责根据cfg生成私钥和证书 + 在这一步会调用PrivateKey生成私钥并调用SelfSignedCertificate生成证书,并将结果返回*/ +func GenerateSelfSignedCertificate(cfg *CertConfig) (*rsa.PrivateKey, *x509.Certificate, error) { + key, err := PrivateKey() + if err != nil { + logrus.Debugf("Failed to generate private key: %s", err) + return nil, nil, errors.Wrap(err, "Failed to generate private key") + } + + //这里的crt是parse之后的,表示已经生成的CA证书,用于存储CA证书的详细信息,例如证书序列号、主题、有效期等 + crt, err := SelfSignedCertificate(cfg, key) + if err != nil { + logrus.Debugf("Failed to create self-signed certificate: %s", err) + return nil, nil, errors.Wrap(err, "failed to create self-signed certificate") + } + return key, crt, nil +} + +type SelfSignedCertKey struct { + CertKey +} + +//自签名证书生成器,封装后该方法用于所有自签名的证书,并将证书和私钥转换格式后保存 +func (c *SelfSignedCertKey) Generate(cfg *CertConfig, filename string) error { + + key, crt, err := GenerateSelfSignedCertificate(cfg) + if err != nil { + return errors.Wrap(err, "Failed to generate self-signed cert/key pair") + } + + c.KeyRaw = PrivateKeyToPem(key) + c.CertRaw = CertToPem(crt) + + err = c.SaveCertificateToFile(filename) + if err != nil { + logrus.Errorf("Faile to save %s: %v", filename, err) + } + + return nil + +} diff --git a/nkd/app/phase/init/config/cert/signedcerts.go b/nkd/app/phase/init/config/cert/signedcerts.go new file mode 100644 index 0000000..66d8a44 --- /dev/null +++ b/nkd/app/phase/init/config/cert/signedcerts.go @@ -0,0 +1,130 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cert + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "math/big" + "time" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +func SignedCertificate( + cfg *CertConfig, + csr *x509.CertificateRequest, + key *rsa.PrivateKey, + caCert *x509.Certificate, + caKey *rsa.PrivateKey, +) (*x509.Certificate, error) { + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + logrus.Errorf("Failed to generate serialNumber: %v", err) + return nil, err + } + certTemplate := x509.Certificate{ + BasicConstraintsValid: true, + IsCA: cfg.IsCA, + DNSNames: csr.DNSNames, + ExtKeyUsage: cfg.ExtKeyUsages, + IPAddresses: csr.IPAddresses, + KeyUsage: cfg.KeyUsages, + NotAfter: time.Now().Add(cfg.Validity), + NotBefore: caCert.NotBefore, + SerialNumber: serialNumber, + Subject: csr.Subject, + } + certBytes, err := x509.CreateCertificate(rand.Reader, &certTemplate, caCert, key.Public(), caKey) + if err != nil { + return nil, errors.Wrap(err, "failed to create x509 certificate") + } + return x509.ParseCertificate(certBytes) +} + +func GenerateSignedCertificate(caKey *rsa.PrivateKey, caCert *x509.Certificate, + cfg *CertConfig) (*rsa.PrivateKey, *x509.Certificate, error) { + key, err := PrivateKey() + if err != nil { + return nil, nil, errors.Wrap(err, "failed to generate private key") + } + // create a CSR + csrTmpl := x509.CertificateRequest{Subject: cfg.Subject, DNSNames: cfg.DNSNames, IPAddresses: cfg.IPAddresses} + csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &csrTmpl, key) + if err != nil { + return nil, nil, errors.Wrap(err, "failed to create certificate request") + } + csr, err := x509.ParseCertificateRequest(csrBytes) + if err != nil { + logrus.Debugf("Failed to parse x509 certificate request: %s", err) + return nil, nil, errors.Wrap(err, "error parsing x509 certificate request") + } + + // create a cert + cert, err := SignedCertificate(cfg, csr, key, caCert, caKey) + if err != nil { + logrus.Debugf("Failed to create a signed certificate: %s", err) + return nil, nil, errors.Wrap(err, "failed to create a signed certificate") + } + return key, cert, nil + +} + +type SignedCertKey struct { + CertKey +} + +func (c *SignedCertKey) Generate( + cfg *CertConfig, + parentCA CertKeyInterface, + filename string, +) error { + var key *rsa.PrivateKey + var crt *x509.Certificate + var err error + + caKey, err := PemToPrivateKey(parentCA.Key()) + if err != nil { + logrus.Debugf("Failed to parse RSA private key: %s", err) + return errors.Wrap(err, "failed to parse rsa private key") + } + + caCert, err := PemToCertificate(parentCA.Cert()) + if err != nil { + logrus.Debugf("Failed to parse x509 certificate: %s", err) + return errors.Wrap(err, "failed to parse x509 certificate") + } + + key, crt, err = GenerateSignedCertificate(caKey, caCert, cfg) + if err != nil { + logrus.Debugf("Failed to generate signed cert/key pair: %s", err) + return errors.Wrap(err, "failed to generate signed cert/key pair") + } + + c.KeyRaw = PrivateKeyToPem(key) + c.CertRaw = CertToPem(crt) + + err = c.SaveCertificateToFile(filename) + if err != nil { + logrus.Errorf("Faile to save %s: %v", filename, err) + } + + return nil +} diff --git a/nkd/app/phase/init/config/cert/tools.go b/nkd/app/phase/init/config/cert/tools.go new file mode 100644 index 0000000..4d10d39 --- /dev/null +++ b/nkd/app/phase/init/config/cert/tools.go @@ -0,0 +1,103 @@ +/* +Copyright 2023 KylinSoft Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cert + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "io/ioutil" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +//PrivateKey负责生成密钥 +func PrivateKey() (*rsa.PrivateKey, error) { + rsaKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return nil, errors.Wrap(err, "Failed to generate RSA private key") + } + + return rsaKey, nil +} + +// PrivateKeyToPem 返回私钥的PEM格式字节切片 +func PrivateKeyToPem(key *rsa.PrivateKey) []byte { + keyInBytes := x509.MarshalPKCS1PrivateKey(key) + keyinPem := pem.EncodeToMemory( + &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: keyInBytes, + }, + ) + return keyinPem +} + +func PemToPrivateKey(data []byte) (*rsa.PrivateKey, error) { + block, _ := pem.Decode(data) + if block == nil { + return nil, errors.Errorf("could not find a PEM block in the private key") + } + return x509.ParsePKCS1PrivateKey(block.Bytes) +} + +// CACertPEM 返回证书的PEM格式字节切片 +func CertToPem(cert *x509.Certificate) []byte { + certInPem := pem.EncodeToMemory( + &pem.Block{ + Type: "CERTIFICATE", + Bytes: cert.Raw, + }, + ) + return certInPem +} + +func PemToCertificate(data []byte) (*x509.Certificate, error) { + block, _ := pem.Decode(data) + if block == nil { + return nil, errors.Errorf("could not find a PEM block in the certificate") + } + return x509.ParseCertificate(block.Bytes) +} + +// SaveCertificateToFile 将证书保存到文件 +func (c *CertKey) SaveCertificateToFile(filename string) error { + err := ioutil.WriteFile(c.SavePath+"/"+filename, c.CertRaw, 0644) + if err != nil { + logrus.Errorf("Faile to save %s: %v", filename, err) + return err + } + + logrus.Infof("Successfully saved %s", filename) + + return nil +} + +// SavePrivateKeyToFile 将私钥保存到文件 +func (c *CertKey) SavePrivateKeyToFile(filename string) error { + err := ioutil.WriteFile(c.SavePath+"/"+filename, c.KeyRaw, 0600) + if err != nil { + logrus.Errorf("Faile to save %s: %v", filename, err) + return err + } + + logrus.Infof("Successfully saved %s", filename) + + return nil +} diff --git a/nkd/app/phase/init/config/certs.go b/nkd/app/phase/init/config/certs.go new file mode 100644 index 0000000..23352b6 --- /dev/null +++ b/nkd/app/phase/init/config/certs.go @@ -0,0 +1,15 @@ +package config + +import "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" + +func NewGenerateCertsCmd() workflow.Phase { + return workflow.Phase{ + Name: "cert", + Short: "Run certs to generate certs", + Run: runGenerateCertsConfig, + } +} + +func runGenerateCertsConfig() error { + return nil +} diff --git a/nkd/app/phase/init/config/infra.go b/nkd/app/phase/init/config/infra.go new file mode 100644 index 0000000..a84bdd2 --- /dev/null +++ b/nkd/app/phase/init/config/infra.go @@ -0,0 +1,17 @@ +package config + +import ( + "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" +) + +func NewGenerateInfraCmd() workflow.Phase { + return workflow.Phase{ + Name: "infra", + Short: "run k8s to genertate infra config", + Run: runGenerateInfraConfig, + } +} + +func runGenerateInfraConfig() error { + return nil +} diff --git a/nkd/app/phase/init/config/k8s.go b/nkd/app/phase/init/config/k8s.go new file mode 100644 index 0000000..a25c4f2 --- /dev/null +++ b/nkd/app/phase/init/config/k8s.go @@ -0,0 +1,15 @@ +package config + +import "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" + +func NewGenerateK8sCmd() workflow.Phase { + return workflow.Phase{ + Name: "k8s", + Short: "run k8s to genertate k8s config", + Run: runGenerateK8sConfig, + } +} + +func runGenerateK8sConfig() error { + return nil +} diff --git a/nkd/app/phase/workflow/Phase.go b/nkd/app/phase/workflow/Phase.go new file mode 100644 index 0000000..87277b9 --- /dev/null +++ b/nkd/app/phase/workflow/Phase.go @@ -0,0 +1,8 @@ +package workflow + +type Phase struct { + Name string + Short string + Phases []Phase + Run func() error +} diff --git a/nkd/app/phase/workflow/runner.go b/nkd/app/phase/workflow/runner.go new file mode 100644 index 0000000..9743357 --- /dev/null +++ b/nkd/app/phase/workflow/runner.go @@ -0,0 +1,91 @@ +package workflow + +import ( + "strings" +) + +type Runner struct { + Phases []Phase + phaseRunners []*phaseRunner +} +type phaseRunner struct { + Phase + parent *phaseRunner + level int + selfPath []string + generatedName string + use string +} + +type RunData interface{} + +func NewRunner() *Runner { + return &Runner{ + Phases: []Phase{}, + } +} + +func (r *Runner) Run() error { + r.prepareForExcution() + print(r.Phases) + + err := r.VisitAll(func(p *phaseRunner) error { + if p.Run != nil { + if err := p.Run(); err != nil { + return err + } + } + return nil + }) + return err +} + +func (r *Runner) VisitAll(fn func(*phaseRunner) error) error { + for _, currentRunner := range r.phaseRunners { + if err := fn(currentRunner); err != nil { + return err + } + } + return nil +} + +func (r *Runner) InitData(args []string) (RunData, error) { + return nil, nil +} + +func (r *Runner) AppendPhase(t Phase) { + r.Phases = append(r.Phases, t) +} + +func (r *Runner) prepareForExcution() { + r.phaseRunners = []*phaseRunner{} + var parentRunner *phaseRunner + for _, phase := range r.Phases { + addPhaseRunner(r, parentRunner, phase) + } +} + +func addPhaseRunner(e *Runner, parentRunner *phaseRunner, phase Phase) { + use := cleanName(phase.Name) + generatedName := use + selfPath := []string{generatedName} + currentRunner := &phaseRunner{ + Phase: phase, + parent: parentRunner, + level: len(selfPath) - 1, + selfPath: selfPath, + generatedName: generatedName, + use: use, + } + e.phaseRunners = append(e.phaseRunners, currentRunner) + + for _, childPhase := range phase.Phases { + addPhaseRunner(e, currentRunner, childPhase) + } + +} + +func cleanName(name string) string { + ret := strings.ToLower(name) + return ret +} diff --git a/nkd/nkd.go b/nkd/nkd.go new file mode 100644 index 0000000..385ae5b --- /dev/null +++ b/nkd/nkd.go @@ -0,0 +1,7 @@ +package main + +import "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app" + +func main() { + app.Run() +} diff --git a/nkd/resource/assert/terrafrom/terraform b/nkd/resource/assert/terrafrom/terraform new file mode 100644 index 0000000..e69de29 diff --git a/nkd/resource/templates/config.json b/nkd/resource/templates/config.json new file mode 100644 index 0000000..ee15e56 --- /dev/null +++ b/nkd/resource/templates/config.json @@ -0,0 +1,83 @@ +[{ + "k8s": { + "advertiseAddress": "", + "kubernetesVersion": "", + "serviceSubnet": "" + }, + "kubeadm": { + "path": "" + }, + "cert":{ + "timeout": "" + }, + "repo": { + "secret": { + }, + "registry": [] + }, + + "infra": { + "platform": "openstack", + "path": "" + }, + "addon": [ + {"name": "calico", "path": ""}, + {} + ] +}, + +{ + "cluster": { + "name": "" + }, + "system":{ + "hostname": [], + "user_name": "", + "password": "", + "certs": { + "timeout": "" + } + }, + "repo": { + "secret": {}, + "registry": {} + }, + "k8s":{ + "kubeadm": {} + }, + "infra":{ + "platform": "", + "vm_size": { + "master": { + "vcpus": "4", + "ram": "8192", + "disk": "64" + }, + "node": { + "vcpus": "4", + "ram": "8192", + "disk": "64" + } + }, + "openstack": { + "user_name": "admin", + "password": "qwer1234", + "tenant_name": "admin", + "auth_url": "", + "region": "RegionOne", + "master_instance_name": [], + "worker_instance_name": [], + "network_name": "", + "master_ip": [], + "worker_ip": [], + "float_ip_pool": "" + }, + "libvirt": {}, + "aliyun": {} + }, + "addon": [ + {"name": "", "path": ""}, + {} + ] +} +] \ No newline at end of file diff --git a/nkd/resource/templates/k8s/k8s-master.bu b/nkd/resource/templates/k8s/k8s-master.bu new file mode 100644 index 0000000..e69de29 diff --git a/nkd/resource/templates/openstack.json b/nkd/resource/templates/openstack.json new file mode 100644 index 0000000..beae023 --- /dev/null +++ b/nkd/resource/templates/openstack.json @@ -0,0 +1,56 @@ +{ + "keystone": { + "user_name": "", + "password": "", + "tenant_name": "", + "auth_url": "", + "region": "" + }, + "master": { + "count": "", + "image": { + "local_file_path": "", + "remote_url": "" + }, + "network": { + "name": "" + }, + "flavor": { + "name": "" + }, + "secgroup": { + "name": "" + }, + "user_data": { + "file": "" + }, + "keypair": { + "name": "" + } + + + }, + "node": { + "count": "", + "image": { + "local_file_path": "", + "remote_url": "" + }, + "network": { + "name": "" + }, + "flavor": { + "name": "" + }, + "secgroup": { + "name": "" + }, + "user_data": { + "file": "" + }, + "keypair": { + "name": "" + } + } + +} \ No newline at end of file diff --git a/nkd/resource/templates/terraform/master/main.tf b/nkd/resource/templates/terraform/master/main.tf new file mode 100644 index 0000000..e69de29 diff --git a/nkd/resource/templates/terraform/node/main.tf b/nkd/resource/templates/terraform/node/main.tf new file mode 100644 index 0000000..e69de29 -- Gitee From 1aefabe7987b07529773dee7dbef5d8cb83018d5 Mon Sep 17 00:00:00 2001 From: easter1007 Date: Fri, 11 Aug 2023 14:05:47 +0800 Subject: [PATCH 2/2] clean nkd --- .gitignore | 1 + nkd/app/cmd/check.go | 20 - nkd/app/cmd/cmd.go | 25 - nkd/app/cmd/config.go | 22 - nkd/app/cmd/deploy.go | 23 - nkd/app/cmd/destroy.go | 21 - nkd/app/cmd/extend.go | 22 - nkd/app/cmd/init.go | 28 -- nkd/app/cmd/upgrade.go | 1 - nkd/app/nkd.go | 13 - nkd/app/phase/config/print.go | 431 ------------------ nkd/app/phase/deploy/deploy.go | 15 - nkd/app/phase/deploy/infra/assets/assets.go | 22 - .../deploy/infra/assets/cluster/cluster.go | 150 ------ .../deploy/infra/assets/cluster/tfvars.go | 83 ---- nkd/app/phase/deploy/infra/terraform/init.go | 41 -- .../phase/deploy/infra/terraform/logger.go | 37 -- .../infra/terraform/providers/providers.go | 35 -- nkd/app/phase/deploy/infra/terraform/stage.go | 26 -- .../terraform/stages/openstack/stages.go | 19 - .../infra/terraform/stages/platform/stages.go | 19 - .../deploy/infra/terraform/stages/split.go | 43 -- nkd/app/phase/deploy/infra/terraform/state.go | 51 --- .../phase/deploy/infra/terraform/terraform.go | 98 ---- .../deploy/infra/tfvars/openstack/tfvars.go | 44 -- nkd/app/phase/init/.DS_Store | Bin 6148 -> 0 bytes nkd/app/phase/init/config/cert/cacert.go | 37 -- nkd/app/phase/init/config/cert/certapi.go | 58 --- nkd/app/phase/init/config/cert/etcd.go | 31 -- .../phase/init/config/cert/selfsignedcert.go | 101 ---- nkd/app/phase/init/config/cert/signedcerts.go | 130 ------ nkd/app/phase/init/config/cert/tools.go | 103 ----- nkd/app/phase/init/config/certs.go | 15 - nkd/app/phase/init/config/infra.go | 17 - nkd/app/phase/init/config/k8s.go | 15 - nkd/app/phase/workflow/Phase.go | 8 - nkd/app/phase/workflow/runner.go | 91 ---- nkd/nkd.go | 7 - nkd/resource/assert/terrafrom/terraform | 0 nkd/resource/templates/config.json | 83 ---- nkd/resource/templates/k8s/k8s-master.bu | 0 nkd/resource/templates/openstack.json | 56 --- .../templates/terraform/master/main.tf | 0 nkd/resource/templates/terraform/node/main.tf | 0 44 files changed, 1 insertion(+), 2041 deletions(-) delete mode 100644 nkd/app/cmd/check.go delete mode 100644 nkd/app/cmd/cmd.go delete mode 100644 nkd/app/cmd/config.go delete mode 100644 nkd/app/cmd/deploy.go delete mode 100644 nkd/app/cmd/destroy.go delete mode 100644 nkd/app/cmd/extend.go delete mode 100644 nkd/app/cmd/init.go delete mode 100644 nkd/app/cmd/upgrade.go delete mode 100644 nkd/app/nkd.go delete mode 100644 nkd/app/phase/config/print.go delete mode 100644 nkd/app/phase/deploy/deploy.go delete mode 100755 nkd/app/phase/deploy/infra/assets/assets.go delete mode 100644 nkd/app/phase/deploy/infra/assets/cluster/cluster.go delete mode 100644 nkd/app/phase/deploy/infra/assets/cluster/tfvars.go delete mode 100644 nkd/app/phase/deploy/infra/terraform/init.go delete mode 100644 nkd/app/phase/deploy/infra/terraform/logger.go delete mode 100644 nkd/app/phase/deploy/infra/terraform/providers/providers.go delete mode 100644 nkd/app/phase/deploy/infra/terraform/stage.go delete mode 100644 nkd/app/phase/deploy/infra/terraform/stages/openstack/stages.go delete mode 100644 nkd/app/phase/deploy/infra/terraform/stages/platform/stages.go delete mode 100644 nkd/app/phase/deploy/infra/terraform/stages/split.go delete mode 100644 nkd/app/phase/deploy/infra/terraform/state.go delete mode 100644 nkd/app/phase/deploy/infra/terraform/terraform.go delete mode 100644 nkd/app/phase/deploy/infra/tfvars/openstack/tfvars.go delete mode 100644 nkd/app/phase/init/.DS_Store delete mode 100644 nkd/app/phase/init/config/cert/cacert.go delete mode 100644 nkd/app/phase/init/config/cert/certapi.go delete mode 100755 nkd/app/phase/init/config/cert/etcd.go delete mode 100644 nkd/app/phase/init/config/cert/selfsignedcert.go delete mode 100644 nkd/app/phase/init/config/cert/signedcerts.go delete mode 100644 nkd/app/phase/init/config/cert/tools.go delete mode 100644 nkd/app/phase/init/config/certs.go delete mode 100644 nkd/app/phase/init/config/infra.go delete mode 100644 nkd/app/phase/init/config/k8s.go delete mode 100644 nkd/app/phase/workflow/Phase.go delete mode 100644 nkd/app/phase/workflow/runner.go delete mode 100644 nkd/nkd.go delete mode 100644 nkd/resource/assert/terrafrom/terraform delete mode 100644 nkd/resource/templates/config.json delete mode 100644 nkd/resource/templates/k8s/k8s-master.bu delete mode 100644 nkd/resource/templates/openstack.json delete mode 100644 nkd/resource/templates/terraform/master/main.tf delete mode 100644 nkd/resource/templates/terraform/node/main.tf diff --git a/.gitignore b/.gitignore index 6e8bef9..859833e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ ./nkd/nkd test.yaml +.gitignore diff --git a/nkd/app/cmd/check.go b/nkd/app/cmd/check.go deleted file mode 100644 index f302929..0000000 --- a/nkd/app/cmd/check.go +++ /dev/null @@ -1,20 +0,0 @@ -package cmd - -import ( - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" - - "github.com/spf13/cobra" -) - -func NewCheckCommand() *cobra.Command { - checkRunner := workflow.NewRunner() - cmd := &cobra.Command{ - Use: "check", - Short: "Use this command to check assert", - RunE: func(cmd *cobra.Command, args []string) error { - return checkRunner.Run() - }, - } - - return cmd -} diff --git a/nkd/app/cmd/cmd.go b/nkd/app/cmd/cmd.go deleted file mode 100644 index 3880a35..0000000 --- a/nkd/app/cmd/cmd.go +++ /dev/null @@ -1,25 +0,0 @@ -package cmd - -import ( - "io" - - "github.com/spf13/cobra" -) - -func NewNkdCommand(in io.Reader, out, err io.Writer) *cobra.Command { - cmds := &cobra.Command{ - Use: "nkd", - Short: "nkd: easily bootstrap a secure Kubernetes cluster", - } - - cmds.ResetFlags() - // TODO: 修改名称 - cmds.AddCommand(NewConfigCommand()) - cmds.AddCommand(NewCheckCommand()) - cmds.AddCommand(NewInitCommand()) - cmds.AddCommand(NewDeployCommand()) - //添加 NewDeployCommand - cmds.AddCommand(NewExtendCommand()) - //添加 NewDestroyCommand - return cmds -} diff --git a/nkd/app/cmd/config.go b/nkd/app/cmd/config.go deleted file mode 100644 index 98efb51..0000000 --- a/nkd/app/cmd/config.go +++ /dev/null @@ -1,22 +0,0 @@ -package cmd - -import ( - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/config" - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" - - "github.com/spf13/cobra" -) - -func NewConfigCommand() *cobra.Command { - initRunner := workflow.NewRunner() - cmd := &cobra.Command{ - Use: "config", - Short: "Manage a k8s cluster", - RunE: func(cmd *cobra.Command, args []string) error { - return initRunner.Run() - }, - } - cmd.AddCommand(config.NewConfigNkdCommand()) - - return cmd -} diff --git a/nkd/app/cmd/deploy.go b/nkd/app/cmd/deploy.go deleted file mode 100644 index 43ea64f..0000000 --- a/nkd/app/cmd/deploy.go +++ /dev/null @@ -1,23 +0,0 @@ -package cmd - -import ( - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/deploy" - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" - - "github.com/spf13/cobra" -) - -func NewDeployCommand() *cobra.Command { - deployRunner := workflow.NewRunner() - cmd := &cobra.Command{ - Use: "deploy", - Short: "Use this command to deploy cluster", - RunE: func(cmd *cobra.Command, args []string) error { - - return deployRunner.Run() - }, - } - deployRunner.AppendPhase(deploy.NewDeployClusterCmd()) - - return cmd -} diff --git a/nkd/app/cmd/destroy.go b/nkd/app/cmd/destroy.go deleted file mode 100644 index e8e5c7c..0000000 --- a/nkd/app/cmd/destroy.go +++ /dev/null @@ -1,21 +0,0 @@ -package cmd - -import ( - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" - - "github.com/spf13/cobra" -) - -func NewDestroyCommand() *cobra.Command { - destroyRunner := workflow.NewRunner() - cmd := &cobra.Command{ - Use: "destroy", - Short: "Use this command to destroy a config or a cluster", - RunE: func(cmd *cobra.Command, args []string) error { - - return destroyRunner.Run() - }, - } - - return cmd -} diff --git a/nkd/app/cmd/extend.go b/nkd/app/cmd/extend.go deleted file mode 100644 index 287e66b..0000000 --- a/nkd/app/cmd/extend.go +++ /dev/null @@ -1,22 +0,0 @@ -package cmd - -import ( - "fmt" - - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" - - "github.com/spf13/cobra" -) - -func NewExtendCommand() *cobra.Command { - extendRunner := workflow.NewRunner() - cmd := &cobra.Command{ - Use: "extend", - Short: "Use join to join a node to a cluster", - RunE: func(cmd *cobra.Command, args []string) error { - fmt.Println("hello world") - return extendRunner.Run() - }, - } - return cmd -} diff --git a/nkd/app/cmd/init.go b/nkd/app/cmd/init.go deleted file mode 100644 index 89fb97e..0000000 --- a/nkd/app/cmd/init.go +++ /dev/null @@ -1,28 +0,0 @@ -package cmd - -import ( - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/init/config" - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" - - "github.com/spf13/cobra" -) - -type initData struct { -} - -func NewInitCommand() *cobra.Command { - initRunner := workflow.NewRunner() - cmd := &cobra.Command{ - Use: "init", - Short: "Use this command to init insert or config", - RunE: func(cmd *cobra.Command, args []string) error { - return initRunner.Run() - }, - } - // TODO: 暂时不需要证书,生成证书的方式,控制生成 - initRunner.AppendPhase(config.NewGenerateCertsCmd()) - initRunner.AppendPhase(config.NewGenerateK8sCmd()) - initRunner.AppendPhase(config.NewGenerateInfraCmd()) - - return cmd -} diff --git a/nkd/app/cmd/upgrade.go b/nkd/app/cmd/upgrade.go deleted file mode 100644 index 1d619dd..0000000 --- a/nkd/app/cmd/upgrade.go +++ /dev/null @@ -1 +0,0 @@ -package cmd diff --git a/nkd/app/nkd.go b/nkd/app/nkd.go deleted file mode 100644 index 52ec8fc..0000000 --- a/nkd/app/nkd.go +++ /dev/null @@ -1,13 +0,0 @@ -package app - -import ( - "os" - - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/cmd" -) - -func Run() error { - cmd := cmd.NewNkdCommand(os.Stdin, os.Stdout, os.Stderr) - // pflag.CommandLine.MarkHidden("version") - return cmd.Execute() -} diff --git a/nkd/app/phase/config/print.go b/nkd/app/phase/config/print.go deleted file mode 100644 index d6d45dd..0000000 --- a/nkd/app/phase/config/print.go +++ /dev/null @@ -1,431 +0,0 @@ -package config - -// { -// "cluster": { -// "name": "" -// }, -// "system":{ -// "hostname": [], -// "user_name": "", -// "password": "", -// "certs": { -// "timeout": "" -// } -// }, -// "repo": { -// "secret": {}, -// "registry": {} -// }, -// "k8s":{ -// "kubeadm": {} -// }, -// "infra":{ -// "platform": "", -// "vm_size": { -// "master": { -// "vcpus": "4", -// "ram": "8192", -// "disk": "64" -// }, -// "node": { -// "vcpus": "4", -// "ram": "8192", -// "disk": "64" -// } -// }, -// "openstack": { -// "user_name": "admin", -// "password": "qwer1234", -// "tenant_name": "admin", -// "auth_url": "", -// "region": "RegionOne", -// "master_instance_name": [], -// "worker_instance_name": [], -// "network_name": "", -// "master_ip": [], -// "worker_ip": [], -// "float_ip_pool": "" -// }, -// "libvirt": {}, -// "aliyun": {} -// }, -// "addon": [ -// {"name": "", "path": ""}, -// {} -// ] -// } - -import ( - "fmt" - "io/ioutil" - "time" - - "github.com/spf13/cobra" - "gopkg.in/yaml.v2" -) - -type System struct { - Hostname string `yaml:"hostname"` - Username string `yaml:"username"` - Password string `yaml:"password"` -} - -type Openstack struct { - User_name string - Password string - Tenant_name string - Auth_url string - Region string - Master_instance_name []string - Worker_instance_name []string - Internal_network string - External_network string - Master_ip []string - Worker_ip []string -} - -type Libvirt struct { -} - -type Size struct { - Vcpus int - Ram int - Disk int -} - -type Vmsize struct { - Master Size - Worker Size -} - -type Infra struct { - Platform string - openstack Openstack - vmsize Vmsize -} - -type Cluster struct { - Name string `yaml:"cluster-name"` -} - -type Repo struct { - Secret []map[string]string `yaml:"secret"` - Registry string `yaml:"registry"` -} - -type TypeMeta struct { - Kind string - ApiVersion string -} - -type BootstrapTokenString struct { - ID string `json:"-"` - Secret string `json:"-" datapolicy:"token"` -} - -type Duration struct { - time.Duration `protobuf:"varint,1,opt,name=duration,casttype=time.Duration"` -} - -type APIEndpoint struct { - AdvertiseAddress string - BindPort int32 -} - -type BootstrapToken struct { - Token *BootstrapTokenString - Groups []string - TTL *Duration - Usages []string -} -type TaintEffect string - -type PullPolicy string - -type Time struct { - time.Time `protobuf:"-"` -} -type Taint struct { - // Required. The taint key to be applied to a node. - Key string `json:"key" protobuf:"bytes,1,opt,name=key"` - // The taint value corresponding to the taint key. - // +optional - Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` - // Required. The effect of the taint on pods - // that do not tolerate the taint. - // Valid effects are NoSchedule, PreferNoSchedule and NoExecute. - Effect TaintEffect `json:"effect" protobuf:"bytes,3,opt,name=effect,casttype=TaintEffect"` - // TimeAdded represents the time at which the taint was added. - // It is only written for NoExecute taints. - // +optional - TimeAdded *Time `json:"timeAdded,omitempty" protobuf:"bytes,4,opt,name=timeAdded"` -} -type NodeRegistrationOptions struct { - Name string - CRISocket string - Taints []Taint - KubeletExtraArgs map[string]string - IgnorePreflightErrors []string - ImagePullPolicy PullPolicy `json:"imagePullPolicy,omitempty"` -} - -type ComponentConfigMap map[string]ComponentConfig - -type ComponentConfig interface { - // DeepCopy should create a new deep copy of the component config in place - DeepCopy() ComponentConfig - - // Marshal is marshalling the config into a YAML document returned as a byte slice - Marshal() ([]byte, error) - - // Unmarshal loads the config from a document map. No config in the document map is no error. - - // Default patches the component config with kubeadm preferred defaults - Default(cfg *ClusterConfiguration, localAPIEndpoint *APIEndpoint, nodeRegOpts *NodeRegistrationOptions) - - // IsUserSupplied indicates if the component config was supplied or modified by a user or was kubeadm generated - IsUserSupplied() bool - - // SetUserSupplied sets the state of the component config "user supplied" flag to, either true, or false. - SetUserSupplied(userSupplied bool) - - // Mutate allows applying pre-defined modifications to the config before it's marshaled. - Mutate() error - - // Set can be used to set the internal configuration in the ComponentConfig - Set(interface{}) - - // Get can be used to get the internal configuration in the ComponentConfig - Get() interface{} -} - -type Etcd struct { - - // Local provides configuration knobs for configuring the local etcd instance - // Local and External are mutually exclusive - Local *LocalEtcd - - // External describes how to connect to an external etcd cluster - // Local and External are mutually exclusive - External *ExternalEtcd -} - -type ImageMeta struct { - // ImageRepository sets the container registry to pull images from. - // if not set, the ImageRepository defined in ClusterConfiguration will be used instead. - ImageRepository string - - // ImageTag allows to specify a tag for the image. - // In case this value is set, kubeadm does not change automatically the version of the above components during upgrades. - ImageTag string - - //TODO: evaluate if we need also a ImageName based on user feedbacks -} - -// LocalEtcd describes that kubeadm should run an etcd cluster locally -type LocalEtcd struct { - // ImageMeta allows to customize the container used for etcd - ImageMeta `json:",inline"` - - // DataDir is the directory etcd will place its data. - // Defaults to "/var/lib/etcd". - DataDir string - - // ExtraArgs are extra arguments provided to the etcd binary - // when run inside a static pod. - // A key in this map is the flag name as it appears on the - // command line except without leading dash(es). - ExtraArgs map[string]string - - // ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert. - ServerCertSANs []string - // PeerCertSANs sets extra Subject Alternative Names for the etcd peer signing cert. - PeerCertSANs []string -} - -// ExternalEtcd describes an external etcd cluster -type ExternalEtcd struct { - - // Endpoints of etcd members. Useful for using external etcd. - // If not provided, kubeadm will run etcd in a static pod. - Endpoints []string - // CAFile is an SSL Certificate Authority file used to secure etcd communication. - CAFile string - // CertFile is an SSL certification file used to secure etcd communication. - CertFile string - // KeyFile is an SSL key file used to secure etcd communication. - KeyFile string -} - -type Networking struct { - // ServiceSubnet is the subnet used by k8s services. Defaults to "10.96.0.0/12". - ServiceSubnet string - // PodSubnet is the subnet used by pods. - PodSubnet string - // DNSDomain is the dns domain used by k8s services. Defaults to "cluster.local". - DNSDomain string -} -type HostPathType string -type HostPathMount struct { - // Name of the volume inside the pod template. - Name string - // HostPath is the path in the host that will be mounted inside - // the pod. - HostPath string - // MountPath is the path inside the pod where hostPath will be mounted. - MountPath string - // ReadOnly controls write access to the volume - ReadOnly bool - // PathType is the type of the HostPath. - PathType HostPathType -} -type ControlPlaneComponent struct { - // ExtraArgs is an extra set of flags to pass to the control plane component. - // A key in this map is the flag name as it appears on the - // command line except without leading dash(es). - // TODO: This is temporary and ideally we would like to switch all components to - // use ComponentConfig + ConfigMaps. - ExtraArgs map[string]string - - // ExtraVolumes is an extra set of host volumes, mounted to the control plane component. - ExtraVolumes []HostPathMount -} -type APIServer struct { - ControlPlaneComponent - - // CertSANs sets extra Subject Alternative Names for the API Server signing cert. - CertSANs []string - - // TimeoutForControlPlane controls the timeout that we use for API server to appear - TimeoutForControlPlane Duration -} -type DNS struct { - // ImageMeta allows to customize the image used for the DNS component - ImageMeta `json:",inline"` -} -type ClusterConfiguration struct { - TypeMeta - - // ComponentConfigs holds component configs known to kubeadm, should long-term only exist in the internal kubeadm API - // +k8s:conversion-gen=false - ComponentConfigs ComponentConfigMap - - // Etcd holds configuration for etcd. - Etcd Etcd - - // Networking holds configuration for the networking topology of the cluster. - Networking Networking - - // KubernetesVersion is the target version of the control plane. - KubernetesVersion string - - // CIKubernetesVersion is the target CI version of the control plane. - // Useful for running kubeadm with CI Kubernetes version. - // +k8s:conversion-gen=false - CIKubernetesVersion string - - // ControlPlaneEndpoint sets a stable IP address or DNS name for the control plane; it - // can be a valid IP address or a RFC-1123 DNS subdomain, both with optional TCP port. - // In case the ControlPlaneEndpoint is not specified, the AdvertiseAddress + BindPort - // are used; in case the ControlPlaneEndpoint is specified but without a TCP port, - // the BindPort is used. - // Possible usages are: - // e.g. In a cluster with more than one control plane instances, this field should be - // assigned the address of the external load balancer in front of the - // control plane instances. - // e.g. in environments with enforced node recycling, the ControlPlaneEndpoint - // could be used for assigning a stable DNS to the control plane. - ControlPlaneEndpoint string - - // APIServer contains extra settings for the API server control plane component - APIServer APIServer - - // ControllerManager contains extra settings for the controller manager control plane component - ControllerManager ControlPlaneComponent - - // Scheduler contains extra settings for the scheduler control plane component - Scheduler ControlPlaneComponent - - // DNS defines the options for the DNS add-on installed in the cluster. - DNS DNS - - // CertificatesDir specifies where to store or look for all required certificates. - CertificatesDir string - - // ImageRepository sets the container registry to pull images from. - // If empty, `registry.k8s.io` will be used by default; in case of kubernetes version is a CI build (kubernetes version starts with `ci/`) - // `gcr.io/k8s-staging-ci-images` will be used as a default for control plane components and for kube-proxy, while `registry.k8s.io` - // will be used for all the other images. - ImageRepository string - - // CIImageRepository is the container registry for core images generated by CI. - // Useful for running kubeadm with images from CI builds. - // +k8s:conversion-gen=false - CIImageRepository string - - // FeatureGates enabled by the user. - FeatureGates map[string]bool - - // The cluster name - ClusterName string -} - -type Patches struct { - // Directory is a path to a directory that contains files named "target[suffix][+patchtype].extension". - // For example, "kube-apiserver0+merge.yaml" or just "etcd.json". "target" can be one of - // "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". - // "patchtype" can be one of "strategic" "merge" or "json" and they match the patch formats supported by kubectl. - // The default "patchtype" is "strategic". "extension" must be either "json" or "yaml". - // "suffix" is an optional string that can be used to determine which patches are applied - // first alpha-numerically. - Directory string -} - -type Kubeadm struct { - ClusterConfiguration - TypeMeta - BootstrapTokens []BootstrapToken - LocalAPIEndpoint APIEndpoint - NodeRegistration NodeRegistrationOptions - CertificateKey string - Patches *Patches -} - -type Addon struct { - Addons []map[string]string -} -type Nkd struct { - Cluster Cluster - System System - Repo Repo - Kubeadm Kubeadm - Addon Addon - Infra Infra -} - -func NewConfigNkdCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "print", - Short: "use this command to print nkd config", - RunE: func(cmd *cobra.Command, args []string) error { - return printDefaultNkdConfig() - }, - } - return cmd -} - -func printDefaultNkdConfig() error { - system := System{Hostname: "master1", Username: "root", Password: "string"} - cluster := Cluster{Name: "cluster1"} - nkd := Nkd{System: system, Cluster: cluster} - conf, err := yaml.Marshal(&nkd) - fmt.Println(string(conf)) - if err != nil { - return err - } - err = ioutil.WriteFile("test.yaml", conf, 644) - if err != nil { - return err - } - return err -} diff --git a/nkd/app/phase/deploy/deploy.go b/nkd/app/phase/deploy/deploy.go deleted file mode 100644 index 8218cbc..0000000 --- a/nkd/app/phase/deploy/deploy.go +++ /dev/null @@ -1,15 +0,0 @@ -package deploy - -import "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" - -func NewDeployClusterCmd() workflow.Phase { - return workflow.Phase{ - Name: "deploy", - Short: "run deploy to deploy k8s cluster", - Run: runDeployK8sCluster, - } -} - -func runDeployK8sCluster() error { - return nil -} diff --git a/nkd/app/phase/deploy/infra/assets/assets.go b/nkd/app/phase/deploy/infra/assets/assets.go deleted file mode 100755 index 81fa8cd..0000000 --- a/nkd/app/phase/deploy/infra/assets/assets.go +++ /dev/null @@ -1,22 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package assets - -type File struct { - Filename string - Data []byte -} diff --git a/nkd/app/phase/deploy/infra/assets/cluster/cluster.go b/nkd/app/phase/deploy/infra/assets/cluster/cluster.go deleted file mode 100644 index 5b38e6a..0000000 --- a/nkd/app/phase/deploy/infra/assets/cluster/cluster.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cluster - -import ( - "os" - "path/filepath" - - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/assets" - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform" - "github.com/hashicorp/terraform-exec/tfexec" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -/* - installDir:自定义工作目录,在该路径下自动创建terraform文件夹 - dir:该路径存放tf配置文件 - terraformDir:该路径包含bin、plugins目录,存放terraform执行文件以及所需plugins -*/ - -type InfraProvider interface { - Create() - Destroy() -} - -type Cluster struct { - InstallDir string - Platform string - Name string -} - -// TODO: 配置文件准备阶段 - -func (c *Cluster) Create() error { - terraformDir := filepath.Join(c.InstallDir, "terraform") - dir := filepath.Join(terraformDir, c.Platform, c.Name) - - terraformVariables := &TerraformVariables{} - tfvarsFiles := make([]*assets.File, 0, len(terraformVariables.Files())+len(c.Platform)+len(c.Name)) - tfvarsFiles = append(tfvarsFiles, terraformVariables.Files()...) - - logrus.Infof("start to create %s in %s", c.Name, c.Platform) - - outputs, err := c.applyStage(dir, terraformDir, tfvarsFiles) - if err != nil { - return errors.Wrapf(err, "failed to create %s in %s", c.Name, c.Platform) - } - - logrus.Info(string(outputs.Data)) - logrus.Infof("succeed in creating %s in %s", c.Name, c.Platform) - - return nil -} - -func (c *Cluster) applyStage(dir string, terraformDir string, tfvarsFiles []*assets.File) (*assets.File, error) { - var applyOpts []tfexec.ApplyOption - for _, file := range tfvarsFiles { - if err := os.WriteFile(filepath.Join(dir, file.Filename), file.Data, 0o600); err != nil { - return nil, err - } - applyOpts = append(applyOpts, tfexec.VarFile(filepath.Join(dir, file.Filename))) - } - - return c.applyTerraform(dir, terraformDir, applyOpts...) -} - -func (c *Cluster) applyTerraform(dir string, terraformDir string, applyOpts ...tfexec.ApplyOption) (*assets.File, error) { - applyErr := terraform.TFApply(dir, terraformDir, applyOpts...) - - _, err := os.Stat(filepath.Join(dir, "terraform.tfstate")) - if os.IsNotExist(err) { - logrus.Errorf("Failed to read tfstate: %v", err) - return nil, errors.Wrap(err, "failed to read tfstate") - } - - if applyErr != nil { - return nil, errors.WithMessage(applyErr, "failed to apply Terraform") - } - - outputs, err := terraform.Outputs(dir, terraformDir) - if err != nil { - return nil, errors.Wrap(err, "could not get outputs file") - } - - outputsFile := &assets.File{ - Filename: "outputs", - Data: outputs, - } - - return outputsFile, nil -} - -func (c *Cluster) Destroy() error { - terraformDir := filepath.Join(c.InstallDir, "terraform") - dir := filepath.Join(terraformDir, c.Platform, c.Name) - - logrus.Infof("start to destroy %s in %s", c.Name, c.Platform) - - // Question: Destroy的tfvarsFiles的获取 - - terraformVariables := &TerraformVariables{} - tfvarsFiles := make([]*assets.File, 0, len(terraformVariables.Files())+len(c.Platform)+len(c.Name)) - tfvarsFiles = append(tfvarsFiles, terraformVariables.Files()...) - - err := c.destroyStage(dir, terraformDir, tfvarsFiles) - if err != nil { - return errors.Wrapf(err, "failed to destroy %s in %s", c.Name, c.Platform) - } - os.Remove(dir) - - logrus.Infof("succeed in destroying %s in %s", c.Name, c.Platform) - - return nil -} - -func (c *Cluster) destroyStage(dir string, terraformDir string, tfvarsFiles []*assets.File) error { - var destroyOpts []tfexec.DestroyOption - for _, file := range tfvarsFiles { - if err := os.WriteFile(filepath.Join(dir, file.Filename), file.Data, 0o600); err != nil { - return err - } - destroyOpts = append(destroyOpts, tfexec.VarFile(filepath.Join(dir, file.Filename))) - } - - return destroyTerraform(dir, terraformDir, destroyOpts...) -} - -func destroyTerraform(dir string, terraformDir string, destroyOpts ...tfexec.DestroyOption) error { - destroyErr := terraform.TFDestroy(dir, terraformDir, destroyOpts...) - if destroyErr != nil { - return errors.WithMessage(destroyErr, "failed to destroy Terraform") - } - - return nil -} diff --git a/nkd/app/phase/deploy/infra/assets/cluster/tfvars.go b/nkd/app/phase/deploy/infra/assets/cluster/tfvars.go deleted file mode 100644 index a2f1b17..0000000 --- a/nkd/app/phase/deploy/infra/assets/cluster/tfvars.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cluster - -import ( - "encoding/json" - "html/template" - "os" - "path/filepath" - - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/assets" - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/tfvars/openstack" - "github.com/pkg/errors" -) - -type TerraformVariables struct { - FileList []*assets.File -} - -func (t *TerraformVariables) Files() []*assets.File { - return t.FileList -} - -func Generate() error { - // 从文件中读取 jsonData - jsonData, err := os.ReadFile("data/json/openstack/main.tf.json") - if err != nil { - return errors.Wrap(err, "error reading json data") - } - - // 解析 JSON 数据 - var terraformData openstack.TerraformData - err = json.Unmarshal(jsonData, &terraformData) - if err != nil { - return errors.Wrap(err, "error parsing json data") - } - - // 从文件中读取 terraformConfig - terraformConfig, err := os.ReadFile("data/templates/openstack/main.tf.template") - if err != nil { - return errors.Wrap(err, "error reading terraform config template") - } - - // 使用模板填充数据 - tmpl, err := template.New("terraform").Parse(string(terraformConfig)) - if err != nil { - return errors.Wrap(err, "error creating terraform config template") - } - - // 创建一个新的文件用于写入填充后的数据 - tfDir := filepath.Join("/root", "terraform") - if err := os.MkdirAll(tfDir, os.ModePerm); err != nil { - return errors.Wrap(err, "could not create the terraform directory") - } - - outputFile, err := os.Create(filepath.Join(tfDir, "main.tf")) - if err != nil { - return errors.Wrap(err, "error creating terraform config") - } - defer outputFile.Close() - - // 将填充后的数据写入文件 - err = tmpl.Execute(outputFile, terraformData) - if err != nil { - return errors.Wrap(err, "error executing terraform config") - } - - return nil -} diff --git a/nkd/app/phase/deploy/infra/terraform/init.go b/nkd/app/phase/deploy/infra/terraform/init.go deleted file mode 100644 index cbd3ad3..0000000 --- a/nkd/app/phase/deploy/infra/terraform/init.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package terraform - -import ( - "context" - "path/filepath" - - "github.com/hashicorp/terraform-exec/tfexec" - "github.com/pkg/errors" -) - -// terraform init -func TFInit(dir string, terraformDir string) error { - tf, err := newTFExec(dir, terraformDir) - if err != nil { - return errors.Wrap(err, "failed to create a new tfexec") - } - - // 使用本地terraform插件 - err = tf.Init(context.Background(), tfexec.PluginDir(filepath.Join(terraformDir, "plugins"))) - if err != nil { - return errors.Wrap(err, "failed to init terraform") - } - - return nil -} diff --git a/nkd/app/phase/deploy/infra/terraform/logger.go b/nkd/app/phase/deploy/infra/terraform/logger.go deleted file mode 100644 index 54add90..0000000 --- a/nkd/app/phase/deploy/infra/terraform/logger.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package terraform - -import ( - "github.com/sirupsen/logrus" -) - -type printfer struct { - logger *logrus.Logger - level logrus.Level -} - -func newPrintfer() *printfer { - return &printfer{ - logger: logrus.StandardLogger(), - level: logrus.DebugLevel, - } -} - -func (p *printfer) Printf(format string, ifs ...interface{}) { - p.logger.Logf(p.level, format, ifs...) -} diff --git a/nkd/app/phase/deploy/infra/terraform/providers/providers.go b/nkd/app/phase/deploy/infra/terraform/providers/providers.go deleted file mode 100644 index 986ee8a..0000000 --- a/nkd/app/phase/deploy/infra/terraform/providers/providers.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package providers - -import "fmt" - -var ( - OpenStack = provider("openstack") -) - -type Provider struct { - Name string - Source string -} - -func provider(name string) Provider { - return Provider{ - Name: name, - Source: fmt.Sprintf("nkd/local/%s", name), - } -} diff --git a/nkd/app/phase/deploy/infra/terraform/stage.go b/nkd/app/phase/deploy/infra/terraform/stage.go deleted file mode 100644 index dabe48f..0000000 --- a/nkd/app/phase/deploy/infra/terraform/stage.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package terraform - -import "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform/providers" - -type Stage interface { - Name() string - - // the list of providers that are used for the stage - Providers() []providers.Provider -} diff --git a/nkd/app/phase/deploy/infra/terraform/stages/openstack/stages.go b/nkd/app/phase/deploy/infra/terraform/stages/openstack/stages.go deleted file mode 100644 index 1b1f18a..0000000 --- a/nkd/app/phase/deploy/infra/terraform/stages/openstack/stages.go +++ /dev/null @@ -1,19 +0,0 @@ -package openstack - -import ( - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform" - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform/providers" - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform/stages" -) - -var PlatformStages = []terraform.Stage{} - -func AddPlatformStage(name string) { - newStage := stages.NewStage( - "openstack", - name, - []providers.Provider{providers.OpenStack}, - ) - - PlatformStages = append(PlatformStages, newStage) -} diff --git a/nkd/app/phase/deploy/infra/terraform/stages/platform/stages.go b/nkd/app/phase/deploy/infra/terraform/stages/platform/stages.go deleted file mode 100644 index 7a99cad..0000000 --- a/nkd/app/phase/deploy/infra/terraform/stages/platform/stages.go +++ /dev/null @@ -1,19 +0,0 @@ -package platform - -import ( - "errors" - "fmt" - - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform" - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform/stages/openstack" -) - -func StagesForPlatform(platform string, stage string) ([]terraform.Stage, error) { - switch platform { - case "openstack": - openstack.AddPlatformStage(stage) - return openstack.PlatformStages, nil - default: - return nil, errors.New(fmt.Sprintf("unsupported platform %q", platform)) - } -} diff --git a/nkd/app/phase/deploy/infra/terraform/stages/split.go b/nkd/app/phase/deploy/infra/terraform/stages/split.go deleted file mode 100644 index caf0de7..0000000 --- a/nkd/app/phase/deploy/infra/terraform/stages/split.go +++ /dev/null @@ -1,43 +0,0 @@ -package stages - -import ( - "fmt" - - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra/terraform/providers" -) - -type StageOption func(*SplitStage) - -func NewStage(platform, name string, providers []providers.Provider, opts ...StageOption) SplitStage { - s := SplitStage{ - platform: platform, - name: name, - providers: providers, - } - for _, opt := range opts { - opt(&s) - } - return s -} - -type SplitStage struct { - platform string - name string - providers []providers.Provider -} - -func (s SplitStage) Name() string { - return s.name -} - -func (s SplitStage) Providers() []providers.Provider { - return s.providers -} - -func (s SplitStage) StateFilename() string { - return fmt.Sprintf("terraform.%s.tfstate", s.name) -} - -func (s SplitStage) OutputsFilename() string { - return fmt.Sprintf("%s.tfvars.json", s.name) -} diff --git a/nkd/app/phase/deploy/infra/terraform/state.go b/nkd/app/phase/deploy/infra/terraform/state.go deleted file mode 100644 index 9509abc..0000000 --- a/nkd/app/phase/deploy/infra/terraform/state.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package terraform - -import ( - "context" - "encoding/json" - - "github.com/pkg/errors" -) - -const StateFilename = "terraform.tfstate" - -// Reads the terraform state file. -func Outputs(workingDir string, terraformBinary string) ([]byte, error) { - tf, err := newTFExec(workingDir, terraformBinary) - if err != nil { - return nil, err - } - - tfoutput, err := tf.Output(context.Background()) - if err != nil { - return nil, errors.Wrap(err, "failed to read terraform state file") - } - - outputs := make(map[string]interface{}, len(tfoutput)) - for key, value := range tfoutput { - outputs[key] = value.Value - } - - data, err := json.Marshal(outputs) - if err != nil { - return nil, errors.Wrap(err, "could not marshal outputs") - } - - return data, nil -} diff --git a/nkd/app/phase/deploy/infra/terraform/terraform.go b/nkd/app/phase/deploy/infra/terraform/terraform.go deleted file mode 100644 index 6bb6a9c..0000000 --- a/nkd/app/phase/deploy/infra/terraform/terraform.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package terraform - -import ( - "context" - "os" - "path/filepath" - "runtime" - - "github.com/hashicorp/terraform-exec/tfexec" - "github.com/openshift/installer/pkg/lineprinter" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -func newTFExec(dir string, terraformDir string) (*tfexec.Terraform, error) { - tfPath := filepath.Join(terraformDir, "bin", runtime.GOOS+"_"+runtime.GOARCH, "terraform") - tf, err := tfexec.NewTerraform(dir, tfPath) - if err != nil { - return nil, err - } - - // If the log path is not set, terraform will not receive debug logs. - if logPath, ok := os.LookupEnv("TERRAFORM_LOG_PATH"); ok { - if err := tf.SetLog(os.Getenv("TERRAFORM_LOG")); err != nil { - logrus.Infof("Skipping setting terraform log levels: %v", err) - } else { - tf.SetLogCore(os.Getenv("TERRAFORM_LOG_CORE")) //nolint:errcheck - tf.SetLogProvider(os.Getenv("TERRAFORM_LOG_PROVIDER")) //nolint:errcheck - tf.SetLogPath(logPath) //nolint:errcheck - } - } - - // Add terraform info logs to the installer log - lpDebug := &lineprinter.LinePrinter{Print: (&lineprinter.Trimmer{WrappedPrint: logrus.Debug}).Print} - lpError := &lineprinter.LinePrinter{Print: (&lineprinter.Trimmer{WrappedPrint: logrus.Error}).Print} - defer lpDebug.Close() - defer lpError.Close() - - tf.SetStdout(lpDebug) - tf.SetStderr(lpError) - tf.SetLogger(newPrintfer()) - - return tf, nil -} - -// terraform apply -func TFApply(dir string, terraformDir string, applyOpts ...tfexec.ApplyOption) error { - if err := TFInit(dir, terraformDir); err != nil { - return err - } - - tf, err := newTFExec(dir, terraformDir) - if err != nil { - return errors.Wrap(err, "failed to create a new tfexec") - } - - err = tf.Apply(context.Background(), applyOpts...) - if err != nil { - return errors.Wrap(err, "failed to apply Terraform") - } - - return nil -} - -// terraform destroy -func TFDestroy(dir string, terraformDir string, destroyOpts ...tfexec.DestroyOption) error { - if err := TFInit(dir, terraformDir); err != nil { - return err - } - - tf, err := newTFExec(dir, terraformDir) - if err != nil { - return errors.Wrap(err, "failed to destroy a new tfexec") - } - - err = tf.Destroy(context.Background(), destroyOpts...) - if err != nil { - return errors.Wrap(err, "failed to destroy terraform") - } - - return nil -} diff --git a/nkd/app/phase/deploy/infra/tfvars/openstack/tfvars.go b/nkd/app/phase/deploy/infra/tfvars/openstack/tfvars.go deleted file mode 100644 index 693bee2..0000000 --- a/nkd/app/phase/deploy/infra/tfvars/openstack/tfvars.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package openstack - -// 定义 JSON 数据的结构 -type TerraformData struct { - Openstack struct { - User_name string `json:"user_name"` - Password string `json:"password"` - Tenant_name string `json:"tenant_name"` - Auth_url string `json:"auth_url"` - Region string `json:"region"` - } `json:"openstack"` - Flavor struct { - Name string `json:"name"` - Ram string `json:"ram"` - Vcpus string `json:"vcpus"` - Disk string `json:"disk"` - Is_public string `json:"is_public"` - } `json:"flavor"` - Instance struct { - Count string `json:"count"` - Name string `json:"name"` - Image_name string `json:"image_name"` - Key_pair string `json:"key_pair"` - } `json:"instance"` - Floatip struct { - Pool string `json:"pool"` - } `json:"floatip"` -} diff --git a/nkd/app/phase/init/.DS_Store b/nkd/app/phase/init/.DS_Store deleted file mode 100644 index b54f3e5947f13a2a169c68e548b4bbf1d8a784d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z-NTn^J@v6nb3nTClcKEM7vaFJMFuDz!1S24l7~sXdfJ&iX<=iO=KA z?&c5-coVTRu=~x<&u->}>x63aJDBnQrw>>AAB9h5>%uihe#WIO|Vo|DHC5(C5l zF+dD#9|Ptruv*(!I#o;z5CcCjfct}hhUgf~G^(uwI=nukzlMkcI=&?kg+a$)rV%_K zT&Du+RBoOaT&IIwm^jB^rctLeu2zP5%*y%Wg{#%UE>t+w@SO09*4+6951J diff --git a/nkd/app/phase/init/config/cert/cacert.go b/nkd/app/phase/init/config/cert/cacert.go deleted file mode 100644 index 0e1227e..0000000 --- a/nkd/app/phase/init/config/cert/cacert.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cert - -import ( - "crypto/x509" - "crypto/x509/pkix" -) - -type RootCA struct { - SelfSignedCertKey -} - -func (c *RootCA) Generate() error { - cfg := &CertConfig{ - Subject: pkix.Name{CommonName: "rootca", OrganizationalUnit: []string{"NestOS"}}, - KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, - Validity: 3650, - IsCA: true, - } - - return c.SelfSignedCertKey.Generate(cfg, "rootca") -} diff --git a/nkd/app/phase/init/config/cert/certapi.go b/nkd/app/phase/init/config/cert/certapi.go deleted file mode 100644 index 4c7c642..0000000 --- a/nkd/app/phase/init/config/cert/certapi.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cert - -import ( - "crypto/x509" - "crypto/x509/pkix" - "net" - "time" -) - -type CertInterface interface { - // Cert returns the certificate. - Cert() []byte -} - -// CertKeyInterface contains a private key and the associated cert. -type CertKeyInterface interface { - CertInterface - // Key returns the private key. - Key() []byte -} - -type CertificateGenerator interface { - GenerateCACertificate() error - GenerateSignedCertificate(commonName string) error -} - -// CertKey 包含证书和私钥 -type CertKey struct { - CertRaw []byte - KeyRaw []byte - SavePath string -} - -type CertConfig struct { - DNSNames []string - ExtKeyUsages []x509.ExtKeyUsage - IPAddresses []net.IP - KeyUsages x509.KeyUsage - Subject pkix.Name - Validity time.Duration - IsCA bool -} diff --git a/nkd/app/phase/init/config/cert/etcd.go b/nkd/app/phase/init/config/cert/etcd.go deleted file mode 100755 index 57a64f5..0000000 --- a/nkd/app/phase/init/config/cert/etcd.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cert - -import ( - "gitee.com/openeuler/nestos-kubernetes-deployer/pkg/infra" -) - -type EtcdCaGenerator struct { -} - -func (e EtcdCaGenerator) GenerateAssets() infra.Assets { - return nil -} - -func init() { -} diff --git a/nkd/app/phase/init/config/cert/selfsignedcert.go b/nkd/app/phase/init/config/cert/selfsignedcert.go deleted file mode 100644 index 91f9d4c..0000000 --- a/nkd/app/phase/init/config/cert/selfsignedcert.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cert - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "math/big" - "time" - - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -// SelfSignedCertificate 只负责创建自签名的证书,这里只传入cfg和privatekey -func SelfSignedCertificate(cfg *CertConfig, key *rsa.PrivateKey) (*x509.Certificate, error) { - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) - serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - if err != nil { - logrus.Errorf("Failed to generate serialNumber: %v", err) - return nil, err - } - certTemplate := x509.Certificate{ - BasicConstraintsValid: true, - IsCA: cfg.IsCA, - KeyUsage: cfg.KeyUsages, - NotAfter: time.Now().Add(cfg.Validity), - NotBefore: time.Now(), - SerialNumber: serialNumber, - Subject: cfg.Subject, - } - // 判断subject字段中CommonName和OrganizationalUnit是否为空 - if len(cfg.Subject.CommonName) == 0 || len(cfg.Subject.OrganizationalUnit) == 0 { - return nil, errors.Errorf("certification's subject is not set, or invalid") - } - - //certBytes是生成证书的中间步骤,它用于将证书的二进制表示存储在内存中,以便后续操作可以使用它 - certBytes, err := x509.CreateCertificate(rand.Reader, &certTemplate, &certTemplate, key.Public(), key) - if err != nil { - return nil, errors.Wrap(err, "failed to create certificate") - } - - return x509.ParseCertificate(certBytes) -} - -/*GenerateSelfSignedCertificate负责根据cfg生成私钥和证书 - 在这一步会调用PrivateKey生成私钥并调用SelfSignedCertificate生成证书,并将结果返回*/ -func GenerateSelfSignedCertificate(cfg *CertConfig) (*rsa.PrivateKey, *x509.Certificate, error) { - key, err := PrivateKey() - if err != nil { - logrus.Debugf("Failed to generate private key: %s", err) - return nil, nil, errors.Wrap(err, "Failed to generate private key") - } - - //这里的crt是parse之后的,表示已经生成的CA证书,用于存储CA证书的详细信息,例如证书序列号、主题、有效期等 - crt, err := SelfSignedCertificate(cfg, key) - if err != nil { - logrus.Debugf("Failed to create self-signed certificate: %s", err) - return nil, nil, errors.Wrap(err, "failed to create self-signed certificate") - } - return key, crt, nil -} - -type SelfSignedCertKey struct { - CertKey -} - -//自签名证书生成器,封装后该方法用于所有自签名的证书,并将证书和私钥转换格式后保存 -func (c *SelfSignedCertKey) Generate(cfg *CertConfig, filename string) error { - - key, crt, err := GenerateSelfSignedCertificate(cfg) - if err != nil { - return errors.Wrap(err, "Failed to generate self-signed cert/key pair") - } - - c.KeyRaw = PrivateKeyToPem(key) - c.CertRaw = CertToPem(crt) - - err = c.SaveCertificateToFile(filename) - if err != nil { - logrus.Errorf("Faile to save %s: %v", filename, err) - } - - return nil - -} diff --git a/nkd/app/phase/init/config/cert/signedcerts.go b/nkd/app/phase/init/config/cert/signedcerts.go deleted file mode 100644 index 66d8a44..0000000 --- a/nkd/app/phase/init/config/cert/signedcerts.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cert - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "math/big" - "time" - - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -func SignedCertificate( - cfg *CertConfig, - csr *x509.CertificateRequest, - key *rsa.PrivateKey, - caCert *x509.Certificate, - caKey *rsa.PrivateKey, -) (*x509.Certificate, error) { - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) - serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - if err != nil { - logrus.Errorf("Failed to generate serialNumber: %v", err) - return nil, err - } - certTemplate := x509.Certificate{ - BasicConstraintsValid: true, - IsCA: cfg.IsCA, - DNSNames: csr.DNSNames, - ExtKeyUsage: cfg.ExtKeyUsages, - IPAddresses: csr.IPAddresses, - KeyUsage: cfg.KeyUsages, - NotAfter: time.Now().Add(cfg.Validity), - NotBefore: caCert.NotBefore, - SerialNumber: serialNumber, - Subject: csr.Subject, - } - certBytes, err := x509.CreateCertificate(rand.Reader, &certTemplate, caCert, key.Public(), caKey) - if err != nil { - return nil, errors.Wrap(err, "failed to create x509 certificate") - } - return x509.ParseCertificate(certBytes) -} - -func GenerateSignedCertificate(caKey *rsa.PrivateKey, caCert *x509.Certificate, - cfg *CertConfig) (*rsa.PrivateKey, *x509.Certificate, error) { - key, err := PrivateKey() - if err != nil { - return nil, nil, errors.Wrap(err, "failed to generate private key") - } - // create a CSR - csrTmpl := x509.CertificateRequest{Subject: cfg.Subject, DNSNames: cfg.DNSNames, IPAddresses: cfg.IPAddresses} - csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &csrTmpl, key) - if err != nil { - return nil, nil, errors.Wrap(err, "failed to create certificate request") - } - csr, err := x509.ParseCertificateRequest(csrBytes) - if err != nil { - logrus.Debugf("Failed to parse x509 certificate request: %s", err) - return nil, nil, errors.Wrap(err, "error parsing x509 certificate request") - } - - // create a cert - cert, err := SignedCertificate(cfg, csr, key, caCert, caKey) - if err != nil { - logrus.Debugf("Failed to create a signed certificate: %s", err) - return nil, nil, errors.Wrap(err, "failed to create a signed certificate") - } - return key, cert, nil - -} - -type SignedCertKey struct { - CertKey -} - -func (c *SignedCertKey) Generate( - cfg *CertConfig, - parentCA CertKeyInterface, - filename string, -) error { - var key *rsa.PrivateKey - var crt *x509.Certificate - var err error - - caKey, err := PemToPrivateKey(parentCA.Key()) - if err != nil { - logrus.Debugf("Failed to parse RSA private key: %s", err) - return errors.Wrap(err, "failed to parse rsa private key") - } - - caCert, err := PemToCertificate(parentCA.Cert()) - if err != nil { - logrus.Debugf("Failed to parse x509 certificate: %s", err) - return errors.Wrap(err, "failed to parse x509 certificate") - } - - key, crt, err = GenerateSignedCertificate(caKey, caCert, cfg) - if err != nil { - logrus.Debugf("Failed to generate signed cert/key pair: %s", err) - return errors.Wrap(err, "failed to generate signed cert/key pair") - } - - c.KeyRaw = PrivateKeyToPem(key) - c.CertRaw = CertToPem(crt) - - err = c.SaveCertificateToFile(filename) - if err != nil { - logrus.Errorf("Faile to save %s: %v", filename, err) - } - - return nil -} diff --git a/nkd/app/phase/init/config/cert/tools.go b/nkd/app/phase/init/config/cert/tools.go deleted file mode 100644 index 4d10d39..0000000 --- a/nkd/app/phase/init/config/cert/tools.go +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright 2023 KylinSoft Co., Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cert - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "io/ioutil" - - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -//PrivateKey负责生成密钥 -func PrivateKey() (*rsa.PrivateKey, error) { - rsaKey, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - return nil, errors.Wrap(err, "Failed to generate RSA private key") - } - - return rsaKey, nil -} - -// PrivateKeyToPem 返回私钥的PEM格式字节切片 -func PrivateKeyToPem(key *rsa.PrivateKey) []byte { - keyInBytes := x509.MarshalPKCS1PrivateKey(key) - keyinPem := pem.EncodeToMemory( - &pem.Block{ - Type: "RSA PRIVATE KEY", - Bytes: keyInBytes, - }, - ) - return keyinPem -} - -func PemToPrivateKey(data []byte) (*rsa.PrivateKey, error) { - block, _ := pem.Decode(data) - if block == nil { - return nil, errors.Errorf("could not find a PEM block in the private key") - } - return x509.ParsePKCS1PrivateKey(block.Bytes) -} - -// CACertPEM 返回证书的PEM格式字节切片 -func CertToPem(cert *x509.Certificate) []byte { - certInPem := pem.EncodeToMemory( - &pem.Block{ - Type: "CERTIFICATE", - Bytes: cert.Raw, - }, - ) - return certInPem -} - -func PemToCertificate(data []byte) (*x509.Certificate, error) { - block, _ := pem.Decode(data) - if block == nil { - return nil, errors.Errorf("could not find a PEM block in the certificate") - } - return x509.ParseCertificate(block.Bytes) -} - -// SaveCertificateToFile 将证书保存到文件 -func (c *CertKey) SaveCertificateToFile(filename string) error { - err := ioutil.WriteFile(c.SavePath+"/"+filename, c.CertRaw, 0644) - if err != nil { - logrus.Errorf("Faile to save %s: %v", filename, err) - return err - } - - logrus.Infof("Successfully saved %s", filename) - - return nil -} - -// SavePrivateKeyToFile 将私钥保存到文件 -func (c *CertKey) SavePrivateKeyToFile(filename string) error { - err := ioutil.WriteFile(c.SavePath+"/"+filename, c.KeyRaw, 0600) - if err != nil { - logrus.Errorf("Faile to save %s: %v", filename, err) - return err - } - - logrus.Infof("Successfully saved %s", filename) - - return nil -} diff --git a/nkd/app/phase/init/config/certs.go b/nkd/app/phase/init/config/certs.go deleted file mode 100644 index 23352b6..0000000 --- a/nkd/app/phase/init/config/certs.go +++ /dev/null @@ -1,15 +0,0 @@ -package config - -import "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" - -func NewGenerateCertsCmd() workflow.Phase { - return workflow.Phase{ - Name: "cert", - Short: "Run certs to generate certs", - Run: runGenerateCertsConfig, - } -} - -func runGenerateCertsConfig() error { - return nil -} diff --git a/nkd/app/phase/init/config/infra.go b/nkd/app/phase/init/config/infra.go deleted file mode 100644 index a84bdd2..0000000 --- a/nkd/app/phase/init/config/infra.go +++ /dev/null @@ -1,17 +0,0 @@ -package config - -import ( - "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" -) - -func NewGenerateInfraCmd() workflow.Phase { - return workflow.Phase{ - Name: "infra", - Short: "run k8s to genertate infra config", - Run: runGenerateInfraConfig, - } -} - -func runGenerateInfraConfig() error { - return nil -} diff --git a/nkd/app/phase/init/config/k8s.go b/nkd/app/phase/init/config/k8s.go deleted file mode 100644 index a25c4f2..0000000 --- a/nkd/app/phase/init/config/k8s.go +++ /dev/null @@ -1,15 +0,0 @@ -package config - -import "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app/phase/workflow" - -func NewGenerateK8sCmd() workflow.Phase { - return workflow.Phase{ - Name: "k8s", - Short: "run k8s to genertate k8s config", - Run: runGenerateK8sConfig, - } -} - -func runGenerateK8sConfig() error { - return nil -} diff --git a/nkd/app/phase/workflow/Phase.go b/nkd/app/phase/workflow/Phase.go deleted file mode 100644 index 87277b9..0000000 --- a/nkd/app/phase/workflow/Phase.go +++ /dev/null @@ -1,8 +0,0 @@ -package workflow - -type Phase struct { - Name string - Short string - Phases []Phase - Run func() error -} diff --git a/nkd/app/phase/workflow/runner.go b/nkd/app/phase/workflow/runner.go deleted file mode 100644 index 9743357..0000000 --- a/nkd/app/phase/workflow/runner.go +++ /dev/null @@ -1,91 +0,0 @@ -package workflow - -import ( - "strings" -) - -type Runner struct { - Phases []Phase - phaseRunners []*phaseRunner -} -type phaseRunner struct { - Phase - parent *phaseRunner - level int - selfPath []string - generatedName string - use string -} - -type RunData interface{} - -func NewRunner() *Runner { - return &Runner{ - Phases: []Phase{}, - } -} - -func (r *Runner) Run() error { - r.prepareForExcution() - print(r.Phases) - - err := r.VisitAll(func(p *phaseRunner) error { - if p.Run != nil { - if err := p.Run(); err != nil { - return err - } - } - return nil - }) - return err -} - -func (r *Runner) VisitAll(fn func(*phaseRunner) error) error { - for _, currentRunner := range r.phaseRunners { - if err := fn(currentRunner); err != nil { - return err - } - } - return nil -} - -func (r *Runner) InitData(args []string) (RunData, error) { - return nil, nil -} - -func (r *Runner) AppendPhase(t Phase) { - r.Phases = append(r.Phases, t) -} - -func (r *Runner) prepareForExcution() { - r.phaseRunners = []*phaseRunner{} - var parentRunner *phaseRunner - for _, phase := range r.Phases { - addPhaseRunner(r, parentRunner, phase) - } -} - -func addPhaseRunner(e *Runner, parentRunner *phaseRunner, phase Phase) { - use := cleanName(phase.Name) - generatedName := use - selfPath := []string{generatedName} - currentRunner := &phaseRunner{ - Phase: phase, - parent: parentRunner, - level: len(selfPath) - 1, - selfPath: selfPath, - generatedName: generatedName, - use: use, - } - e.phaseRunners = append(e.phaseRunners, currentRunner) - - for _, childPhase := range phase.Phases { - addPhaseRunner(e, currentRunner, childPhase) - } - -} - -func cleanName(name string) string { - ret := strings.ToLower(name) - return ret -} diff --git a/nkd/nkd.go b/nkd/nkd.go deleted file mode 100644 index 385ae5b..0000000 --- a/nkd/nkd.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "gitee.com/openeuler/nestos-kubernetes-deployer/nkd/app" - -func main() { - app.Run() -} diff --git a/nkd/resource/assert/terrafrom/terraform b/nkd/resource/assert/terrafrom/terraform deleted file mode 100644 index e69de29..0000000 diff --git a/nkd/resource/templates/config.json b/nkd/resource/templates/config.json deleted file mode 100644 index ee15e56..0000000 --- a/nkd/resource/templates/config.json +++ /dev/null @@ -1,83 +0,0 @@ -[{ - "k8s": { - "advertiseAddress": "", - "kubernetesVersion": "", - "serviceSubnet": "" - }, - "kubeadm": { - "path": "" - }, - "cert":{ - "timeout": "" - }, - "repo": { - "secret": { - }, - "registry": [] - }, - - "infra": { - "platform": "openstack", - "path": "" - }, - "addon": [ - {"name": "calico", "path": ""}, - {} - ] -}, - -{ - "cluster": { - "name": "" - }, - "system":{ - "hostname": [], - "user_name": "", - "password": "", - "certs": { - "timeout": "" - } - }, - "repo": { - "secret": {}, - "registry": {} - }, - "k8s":{ - "kubeadm": {} - }, - "infra":{ - "platform": "", - "vm_size": { - "master": { - "vcpus": "4", - "ram": "8192", - "disk": "64" - }, - "node": { - "vcpus": "4", - "ram": "8192", - "disk": "64" - } - }, - "openstack": { - "user_name": "admin", - "password": "qwer1234", - "tenant_name": "admin", - "auth_url": "", - "region": "RegionOne", - "master_instance_name": [], - "worker_instance_name": [], - "network_name": "", - "master_ip": [], - "worker_ip": [], - "float_ip_pool": "" - }, - "libvirt": {}, - "aliyun": {} - }, - "addon": [ - {"name": "", "path": ""}, - {} - ] -} -] \ No newline at end of file diff --git a/nkd/resource/templates/k8s/k8s-master.bu b/nkd/resource/templates/k8s/k8s-master.bu deleted file mode 100644 index e69de29..0000000 diff --git a/nkd/resource/templates/openstack.json b/nkd/resource/templates/openstack.json deleted file mode 100644 index beae023..0000000 --- a/nkd/resource/templates/openstack.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "keystone": { - "user_name": "", - "password": "", - "tenant_name": "", - "auth_url": "", - "region": "" - }, - "master": { - "count": "", - "image": { - "local_file_path": "", - "remote_url": "" - }, - "network": { - "name": "" - }, - "flavor": { - "name": "" - }, - "secgroup": { - "name": "" - }, - "user_data": { - "file": "" - }, - "keypair": { - "name": "" - } - - - }, - "node": { - "count": "", - "image": { - "local_file_path": "", - "remote_url": "" - }, - "network": { - "name": "" - }, - "flavor": { - "name": "" - }, - "secgroup": { - "name": "" - }, - "user_data": { - "file": "" - }, - "keypair": { - "name": "" - } - } - -} \ No newline at end of file diff --git a/nkd/resource/templates/terraform/master/main.tf b/nkd/resource/templates/terraform/master/main.tf deleted file mode 100644 index e69de29..0000000 diff --git a/nkd/resource/templates/terraform/node/main.tf b/nkd/resource/templates/terraform/node/main.tf deleted file mode 100644 index e69de29..0000000 -- Gitee