refactor: integrate CLI's code & CI into main repo (#1343)

This commit is contained in:
dkeven
2025-05-26 17:21:25 +08:00
committed by GitHub
parent 532b0a3e24
commit 22fdd7b86f
529 changed files with 102147 additions and 66 deletions

View File

@@ -48,6 +48,23 @@ jobs:
# if: steps.list-changed.outputs.changed == 'true'
# run: ct install --chart-dirs wizard/charts,wizard/config --target-branch ${{ github.event.repository.default_branch }}
test-version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.generate.outputs.version }}
steps:
- id: generate
run: |
v=1.12.0-$(echo $RANDOM)
echo "version=$v" >> "$GITHUB_OUTPUT"
upload-cli:
needs: test-version
uses: ./.github/workflows/release-cli.yaml
secrets: inherit
with:
version: ${{ needs.test-version.outputs.version }}
push-image:
runs-on: ubuntu-latest
@@ -131,49 +148,46 @@ jobs:
bash build/deps-manifest.sh linux/arm64 && bash build/upload-deps.sh linux/arm64
install-test:
needs: [lint-test, push-image, push-image-arm64, push-deps, push-deps-arm64]
upload-package:
needs: [lint-test, test-version, push-image, push-image-arm64, push-deps, push-deps-arm64]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: 'Test tag version'
id: vars
run: |
v=1.12.0-$(echo $RANDOM)
echo "tag_version=$v" >> $GITHUB_OUTPUT
- name: Package installer
run: |
bash build/build.sh ${{ needs.test-version.outputs.version }}
- name: Package installer
run: |
bash build/build.sh ${{ steps.vars.outputs.tag_version }}
- name: Upload package
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
run: |
md5sum install-wizard-v${{ needs.test-version.outputs.version }}.tar.gz > install-wizard-v${{ needs.test-version.outputs.version }}.md5sum.txt && \
aws s3 cp install-wizard-v${{ needs.test-version.outputs.version }}.md5sum.txt s3://terminus-os-install/install-wizard-v${{ needs.test-version.outputs.version }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ needs.test-version.outputs.version }}.tar.gz s3://terminus-os-install/install-wizard-v${{ needs.test-version.outputs.version }}.tar.gz --acl=public-read
- name: Upload package
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
run: |
md5sum install-wizard-v${{ steps.vars.outputs.tag_version }}.tar.gz > install-wizard-v${{ steps.vars.outputs.tag_version }}.md5sum.txt && \
aws s3 cp install-wizard-v${{ steps.vars.outputs.tag_version }}.md5sum.txt s3://terminus-os-install/install-wizard-v${{ steps.vars.outputs.tag_version }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ steps.vars.outputs.tag_version }}.tar.gz s3://terminus-os-install/install-wizard-v${{ steps.vars.outputs.tag_version }}.tar.gz --acl=public-read
install-test:
needs: [test-version, upload-package]
runs-on: ubuntu-latest
steps:
- name: Deploy Request
uses: fjogeleit/http-request-action@v1
with:
url: 'https://cloud-dev-api.bttcdn.com/v1/resource/installTest'
method: 'POST'
customHeaders: '{"Authorization": "${{ secrets.INSTALL_SECRET }}"}'
data: 'versions=${{ steps.vars.outputs.tag_version }}&downloadUrl=https://dc3p1870nn3cj.cloudfront.net/install-wizard-v${{ steps.vars.outputs.tag_version }}.tar.gz'
data: 'versions=${{ needs.test-version.outputs.version }}&downloadUrl=https://dc3p1870nn3cj.cloudfront.net/install-wizard-v${{ steps.vars.outputs.tag_version }}.tar.gz'
contentType: "application/x-www-form-urlencoded"
- name: Check Reault
- name: Check Result
uses: eball/poll-check-endpoint@v0.1.0
with:
url: https://cloud-dev-api.bttcdn.com/v1/resource/installResult
@@ -184,4 +198,4 @@ jobs:
timeout: 1800000
interval: 30000
customHeaders: '{"Authorization": "${{ secrets.INSTALL_SECRET }}", "Content-Type": "application/x-www-form-urlencoded"}'
data: 'versions=${{ steps.vars.outputs.tag_version }}'
data: 'versions=${{ needs.test-version.outputs.version }}'

53
.github/workflows/release-cli.yaml vendored Normal file
View File

@@ -0,0 +1,53 @@
name: Release CLI
on:
workflow_call:
inputs:
version:
type: string
required: true
workflow_dispatch:
jobs:
goreleaser:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Add Local Git Tag For GoReleaser
run: git tag ${{ inputs.version }}
continue-on-error: true
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.22.4
- name: Install x86_64 cross-compiler
run: sudo apt-get update && sudo apt-get install -y build-essential
- name: Install ARM cross-compiler
run: sudo apt-get update && sudo apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v3.1.0
with:
distribution: goreleaser
workdir: './cli'
version: v1.18.2
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to S3
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
run: |
cd output && for file in *.tar.gz; do
aws s3 cp "$file" s3://terminus-os-install/$file --acl=public-read
# coscmd upload $file /$file
done

View File

@@ -9,6 +9,24 @@ on:
workflow_dispatch:
jobs:
daily-version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.generate.outputs.version }}
steps:
- id: generate
run: |
v=1.12.0-$(date +"%Y%m%d")
echo "version=$v" >> "$GITHUB_OUTPUT"
release-cli:
needs: daily-version
uses: ./.github/workflows/release-cli.yaml
secrets: inherit
with:
version: ${{ needs.daily-version.outputs.version }}
push-images:
runs-on: ubuntu-22.04
@@ -71,59 +89,50 @@ jobs:
upload-package:
needs: [push-images, push-images-arm64, push-deps, push-deps-arm64]
needs: [daily-version, push-images, push-images-arm64, push-deps, push-deps-arm64]
runs-on: ubuntu-latest
outputs:
md5sum: ${{ steps.upload.outputs.md5sum }}
steps:
- name: 'Daily tag version'
id: vars
run: |
v=1.12.0-$(date +"%Y%m%d")
echo "tag_version=$v" >> $GITHUB_OUTPUT
- name: 'Checkout source code'
uses: actions/checkout@v3
- name: Package installer
run: |
bash build/build.sh ${{ steps.vars.outputs.tag_version }}
bash build/build.sh ${{ needs.daily-version.outputs.version }}
- name: Upload to S3
id: upload
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
run: |
md5sum install-wizard-v${{ steps.vars.outputs.tag_version }}.tar.gz > install-wizard-v${{ steps.vars.outputs.tag_version }}.md5sum.txt && \
aws s3 cp install-wizard-v${{ steps.vars.outputs.tag_version }}.md5sum.txt s3://terminus-os-install/install-wizard-v${{ steps.vars.outputs.tag_version }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ steps.vars.outputs.tag_version }}.tar.gz s3://terminus-os-install/install-wizard-v${{ steps.vars.outputs.tag_version }}.tar.gz --acl=public-read
md5sum install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz > install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt && \
aws s3 cp install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt s3://terminus-os-install/install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz s3://terminus-os-install/install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz --acl=public-read && \
echo "md5sum=$(awk '{print $1}' install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt)" >> "$GITHUB_OUTPUT"
release:
needs: [upload-package]
needs: [daily-version, upload-package]
runs-on: ubuntu-latest
steps:
- name: 'Checkout source code'
uses: actions/checkout@v3
- name: 'Daily tag version'
id: vars
run: |
v=1.12.0-$(date +"%Y%m%d")
echo "tag_version=$v" >> $GITHUB_OUTPUT
echo "version_md5sum=$(curl -sSfL https://dc3p1870nn3cj.cloudfront.net/install-wizard-v${v}.md5sum.txt|awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Update checksum
uses: eball/write-tag-to-version-file@latest
with:
filename: 'build/base-package/install.sh'
placeholder: '#__MD5SUM__'
tag: ${{ steps.vars.outputs.version_md5sum }}
tag: ${{ needs.upload-package.outputs.md5sum }}
- name: Package installer
run: |
bash build/build.sh ${{ steps.vars.outputs.tag_version }}
bash build/build.sh ${{ needs.daily-version.outputs.version }}
- name: 'Archives'
run: |
@@ -134,10 +143,10 @@ jobs:
- name: Release public files
uses: softprops/action-gh-release@v1
with:
name: v${{ steps.vars.outputs.tag_version }} Release
tag_name: ${{ steps.vars.outputs.tag_version }}
name: v${{ needs.daily-version.outputs.version }} Release
tag_name: ${{ needs.daily-version.outputs.version }}
files: |
install-wizard-v${{ steps.vars.outputs.tag_version }}.tar.gz
install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz
build/base-package/publicInstaller.sh
build/base-package/install.sh
build/base-package/install.ps1

View File

@@ -9,6 +9,13 @@ on:
description: 'Release Tags'
jobs:
release-cli:
uses: ./.github/workflows/release-cli.yaml
secrets: inherit
with:
version: ${{ github.event.inputs.tags }}
push:
runs-on: ubuntu-22.04

3
.gitignore vendored
View File

@@ -28,4 +28,5 @@ install-wizard-*.tar.gz
olares-cli-*.tar.gz
!ks-console-*.tgz
.vscode
.DS_Store
.DS_Store
cli/output

View File

@@ -48,7 +48,7 @@ if (-Not (Test-Path $CLI_PROGRAM_PATH)) {
New-Item -Path $CLI_PROGRAM_PATH -ItemType Directory
}
$CLI_VERSION = "0.2.36"
$CLI_VERSION = "$version"
$CLI_FILE = "olares-cli-v{0}_windows_{1}.tar.gz" -f $CLI_VERSION, $arch
$CLI_URL = "{0}/{1}" -f $downloadUrl, $CLI_FILE
$CLI_PATH = "{0}{1}" -f $CLI_PROGRAM_PATH, $CLI_FILE

View File

@@ -74,13 +74,12 @@ if [ -z ${cdn_url} ]; then
cdn_url="https://dc3p1870nn3cj.cloudfront.net"
fi
CLI_VERSION="0.2.36"
CLI_FILE="olares-cli-v${CLI_VERSION}_linux_${ARCH}.tar.gz"
CLI_FILE="olares-cli-v${VERSION}_linux_${ARCH}.tar.gz"
if [[ x"$os_type" == x"Darwin" ]]; then
CLI_FILE="olares-cli-v${CLI_VERSION}_darwin_${ARCH}.tar.gz"
CLI_FILE="olares-cli-v${VERSION}_darwin_${ARCH}.tar.gz"
fi
if command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$CLI_VERSION" ]]; then
if command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$VERSION" ]]; then
INSTALL_OLARES_CLI=$(which olares-cli)
echo "olares-cli already installed and is the expected version"
echo ""
@@ -97,7 +96,7 @@ else
echo "error: failed to download Olares installer"
exit 1
else
echo "Olares installer ${CLI_VERSION} download complete!"
echo "Olares installer ${VERSION} download complete!"
echo ""
fi
fi

View File

@@ -145,6 +145,14 @@ if ! command_exists tar; then
exit 1
fi
export VERSION="#__VERSION__"
if [[ "x${VERSION}" == "x" || "x${VERSION:3}" == "xVERSION__" ]]; then
echo "error: Olares version is unspecified, please set the VERSION env var and rerun this script."
echo "for example: VERSION=1.12.0-20241124 bash $0"
exit 1
fi
BASE_DIR="$HOME/.olares"
if [ ! -d $BASE_DIR ]; then
mkdir -p $BASE_DIR
@@ -157,10 +165,9 @@ fi
set_master_host_ssh_options
CLI_VERSION="0.2.36"
CLI_FILE="olares-cli-v${CLI_VERSION}_linux_${ARCH}.tar.gz"
CLI_FILE="olares-cli-v${VERSION}_linux_${ARCH}.tar.gz"
if command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$CLI_VERSION" ]]; then
if command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$VERSION" ]]; then
INSTALL_OLARES_CLI=$(which olares-cli)
echo "olares-cli already installed and is the expected version"
echo ""
@@ -177,7 +184,7 @@ else
echo "error: failed to download Olares installer"
exit 1
else
echo "Olares installer ${CLI_VERSION} download complete!"
echo "Olares installer ${VERSION} download complete!"
echo ""
fi
fi

View File

@@ -36,6 +36,7 @@ if [ ! -z $VERSION ]; then
sh -c "$SED 's/#__VERSION__/${VERSION}/' wizard/config/settings/templates/terminus_cr.yaml"
sh -c "$SED 's/#__VERSION__/${VERSION}/' install.sh"
sh -c "$SED 's/#__VERSION__/${VERSION}/' install.ps1"
sh -c "$SED 's/#__VERSION__/${VERSION}/' joincluster.sh"
VERSION="v${VERSION}"
else
VERSION="debug"

41
cli/.goreleaser.yaml Normal file
View File

@@ -0,0 +1,41 @@
project_name: olares-cli
builds:
- env:
- CGO_ENABLED=0
binary: olares-cli
main: ./cmd/main.go
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm
- arm64
goarm:
- 7
ignore:
- goos: linux
goarch: arm64
- goos: darwin
goarch: arm
- goos: windows
goarch: arm
ldflags:
- -s
- -w
- -X bytetrade.io/web3os/installer/version.VERSION={{ .Version }}
dist: ./output
archives:
- id: olares-cli
name_template: "{{ .ProjectName }}-v{{ .Version }}_{{ .Os }}_{{ .Arch }}"
replacements:
linux: linux
amd64: amd64
arm: arm64
checksum:
name_template: "checksums.txt"
release:
disable: true
changelog:
skip: true

1
cli/README.md Executable file
View File

@@ -0,0 +1 @@
# installer

View File

@@ -0,0 +1,43 @@
/*
Copyright 2020 The KubeSphere Authors.
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 v1alpha1
type Addon struct {
Name string `yaml:"name" json:"name,omitempty"`
Namespace string `yaml:"namespace" json:"namespace,omitempty"`
Sources Sources `yaml:"sources" json:"sources,omitempty"`
Retries int `yaml:"retries" json:"retries,omitempty"`
Delay int `yaml:"delay" json:"delay,omitempty"`
}
type Sources struct {
Chart Chart `yaml:"chart" json:"chart,omitempty"`
Yaml Yaml `yaml:"yaml" json:"yaml,omitempty"`
}
type Chart struct {
Name string `yaml:"name" json:"name,omitempty"`
Repo string `yaml:"repo" json:"repo,omitempty"`
Path string `yaml:"path" json:"path,omitempty"`
Version string `yaml:"version" json:"version,omitempty"`
ValuesFile string `yaml:"valuesFile" json:"valuesFile,omitempty"`
Values []string `yaml:"values" json:"values,omitempty"`
}
type Yaml struct {
Path []string `yaml:"path" json:"path,omitempty"`
}

View File

@@ -0,0 +1,403 @@
/*
Copyright 2021.
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 v1alpha1
import (
"fmt"
"regexp"
"strconv"
"strings"
"bytetrade.io/web3os/installer/pkg/core/logger"
"bytetrade.io/web3os/installer/pkg/core/util"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// ClusterSpec defines the desired state of Cluster
type ClusterSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Foo is an example field of Cluster. Edit Cluster_types.go to remove/update
Hosts []HostCfg `yaml:"hosts" json:"hosts,omitempty"`
RoleGroups RoleGroups `yaml:"roleGroups" json:"roleGroups,omitempty"`
ControlPlaneEndpoint ControlPlaneEndpoint `yaml:"controlPlaneEndpoint" json:"controlPlaneEndpoint,omitempty"`
Kubernetes Kubernetes `yaml:"kubernetes" json:"kubernetes,omitempty"`
Network NetworkConfig `yaml:"network" json:"network,omitempty"`
Registry RegistryConfig `yaml:"registry" json:"registry,omitempty"`
Addons []Addon `yaml:"addons" json:"addons,omitempty"`
KubeSphere KubeSphere `json:"kubesphere,omitempty"`
}
// ClusterStatus defines the observed state of Cluster
type ClusterStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
JobInfo JobInfo `json:"jobInfo,omitempty"`
Version string `json:"version,omitempty"`
NetworkPlugin string `json:"networkPlugin,omitempty"`
NodesCount int `json:"nodesCount,omitempty"`
EtcdCount int `json:"etcdCount,omitempty"`
MasterCount int `json:"masterCount,omitempty"`
WorkerCount int `json:"workerCount,omitempty"`
Nodes []NodeStatus `json:"nodes,omitempty"`
Conditions []Condition `json:"Conditions,omitempty"`
}
// JobInfo defines the job information to be used to create a cluster or add a node.
type JobInfo struct {
Namespace string `json:"namespace,omitempty"`
Name string `json:"name,omitempty"`
Pods []PodInfo `json:"pods,omitempty"`
}
// PodInfo defines the pod information to be used to create a cluster or add a node.
type PodInfo struct {
Name string `json:"name,omitempty"`
Containers []ContainerInfo `json:"containers,omitempty"`
}
// ContainerInfo defines the container information to be used to create a cluster or add a node.
type ContainerInfo struct {
Name string `json:"name,omitempty"`
}
// NodeStatus defines the status information of the nodes in the cluster.
type NodeStatus struct {
InternalIP string `json:"internalIP,omitempty"`
Hostname string `json:"hostname,omitempty"`
Roles map[string]bool `json:"roles,omitempty"`
}
// Condition defines the process information.
type Condition struct {
Step string `json:"step,omitempty"`
StartTime metav1.Time `json:"startTime,omitempty"`
EndTime metav1.Time `json:"endTime,omitempty"`
Status bool `json:"status,omitempty"`
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// Cluster is the Schema for the clusters API
// +kubebuilder:resource:path=clusters,scope=Cluster
type Cluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ClusterSpec `json:"spec,omitempty"`
Status ClusterStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// ClusterList contains a list of Cluster
type ClusterList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Cluster `json:"items"`
}
func init() {
SchemeBuilder.Register(&Cluster{}, &ClusterList{})
}
// HostCfg defines host information for cluster.
type HostCfg struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Address string `yaml:"address,omitempty" json:"address,omitempty"`
InternalAddress string `yaml:"internalAddress,omitempty" json:"internalAddress,omitempty"`
Port int `yaml:"port,omitempty" json:"port,omitempty"`
User string `yaml:"user,omitempty" json:"user,omitempty"`
Password string `yaml:"password,omitempty" json:"password,omitempty"`
PrivateKey string `yaml:"privateKey,omitempty" json:"privateKey,omitempty"`
PrivateKeyPath string `yaml:"privateKeyPath,omitempty" json:"privateKeyPath,omitempty"`
Arch string `yaml:"arch,omitempty" json:"arch,omitempty"`
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
ID string `yaml:"id,omitempty" json:"id,omitempty"`
Index int `json:"-"`
IsEtcd bool `json:"-"`
IsMaster bool `json:"-"`
IsWorker bool `json:"-"`
EtcdExist bool `json:"-"`
EtcdName string `json:"-"`
}
// RoleGroups defines the grouping of role for hosts (etcd / master / worker).
type RoleGroups struct {
Etcd []string `yaml:"etcd" json:"etcd,omitempty"`
Master []string `yaml:"master" json:"master,omitempty"`
Worker []string `yaml:"worker" json:"worker,omitempty"`
}
// HostGroups defines the grouping of hosts for cluster (all / etcd / master / worker / k8s).
type HostGroups struct {
All []HostCfg
Etcd []HostCfg
Master []HostCfg
Worker []HostCfg
K8s []HostCfg
}
// ControlPlaneEndpoint defines the control plane endpoint information for cluster.
type ControlPlaneEndpoint struct {
InternalLoadbalancer string `yaml:"internalLoadbalancer" json:"internalLoadbalancer,omitempty"`
Domain string `yaml:"domain" json:"domain,omitempty"`
Address string `yaml:"address" json:"address,omitempty"`
Port int `yaml:"port" json:"port,omitempty"`
}
// RegistryConfig defines the configuration information of the image's repository.
type RegistryConfig struct {
RegistryMirrors []string `yaml:"registryMirrors" json:"registryMirrors,omitempty"`
InsecureRegistries []string `yaml:"insecureRegistries" json:"insecureRegistries,omitempty"`
PrivateRegistry string `yaml:"privateRegistry" json:"privateRegistry,omitempty"`
}
// KubeSphere defines the configuration information of the KubeSphere.
type KubeSphere struct {
Enabled bool `json:"enabled,omitempty"`
Version string `json:"version,omitempty"`
Configurations string `json:"configurations,omitempty"`
}
// ExternalEtcd defines configuration information of external etcd.
type ExternalEtcd struct {
Endpoints []string
CaFile string
CertFile string
KeyFile string
}
// Copy is used to create a copy for Runtime.
func (h *HostCfg) Copy() *HostCfg {
host := *h
return &host
}
// GenerateCertSANs is used to generate cert sans for cluster.
func (cfg *ClusterSpec) GenerateCertSANs() []string {
clusterSvc := fmt.Sprintf("kubernetes.default.svc.%s", cfg.Kubernetes.ClusterName)
defaultCertSANs := []string{"kubernetes", "kubernetes.default", "kubernetes.default.svc", clusterSvc, "localhost", "127.0.0.1"}
extraCertSANs := []string{}
extraCertSANs = append(extraCertSANs, cfg.ControlPlaneEndpoint.Domain)
extraCertSANs = append(extraCertSANs, cfg.ControlPlaneEndpoint.Address)
for _, host := range cfg.Hosts {
extraCertSANs = append(extraCertSANs, host.Name)
extraCertSANs = append(extraCertSANs, fmt.Sprintf("%s.%s", host.Name, cfg.Kubernetes.ClusterName))
if host.Address != cfg.ControlPlaneEndpoint.Address {
extraCertSANs = append(extraCertSANs, host.Address)
}
if host.InternalAddress != host.Address && host.InternalAddress != cfg.ControlPlaneEndpoint.Address {
extraCertSANs = append(extraCertSANs, host.InternalAddress)
}
}
extraCertSANs = append(extraCertSANs, util.ParseIp(cfg.Network.KubeServiceCIDR)[0])
defaultCertSANs = append(defaultCertSANs, extraCertSANs...)
if cfg.Kubernetes.ApiserverCertExtraSans != nil {
defaultCertSANs = append(defaultCertSANs, cfg.Kubernetes.ApiserverCertExtraSans...)
}
return defaultCertSANs
}
// GroupHosts is used to group hosts according to the configuration file.s
func (cfg *ClusterSpec) GroupHosts() (*HostGroups, error) {
clusterHostsGroups := HostGroups{}
hostList := map[string]string{}
for _, host := range cfg.Hosts {
hostList[host.Name] = host.Name
}
etcdGroup, masterGroup, workerGroup, err := cfg.ParseRolesList(hostList)
if err != nil {
return nil, err
}
for index, host := range cfg.Hosts {
host.Index = index
if len(etcdGroup) > 0 {
for _, hostName := range etcdGroup {
if host.Name == hostName {
host.IsEtcd = true
break
}
}
}
if len(masterGroup) > 0 {
for _, hostName := range masterGroup {
if host.Name == hostName {
host.IsMaster = true
break
}
}
}
if len(workerGroup) > 0 {
for _, hostName := range workerGroup {
if hostName != "" && host.Name == hostName {
host.IsWorker = true
break
}
}
}
if host.IsEtcd {
clusterHostsGroups.Etcd = append(clusterHostsGroups.Etcd, host)
}
if host.IsMaster {
clusterHostsGroups.Master = append(clusterHostsGroups.Master, host)
}
if host.IsWorker {
clusterHostsGroups.Worker = append(clusterHostsGroups.Worker, host)
}
if host.IsMaster || host.IsWorker {
clusterHostsGroups.K8s = append(clusterHostsGroups.K8s, host)
}
clusterHostsGroups.All = append(clusterHostsGroups.All, host)
}
//Check that the parameters under roleGroups are incorrect
if len(masterGroup) == 0 {
logger.Fatal(errors.New("The number of master cannot be 0"))
}
if len(etcdGroup) == 0 {
logger.Fatal(errors.New("The number of etcd cannot be 0"))
}
if len(masterGroup) != len(clusterHostsGroups.Master) {
return nil, errors.New("Incorrect nodeName under roleGroups/master in the configuration file")
}
if len(etcdGroup) != len(clusterHostsGroups.Etcd) {
return nil, errors.New("Incorrect nodeName under roleGroups/etcd in the configuration file")
}
if len(workerGroup) != len(clusterHostsGroups.Worker) {
return nil, errors.New("Incorrect nodeName under roleGroups/work in the configuration file")
}
return &clusterHostsGroups, nil
}
// ClusterIP is used to get the kube-apiserver service address inside the cluster.
func (cfg *ClusterSpec) ClusterIP() string {
return util.ParseIp(cfg.Network.KubeServiceCIDR)[0]
}
// CorednsClusterIP is used to get the coredns service address inside the cluster.
func (cfg *ClusterSpec) CorednsClusterIP() string {
return util.ParseIp(cfg.Network.KubeServiceCIDR)[2]
}
// ClusterDNS is used to get the dns server address inside the cluster.
func (cfg *ClusterSpec) ClusterDNS() string {
if cfg.Kubernetes.EnableNodelocaldns() {
return "169.254.25.10"
}
return cfg.CorednsClusterIP()
}
// ParseRolesList is used to parse the host grouping list.
func (cfg *ClusterSpec) ParseRolesList(hostList map[string]string) ([]string, []string, []string, error) {
etcdGroupList := []string{}
masterGroupList := []string{}
workerGroupList := []string{}
for _, host := range cfg.RoleGroups.Etcd {
if strings.Contains(host, "[") && strings.Contains(host, "]") && strings.Contains(host, ":") {
etcdGroupList = append(etcdGroupList, getHostsRange(host, hostList, "etcd")...)
} else {
if err := hostVerify(hostList, host, "etcd"); err != nil {
logger.Fatal(err)
}
etcdGroupList = append(etcdGroupList, host)
}
}
for _, host := range cfg.RoleGroups.Master {
if strings.Contains(host, "[") && strings.Contains(host, "]") && strings.Contains(host, ":") {
masterGroupList = append(masterGroupList, getHostsRange(host, hostList, "master")...)
} else {
if err := hostVerify(hostList, host, "master"); err != nil {
logger.Fatal(err)
}
masterGroupList = append(masterGroupList, host)
}
}
for _, host := range cfg.RoleGroups.Worker {
if strings.Contains(host, "[") && strings.Contains(host, "]") && strings.Contains(host, ":") {
workerGroupList = append(workerGroupList, getHostsRange(host, hostList, "worker")...)
} else {
if err := hostVerify(hostList, host, "worker"); err != nil {
logger.Fatal(err)
}
workerGroupList = append(workerGroupList, host)
}
}
return etcdGroupList, masterGroupList, workerGroupList, nil
}
func getHostsRange(rangeStr string, hostList map[string]string, group string) []string {
hostRangeList := []string{}
r := regexp.MustCompile(`\[(\d+)\:(\d+)\]`)
nameSuffix := r.FindStringSubmatch(rangeStr)
namePrefix := strings.Split(rangeStr, nameSuffix[0])[0]
nameSuffixStart, _ := strconv.Atoi(nameSuffix[1])
nameSuffixEnd, _ := strconv.Atoi(nameSuffix[2])
for i := nameSuffixStart; i <= nameSuffixEnd; i++ {
if err := hostVerify(hostList, fmt.Sprintf("%s%d", namePrefix, i), group); err != nil {
logger.Fatal(err)
}
hostRangeList = append(hostRangeList, fmt.Sprintf("%s%d", namePrefix, i))
}
return hostRangeList
}
func hostVerify(hostList map[string]string, hostName string, group string) error {
if _, ok := hostList[hostName]; !ok {
return fmt.Errorf("[%s] is in [%s] group, but not in hosts list", hostName, group)
}
return nil
}
const (
Haproxy = "haproxy"
)
func (c ControlPlaneEndpoint) IsInternalLBEnabled() bool {
if c.InternalLoadbalancer == Haproxy {
return true
}
return false
}

View File

@@ -0,0 +1,276 @@
/*
Copyright 2020 The KubeSphere Authors.
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 v1alpha1
import (
"fmt"
"os"
"strings"
"bytetrade.io/web3os/installer/pkg/core/util"
)
const (
DefaultPreDir = "kubekey"
DefaultTmpDir = "/tmp/kubekey"
DefaultSSHPort = 22
DefaultLBPort = 6443
DefaultLBDomain = "lb.kubesphere.local"
DefaultNetworkPlugin = "calico"
DefaultPodsCIDR = "10.233.64.0/18"
DefaultServiceCIDR = "10.233.0.0/18"
DefaultKubeImageNamespace = "kubesphere"
DefaultClusterName = "cluster.local"
DefaultArch = "amd64"
DefaultEtcdVersion = "v3.4.13"
DefaultEtcdPort = "2379"
DefaultDockerVersion = "20.10.8"
DefaultCrictlVersion = "v1.22.0"
DefaultKubeVersion = "v1.21.5"
DefaultCalicoVersion = "v3.20.0"
DefaultFlannelVersion = "v0.12.0"
DefaultCniVersion = "v0.9.1"
DefaultCiliumVersion = "v1.8.3"
DefaultKubeovnVersion = "v1.5.0"
DefaultHelmVersion = "v3.6.3"
DefaultMaxPods = 200
DefaultNodeCidrMaskSize = 24
DefaultIPIPMode = "Always"
DefaultVXLANMode = "Never"
DefaultVethMTU = 1440
DefaultBackendMode = "vxlan"
DefaultProxyMode = "ipvs"
DefaultCrioEndpoint = "unix:///var/run/crio/crio.sock"
DefaultContainerdEndpoint = "unix:///run/containerd/containerd.sock"
DefaultIsulaEndpoint = "unix:///var/run/isulad.sock"
Etcd = "etcd"
Master = "master"
Worker = "worker"
K8s = "k8s"
DefaultEtcdBackupDir = "/var/backups/kube_etcd"
DefaultEtcdBackupPeriod = 30
DefaultKeepBackNumber = 5
DefaultEtcdBackupScriptDir = "/usr/local/bin/kube-scripts"
DefaultJoinCIDR = "100.64.0.0/16"
DefaultNetworkType = "geneve"
DefaultVlanID = "100"
DefaultOvnLabel = "node-role.kubernetes.io/control-plane"
DefaultDPDKVersion = "19.11"
DefaultDNSAddress = "114.114.114.114"
Docker = "docker"
Containerd = "containerd"
Crio = "crio"
Isula = "isula"
)
func (cfg *ClusterSpec) SetDefaultClusterSpec(incluster bool) (*ClusterSpec, *HostGroups, error) {
clusterCfg := ClusterSpec{}
clusterCfg.Hosts = SetDefaultHostsCfg(cfg)
clusterCfg.RoleGroups = cfg.RoleGroups
hostGroups, err := clusterCfg.GroupHosts()
if err != nil {
return nil, nil, err
}
clusterCfg.ControlPlaneEndpoint = SetDefaultLBCfg(cfg, hostGroups.Master, incluster)
clusterCfg.Network = SetDefaultNetworkCfg(cfg)
clusterCfg.Kubernetes = SetDefaultClusterCfg(cfg)
clusterCfg.Registry = cfg.Registry
clusterCfg.Addons = cfg.Addons
clusterCfg.KubeSphere = cfg.KubeSphere
if cfg.Kubernetes.ClusterName == "" {
clusterCfg.Kubernetes.ClusterName = DefaultClusterName
}
if cfg.Kubernetes.Version == "" {
clusterCfg.Kubernetes.Version = DefaultKubeVersion
}
if cfg.Kubernetes.MaxPods == 0 {
clusterCfg.Kubernetes.MaxPods = DefaultMaxPods
}
if cfg.Kubernetes.NodeCidrMaskSize == 0 {
clusterCfg.Kubernetes.NodeCidrMaskSize = DefaultNodeCidrMaskSize
}
if cfg.Kubernetes.ProxyMode == "" {
clusterCfg.Kubernetes.ProxyMode = DefaultProxyMode
}
return &clusterCfg, hostGroups, nil
}
func SetDefaultHostsCfg(cfg *ClusterSpec) []HostCfg {
var hostscfg []HostCfg
if len(cfg.Hosts) == 0 {
return nil
}
for _, host := range cfg.Hosts {
if len(host.Address) == 0 && len(host.InternalAddress) > 0 {
host.Address = host.InternalAddress
}
if len(host.InternalAddress) == 0 && len(host.Address) > 0 {
host.InternalAddress = host.Address
}
if host.User == "" {
host.User = "root"
}
if host.Port == 0 {
host.Port = DefaultSSHPort
}
if host.PrivateKey == "" {
if host.Password == "" && host.PrivateKeyPath == "" {
host.PrivateKeyPath = "~/.ssh/id_rsa"
}
if host.PrivateKeyPath != "" && strings.HasPrefix(strings.TrimSpace(host.PrivateKeyPath), "~/") {
homeDir, _ := util.Home()
host.PrivateKeyPath = strings.Replace(host.PrivateKeyPath, "~/", fmt.Sprintf("%s/", homeDir), 1)
}
}
if host.Arch == "" {
host.Arch = DefaultArch
}
hostscfg = append(hostscfg, host)
}
return hostscfg
}
func SetDefaultLBCfg(cfg *ClusterSpec, masterGroup []HostCfg, incluster bool) ControlPlaneEndpoint {
if !incluster {
//The detection is not an HA environment, and the address at LB does not need input
if len(masterGroup) == 1 && cfg.ControlPlaneEndpoint.Address != "" {
fmt.Println("When the environment is not HA, the LB address does not need to be entered, so delete the corresponding value.")
os.Exit(0)
}
//Check whether LB should be configured
if len(masterGroup) >= 3 && !cfg.ControlPlaneEndpoint.IsInternalLBEnabled() && cfg.ControlPlaneEndpoint.Address == "" {
fmt.Println("When the environment has at least three masters, You must set the value of the LB address or enable the internal loadbalancer.")
os.Exit(0)
}
// Check whether LB address and the internal LB are both enabled
if cfg.ControlPlaneEndpoint.IsInternalLBEnabled() && cfg.ControlPlaneEndpoint.Address != "" {
fmt.Println("You cannot set up the internal load balancer and the LB address at the same time.")
os.Exit(0)
}
}
if cfg.ControlPlaneEndpoint.Address == "" || cfg.ControlPlaneEndpoint.Address == "127.0.0.1" {
cfg.ControlPlaneEndpoint.Address = masterGroup[0].InternalAddress
}
if cfg.ControlPlaneEndpoint.Domain == "" {
cfg.ControlPlaneEndpoint.Domain = DefaultLBDomain
}
if cfg.ControlPlaneEndpoint.Port == 0 {
cfg.ControlPlaneEndpoint.Port = DefaultLBPort
}
defaultLbCfg := cfg.ControlPlaneEndpoint
return defaultLbCfg
}
func SetDefaultNetworkCfg(cfg *ClusterSpec) NetworkConfig {
if cfg.Network.Plugin == "" {
cfg.Network.Plugin = DefaultNetworkPlugin
}
if cfg.Network.KubePodsCIDR == "" {
cfg.Network.KubePodsCIDR = DefaultPodsCIDR
}
if cfg.Network.KubeServiceCIDR == "" {
cfg.Network.KubeServiceCIDR = DefaultServiceCIDR
}
if cfg.Network.Calico.IPIPMode == "" {
cfg.Network.Calico.IPIPMode = DefaultIPIPMode
}
if cfg.Network.Calico.VXLANMode == "" {
cfg.Network.Calico.VXLANMode = DefaultVXLANMode
}
if cfg.Network.Calico.VethMTU == 0 {
cfg.Network.Calico.VethMTU = DefaultVethMTU
}
if cfg.Network.Flannel.BackendMode == "" {
cfg.Network.Flannel.BackendMode = DefaultBackendMode
}
// kube-ovn default config
if cfg.Network.Kubeovn.JoinCIDR == "" {
cfg.Network.Kubeovn.JoinCIDR = DefaultJoinCIDR
}
if cfg.Network.Kubeovn.Label == "" {
cfg.Network.Kubeovn.Label = DefaultOvnLabel
}
if cfg.Network.Kubeovn.VlanID == "" {
cfg.Network.Kubeovn.VlanID = DefaultVlanID
}
if cfg.Network.Kubeovn.NetworkType == "" {
cfg.Network.Kubeovn.NetworkType = DefaultNetworkType
}
if cfg.Network.Kubeovn.PingerExternalAddress == "" {
cfg.Network.Kubeovn.PingerExternalAddress = DefaultDNSAddress
}
if cfg.Network.Kubeovn.DpdkVersion == "" {
cfg.Network.Kubeovn.DpdkVersion = DefaultDPDKVersion
}
defaultNetworkCfg := cfg.Network
return defaultNetworkCfg
}
func SetDefaultClusterCfg(cfg *ClusterSpec) Kubernetes {
if cfg.Kubernetes.Version == "" {
cfg.Kubernetes.Version = DefaultKubeVersion
} else {
s := strings.Split(cfg.Kubernetes.Version, "-")
if len(s) > 1 {
cfg.Kubernetes.Version = s[0]
cfg.Kubernetes.Type = s[1]
}
}
if cfg.Kubernetes.ClusterName == "" {
cfg.Kubernetes.ClusterName = DefaultClusterName
}
if cfg.Kubernetes.EtcdBackupDir == "" {
cfg.Kubernetes.EtcdBackupDir = DefaultEtcdBackupDir
}
if cfg.Kubernetes.EtcdBackupPeriod == 0 {
cfg.Kubernetes.EtcdBackupPeriod = DefaultEtcdBackupPeriod
}
if cfg.Kubernetes.KeepBackupNumber == 0 {
cfg.Kubernetes.KeepBackupNumber = DefaultKeepBackNumber
}
if cfg.Kubernetes.EtcdBackupScriptDir == "" {
cfg.Kubernetes.EtcdBackupScriptDir = DefaultEtcdBackupScriptDir
}
if cfg.Kubernetes.ContainerManager == "" {
cfg.Kubernetes.ContainerManager = Docker
}
if cfg.Kubernetes.ContainerRuntimeEndpoint == "" {
switch cfg.Kubernetes.ContainerManager {
case Docker:
cfg.Kubernetes.ContainerRuntimeEndpoint = ""
case Crio:
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultCrioEndpoint
case Containerd:
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultContainerdEndpoint
case Isula:
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultIsulaEndpoint
default:
cfg.Kubernetes.ContainerRuntimeEndpoint = ""
}
}
defaultClusterCfg := cfg.Kubernetes
return defaultClusterCfg
}

View File

@@ -0,0 +1,43 @@
/*
Copyright 2021.
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 v1alpha1 contains API Schema definitions for the kubekey v1alpha1 API group
// +kubebuilder:object:generate=true
// +groupName=kubekey.kubesphere.io
package v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = GroupVersion
var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "kubekey.kubesphere.io", Version: "v1alpha1"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
func Resource(resource string) schema.GroupResource {
return GroupVersion.WithResource(resource).GroupResource()
}

View File

@@ -0,0 +1,53 @@
/*
Copyright 2020 The KubeSphere Authors.
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 v1alpha1
import "k8s.io/apimachinery/pkg/runtime"
type Kubernetes struct {
Type string `yaml:"type" json:"type,omitempty"`
Version string `yaml:"version" json:"version,omitempty"`
ClusterName string `yaml:"clusterName" json:"clusterName,omitempty"`
MasqueradeAll bool `yaml:"masqueradeAll" json:"masqueradeAll,omitempty"`
MaxPods int `yaml:"maxPods" json:"maxPods,omitempty"`
NodeCidrMaskSize int `yaml:"nodeCidrMaskSize" json:"nodeCidrMaskSize,omitempty"`
ApiserverCertExtraSans []string `yaml:"apiserverCertExtraSans" json:"apiserverCertExtraSans,omitempty"`
ProxyMode string `yaml:"proxyMode" json:"proxyMode,omitempty"`
// +optional
Nodelocaldns *bool `yaml:"nodelocaldns" json:"nodelocaldns,omitempty"`
EtcdBackupDir string `yaml:"etcdBackupDir" json:"etcdBackupDir,omitempty"`
EtcdBackupPeriod int `yaml:"etcdBackupPeriod" json:"etcdBackupPeriod,omitempty"`
KeepBackupNumber int `yaml:"keepBackupNumber" json:"keepBackupNumber,omitempty"`
EtcdBackupScriptDir string `yaml:"etcdBackupScript" json:"etcdBackupScript,omitempty"`
ContainerManager string `yaml:"containerManager" json:"containerManager,omitempty"`
ContainerRuntimeEndpoint string `yaml:"containerRuntimeEndpoint" json:"containerRuntimeEndpoint,omitempty"`
ApiServerArgs []string `yaml:"apiserverArgs" json:"apiserverArgs,omitempty"`
ControllerManagerArgs []string `yaml:"controllerManagerArgs" json:"controllerManagerArgs,omitempty"`
SchedulerArgs []string `yaml:"schedulerArgs" json:"schedulerArgs,omitempty"`
KubeletArgs []string `yaml:"kubeletArgs" json:"kubeletArgs,omitempty"`
KubeProxyArgs []string `yaml:"kubeProxyArgs" json:"kubeProxyArgs,omitempty"`
KubeletConfiguration runtime.RawExtension `yaml:"kubeletConfiguration" json:"kubeletConfiguration,omitempty"`
KubeProxyConfiguration runtime.RawExtension `yaml:"kubeProxyConfiguration" json:"kubeProxyConfiguration,omitempty"`
}
// EnableNodelocaldns is used to determine whether to deploy nodelocaldns.
func (k *Kubernetes) EnableNodelocaldns() bool {
if k.Nodelocaldns == nil {
return true
}
return *k.Nodelocaldns
}

View File

@@ -0,0 +1,53 @@
/*
Copyright 2020 The KubeSphere Authors.
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 v1alpha1
type NetworkConfig struct {
Plugin string `yaml:"plugin" json:"plugin,omitempty"`
KubePodsCIDR string `yaml:"kubePodsCIDR" json:"kubePodsCIDR,omitempty"`
KubeServiceCIDR string `yaml:"kubeServiceCIDR" json:"kubeServiceCIDR,omitempty"`
Calico CalicoCfg `yaml:"calico" json:"calico,omitempty"`
Flannel FlannelCfg `yaml:"flannel" json:"flannel,omitempty"`
Kubeovn KubeovnCfg `yaml:"kubeovn" json:"kubeovn,omitempty"`
}
type CalicoCfg struct {
IPIPMode string `yaml:"ipipMode" json:"ipipMode,omitempty"`
VXLANMode string `yaml:"vxlanMode" json:"vxlanMode,omitempty"`
VethMTU int `yaml:"vethMTU" json:"vethMTU,omitempty"`
}
type FlannelCfg struct {
BackendMode string `yaml:"backendMode" json:"backendMode,omitempty"`
Directrouting bool `yaml:"directRouting" json:"directRouting,omitempty"`
}
type KubeovnCfg struct {
JoinCIDR string `yaml:"joinCIDR" json:"joinCIDR,omitempty"`
NetworkType string `yaml:"networkType" json:"networkType,omitempty"`
Label string `yaml:"label" json:"label,omitempty"`
Iface string `yaml:"iface" json:"iface,omitempty"`
VlanInterfaceName string `yaml:"vlanInterfaceName" json:"vlanInterfaceName,omitempty"`
VlanID string `yaml:"vlanID" json:"vlanID,omitempty"`
DpdkMode bool `yaml:"dpdkMode" json:"dpdkMode,omitempty"`
EnableSSL bool `yaml:"enableSSL" json:"enableSSL,omitempty"`
EnableMirror bool `yaml:"enableMirror" json:"enableMirror,omitempty"`
HwOffload bool `yaml:"hwOffload" json:"hwOffload,omitempty"`
DpdkVersion string `yaml:"dpdkVersion" json:"dpdkVersion,omitempty"`
PingerExternalAddress string `yaml:"pingerExternalAddress" json:"pingerExternalAddress,omitempty"`
PingerExternalDomain string `yaml:"pingerExternalDomain" json:"pingerExternalDomain,omitempty"`
}

View File

@@ -0,0 +1,611 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by controller-gen. DO NOT EDIT.
package v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Addon) DeepCopyInto(out *Addon) {
*out = *in
in.Sources.DeepCopyInto(&out.Sources)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Addon.
func (in *Addon) DeepCopy() *Addon {
if in == nil {
return nil
}
out := new(Addon)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CalicoCfg) DeepCopyInto(out *CalicoCfg) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CalicoCfg.
func (in *CalicoCfg) DeepCopy() *CalicoCfg {
if in == nil {
return nil
}
out := new(CalicoCfg)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Chart) DeepCopyInto(out *Chart) {
*out = *in
if in.Values != nil {
in, out := &in.Values, &out.Values
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Chart.
func (in *Chart) DeepCopy() *Chart {
if in == nil {
return nil
}
out := new(Chart)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Cluster) DeepCopyInto(out *Cluster) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster.
func (in *Cluster) DeepCopy() *Cluster {
if in == nil {
return nil
}
out := new(Cluster)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Cluster) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterList) DeepCopyInto(out *ClusterList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Cluster, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList.
func (in *ClusterList) DeepCopy() *ClusterList {
if in == nil {
return nil
}
out := new(ClusterList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ClusterList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
*out = *in
if in.Hosts != nil {
in, out := &in.Hosts, &out.Hosts
*out = make([]HostCfg, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
in.RoleGroups.DeepCopyInto(&out.RoleGroups)
out.ControlPlaneEndpoint = in.ControlPlaneEndpoint
in.Kubernetes.DeepCopyInto(&out.Kubernetes)
out.Network = in.Network
in.Registry.DeepCopyInto(&out.Registry)
if in.Addons != nil {
in, out := &in.Addons, &out.Addons
*out = make([]Addon, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
out.KubeSphere = in.KubeSphere
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec.
func (in *ClusterSpec) DeepCopy() *ClusterSpec {
if in == nil {
return nil
}
out := new(ClusterSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) {
*out = *in
in.JobInfo.DeepCopyInto(&out.JobInfo)
if in.Nodes != nil {
in, out := &in.Nodes, &out.Nodes
*out = make([]NodeStatus, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus.
func (in *ClusterStatus) DeepCopy() *ClusterStatus {
if in == nil {
return nil
}
out := new(ClusterStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Condition) DeepCopyInto(out *Condition) {
*out = *in
in.StartTime.DeepCopyInto(&out.StartTime)
in.EndTime.DeepCopyInto(&out.EndTime)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
func (in *Condition) DeepCopy() *Condition {
if in == nil {
return nil
}
out := new(Condition)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ContainerInfo) DeepCopyInto(out *ContainerInfo) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerInfo.
func (in *ContainerInfo) DeepCopy() *ContainerInfo {
if in == nil {
return nil
}
out := new(ContainerInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ControlPlaneEndpoint) DeepCopyInto(out *ControlPlaneEndpoint) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneEndpoint.
func (in *ControlPlaneEndpoint) DeepCopy() *ControlPlaneEndpoint {
if in == nil {
return nil
}
out := new(ControlPlaneEndpoint)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalEtcd) DeepCopyInto(out *ExternalEtcd) {
*out = *in
if in.Endpoints != nil {
in, out := &in.Endpoints, &out.Endpoints
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalEtcd.
func (in *ExternalEtcd) DeepCopy() *ExternalEtcd {
if in == nil {
return nil
}
out := new(ExternalEtcd)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlannelCfg) DeepCopyInto(out *FlannelCfg) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlannelCfg.
func (in *FlannelCfg) DeepCopy() *FlannelCfg {
if in == nil {
return nil
}
out := new(FlannelCfg)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostCfg) DeepCopyInto(out *HostCfg) {
*out = *in
if in.Labels != nil {
in, out := &in.Labels, &out.Labels
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostCfg.
func (in *HostCfg) DeepCopy() *HostCfg {
if in == nil {
return nil
}
out := new(HostCfg)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostGroups) DeepCopyInto(out *HostGroups) {
*out = *in
if in.All != nil {
in, out := &in.All, &out.All
*out = make([]HostCfg, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Etcd != nil {
in, out := &in.Etcd, &out.Etcd
*out = make([]HostCfg, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Master != nil {
in, out := &in.Master, &out.Master
*out = make([]HostCfg, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Worker != nil {
in, out := &in.Worker, &out.Worker
*out = make([]HostCfg, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.K8s != nil {
in, out := &in.K8s, &out.K8s
*out = make([]HostCfg, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostGroups.
func (in *HostGroups) DeepCopy() *HostGroups {
if in == nil {
return nil
}
out := new(HostGroups)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JobInfo) DeepCopyInto(out *JobInfo) {
*out = *in
if in.Pods != nil {
in, out := &in.Pods, &out.Pods
*out = make([]PodInfo, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobInfo.
func (in *JobInfo) DeepCopy() *JobInfo {
if in == nil {
return nil
}
out := new(JobInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeSphere) DeepCopyInto(out *KubeSphere) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeSphere.
func (in *KubeSphere) DeepCopy() *KubeSphere {
if in == nil {
return nil
}
out := new(KubeSphere)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeovnCfg) DeepCopyInto(out *KubeovnCfg) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeovnCfg.
func (in *KubeovnCfg) DeepCopy() *KubeovnCfg {
if in == nil {
return nil
}
out := new(KubeovnCfg)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Kubernetes) DeepCopyInto(out *Kubernetes) {
*out = *in
if in.ApiserverCertExtraSans != nil {
in, out := &in.ApiserverCertExtraSans, &out.ApiserverCertExtraSans
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Nodelocaldns != nil {
in, out := &in.Nodelocaldns, &out.Nodelocaldns
*out = new(bool)
**out = **in
}
if in.ApiServerArgs != nil {
in, out := &in.ApiServerArgs, &out.ApiServerArgs
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ControllerManagerArgs != nil {
in, out := &in.ControllerManagerArgs, &out.ControllerManagerArgs
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.SchedulerArgs != nil {
in, out := &in.SchedulerArgs, &out.SchedulerArgs
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.KubeletArgs != nil {
in, out := &in.KubeletArgs, &out.KubeletArgs
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.KubeProxyArgs != nil {
in, out := &in.KubeProxyArgs, &out.KubeProxyArgs
*out = make([]string, len(*in))
copy(*out, *in)
}
in.KubeletConfiguration.DeepCopyInto(&out.KubeletConfiguration)
in.KubeProxyConfiguration.DeepCopyInto(&out.KubeProxyConfiguration)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Kubernetes.
func (in *Kubernetes) DeepCopy() *Kubernetes {
if in == nil {
return nil
}
out := new(Kubernetes)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NetworkConfig) DeepCopyInto(out *NetworkConfig) {
*out = *in
out.Calico = in.Calico
out.Flannel = in.Flannel
out.Kubeovn = in.Kubeovn
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkConfig.
func (in *NetworkConfig) DeepCopy() *NetworkConfig {
if in == nil {
return nil
}
out := new(NetworkConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeStatus) DeepCopyInto(out *NodeStatus) {
*out = *in
if in.Roles != nil {
in, out := &in.Roles, &out.Roles
*out = make(map[string]bool, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeStatus.
func (in *NodeStatus) DeepCopy() *NodeStatus {
if in == nil {
return nil
}
out := new(NodeStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodInfo) DeepCopyInto(out *PodInfo) {
*out = *in
if in.Containers != nil {
in, out := &in.Containers, &out.Containers
*out = make([]ContainerInfo, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfo.
func (in *PodInfo) DeepCopy() *PodInfo {
if in == nil {
return nil
}
out := new(PodInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RegistryConfig) DeepCopyInto(out *RegistryConfig) {
*out = *in
if in.RegistryMirrors != nil {
in, out := &in.RegistryMirrors, &out.RegistryMirrors
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.InsecureRegistries != nil {
in, out := &in.InsecureRegistries, &out.InsecureRegistries
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryConfig.
func (in *RegistryConfig) DeepCopy() *RegistryConfig {
if in == nil {
return nil
}
out := new(RegistryConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RoleGroups) DeepCopyInto(out *RoleGroups) {
*out = *in
if in.Etcd != nil {
in, out := &in.Etcd, &out.Etcd
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Master != nil {
in, out := &in.Master, &out.Master
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Worker != nil {
in, out := &in.Worker, &out.Worker
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleGroups.
func (in *RoleGroups) DeepCopy() *RoleGroups {
if in == nil {
return nil
}
out := new(RoleGroups)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Sources) DeepCopyInto(out *Sources) {
*out = *in
in.Chart.DeepCopyInto(&out.Chart)
in.Yaml.DeepCopyInto(&out.Yaml)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Sources.
func (in *Sources) DeepCopy() *Sources {
if in == nil {
return nil
}
out := new(Sources)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Yaml) DeepCopyInto(out *Yaml) {
*out = *in
if in.Path != nil {
in, out := &in.Path, &out.Path
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Yaml.
func (in *Yaml) DeepCopy() *Yaml {
if in == nil {
return nil
}
out := new(Yaml)
in.DeepCopyInto(out)
return out
}

View File

@@ -0,0 +1,43 @@
/*
Copyright 2021 The KubeSphere Authors.
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 v1alpha2
type Addon struct {
Name string `yaml:"name" json:"name,omitempty"`
Namespace string `yaml:"namespace" json:"namespace,omitempty"`
Sources Sources `yaml:"sources" json:"sources,omitempty"`
Retries int `yaml:"retries" json:"retries,omitempty"`
Delay int `yaml:"delay" json:"delay,omitempty"`
}
type Sources struct {
Chart Chart `yaml:"chart" json:"chart,omitempty"`
Yaml Yaml `yaml:"yaml" json:"yaml,omitempty"`
}
type Chart struct {
Name string `yaml:"name" json:"name,omitempty"`
Repo string `yaml:"repo" json:"repo,omitempty"`
Path string `yaml:"path" json:"path,omitempty"`
Version string `yaml:"version" json:"version,omitempty"`
ValuesFile string `yaml:"valuesFile" json:"valuesFile,omitempty"`
Values []string `yaml:"values" json:"values,omitempty"`
}
type Yaml struct {
Path []string `yaml:"path" json:"path,omitempty"`
}

View File

@@ -0,0 +1,364 @@
/*
Copyright 2021 The KubeSphere Authors.
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 v1alpha2
import (
"fmt"
"regexp"
"strconv"
"strings"
"bytetrade.io/web3os/installer/pkg/core/connector"
"bytetrade.io/web3os/installer/pkg/core/logger"
"bytetrade.io/web3os/installer/pkg/core/util"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// ClusterSpec defines the desired state of Cluster
type ClusterSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Foo is an example field of Cluster. Edit Cluster_types.go to remove/update
Hosts []HostCfg `yaml:"hosts" json:"hosts,omitempty"`
RoleGroups map[string][]string `yaml:"roleGroups" json:"roleGroups,omitempty"`
ControlPlaneEndpoint ControlPlaneEndpoint `yaml:"controlPlaneEndpoint" json:"controlPlaneEndpoint,omitempty"`
System System `yaml:"system" json:"system,omitempty"`
Etcd EtcdCluster `yaml:"etcd" json:"etcd,omitempty"`
Kubernetes Kubernetes `yaml:"kubernetes" json:"kubernetes,omitempty"`
Network NetworkConfig `yaml:"network" json:"network,omitempty"`
Registry RegistryConfig `yaml:"registry" json:"registry,omitempty"`
Addons []Addon `yaml:"addons" json:"addons,omitempty"`
KubeSphere KubeSphere `json:"kubesphere,omitempty"`
}
// ClusterStatus defines the observed state of Cluster
type ClusterStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
JobInfo JobInfo `json:"jobInfo,omitempty"`
PiplineInfo PiplineInfo `json:"piplineInfo,omitempty"`
Version string `json:"version,omitempty"`
NetworkPlugin string `json:"networkPlugin,omitempty"`
NodesCount int `json:"nodesCount,omitempty"`
EtcdCount int `json:"etcdCount,omitempty"`
MasterCount int `json:"masterCount,omitempty"`
WorkerCount int `json:"workerCount,omitempty"`
Nodes []NodeStatus `json:"nodes,omitempty"`
Conditions []Condition `json:"Conditions,omitempty"`
}
// JobInfo defines the job information to be used to create a cluster or add a node.
type JobInfo struct {
Namespace string `json:"namespace,omitempty"`
Name string `json:"name,omitempty"`
Pods []PodInfo `json:"pods,omitempty"`
}
// PodInfo defines the pod information to be used to create a cluster or add a node.
type PodInfo struct {
Name string `json:"name,omitempty"`
Containers []ContainerInfo `json:"containers,omitempty"`
}
// ContainerInfo defines the container information to be used to create a cluster or add a node.
type ContainerInfo struct {
Name string `json:"name,omitempty"`
}
// PiplineInfo define the pipline information for operating cluster.
type PiplineInfo struct {
// Running or Terminated
Status string `json:"status,omitempty"`
}
// NodeStatus defines the status information of the nodes in the cluster.
type NodeStatus struct {
InternalIP string `json:"internalIP,omitempty"`
Hostname string `json:"hostname,omitempty"`
Roles map[string]bool `json:"roles,omitempty"`
}
// Condition defines the process information.
type Condition struct {
Step string `json:"step,omitempty"`
StartTime metav1.Time `json:"startTime,omitempty"`
EndTime metav1.Time `json:"endTime,omitempty"`
Status bool `json:"status,omitempty"`
Events map[string]Event `json:"event,omitempty"`
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:subresource:status
// Cluster is the Schema for the clusters API
// +kubebuilder:resource:path=clusters,scope=Cluster
type Cluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ClusterSpec `json:"spec,omitempty"`
Status ClusterStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// ClusterList contains a list of Cluster
type ClusterList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Cluster `json:"items"`
}
func init() {
SchemeBuilder.Register(&Cluster{}, &ClusterList{})
}
// HostCfg defines host information for cluster.
type HostCfg struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Address string `yaml:"address,omitempty" json:"address,omitempty"`
InternalAddress string `yaml:"internalAddress,omitempty" json:"internalAddress,omitempty"`
Port int `yaml:"port,omitempty" json:"port,omitempty"`
User string `yaml:"user,omitempty" json:"user,omitempty"`
Password string `yaml:"password,omitempty" json:"password,omitempty"`
PrivateKey string `yaml:"privateKey,omitempty" json:"privateKey,omitempty"`
PrivateKeyPath string `yaml:"privateKeyPath,omitempty" json:"privateKeyPath,omitempty"`
Arch string `yaml:"arch,omitempty" json:"arch,omitempty"`
Timeout *int64 `yaml:"timeout,omitempty" json:"timeout,omitempty"`
// Labels defines the kubernetes labels for the node.
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
}
// ControlPlaneEndpoint defines the control plane endpoint information for cluster.
type ControlPlaneEndpoint struct {
InternalLoadbalancer string `yaml:"internalLoadbalancer" json:"internalLoadbalancer,omitempty"`
Domain string `yaml:"domain" json:"domain,omitempty"`
Address string `yaml:"address" json:"address,omitempty"`
Port int `yaml:"port" json:"port,omitempty"`
KubeVip KubeVip `yaml:"kubevip" json:"kubevip,omitempty"`
}
type KubeVip struct {
Mode string `yaml:"mode" json:"mode,omitempty"`
}
// System defines the system config for each node in cluster.
type System struct {
NtpServers []string `yaml:"ntpServers" json:"ntpServers,omitempty"`
Timezone string `yaml:"timezone" json:"timezone,omitempty"`
Rpms []string `yaml:"rpms" json:"rpms,omitempty"`
Debs []string `yaml:"debs" json:"debs,omitempty"`
}
// RegistryConfig defines the configuration information of the image's repository.
type RegistryConfig struct {
Type string `yaml:"type" json:"type,omitempty"`
RegistryMirrors []string `yaml:"registryMirrors" json:"registryMirrors,omitempty"`
InsecureRegistries []string `yaml:"insecureRegistries" json:"insecureRegistries,omitempty"`
PrivateRegistry string `yaml:"privateRegistry" json:"privateRegistry,omitempty"`
DataRoot string `yaml:"dataRoot" json:"dataRoot,omitempty"`
NamespaceOverride string `yaml:"namespaceOverride" json:"namespaceOverride,omitempty"`
Auths runtime.RawExtension `yaml:"auths" json:"auths,omitempty"`
}
// KubeSphere defines the configuration information of the KubeSphere.
type KubeSphere struct {
Enabled bool `json:"enabled,omitempty"`
Version string `json:"version,omitempty"`
Configurations string `json:"configurations,omitempty"`
}
// GenerateCertSANs is used to generate cert sans for cluster.
func (cfg *ClusterSpec) GenerateCertSANs() []string {
clusterSvc := fmt.Sprintf("kubernetes.default.svc.%s", cfg.Kubernetes.DNSDomain)
defaultCertSANs := []string{"kubernetes", "kubernetes.default", "kubernetes.default.svc", clusterSvc, "localhost", "127.0.0.1"}
extraCertSANs := make([]string, 0)
extraCertSANs = append(extraCertSANs, cfg.ControlPlaneEndpoint.Domain)
extraCertSANs = append(extraCertSANs, cfg.ControlPlaneEndpoint.Address)
for _, host := range cfg.Hosts {
extraCertSANs = append(extraCertSANs, host.Name)
extraCertSANs = append(extraCertSANs, fmt.Sprintf("%s.%s", host.Name, cfg.Kubernetes.DNSDomain))
if host.Address != cfg.ControlPlaneEndpoint.Address {
extraCertSANs = append(extraCertSANs, host.Address)
}
if host.InternalAddress != host.Address && host.InternalAddress != cfg.ControlPlaneEndpoint.Address {
extraCertSANs = append(extraCertSANs, host.InternalAddress)
}
}
extraCertSANs = append(extraCertSANs, util.ParseIp(cfg.Network.KubeServiceCIDR)[0])
defaultCertSANs = append(defaultCertSANs, extraCertSANs...)
if cfg.Kubernetes.ApiserverCertExtraSans != nil {
defaultCertSANs = append(defaultCertSANs, cfg.Kubernetes.ApiserverCertExtraSans...)
}
return defaultCertSANs
}
// GroupHosts is used to group hosts according to the configuration file.s
func (cfg *ClusterSpec) GroupHosts() map[string][]*KubeHost {
hostMap := make(map[string]*KubeHost)
for _, hostCfg := range cfg.Hosts {
host := toHosts(hostCfg)
hostMap[host.Name] = host
}
roleGroups := cfg.ParseRolesList(hostMap)
//Check that the parameters under roleGroups are incorrect
if len(roleGroups[Master]) == 0 && len(roleGroups[ControlPlane]) == 0 {
logger.Fatal(errors.New("The number of master/control-plane cannot be 0"))
}
if len(roleGroups[Etcd]) == 0 && cfg.Etcd.Type == KubeKey {
logger.Fatal(errors.New("The number of etcd cannot be 0"))
}
if len(roleGroups[Registry]) > 1 {
logger.Fatal(errors.New("The number of registry node cannot be greater than 1."))
}
for _, host := range roleGroups[ControlPlane] {
host.SetRole(Master)
roleGroups[Master] = append(roleGroups[Master], host)
}
return roleGroups
}
// +kubebuilder:object:generate=false
type KubeHost struct {
*connector.BaseHost
Labels map[string]string
}
func toHosts(cfg HostCfg) *KubeHost {
host := connector.NewHost()
host.Name = cfg.Name
host.Address = cfg.Address
host.InternalAddress = cfg.InternalAddress
host.Port = cfg.Port
host.User = cfg.User
host.Password = cfg.Password
host.PrivateKey = cfg.PrivateKey
host.PrivateKeyPath = cfg.PrivateKeyPath
host.Arch = cfg.Arch
host.Timeout = *cfg.Timeout
kubeHost := &KubeHost{
BaseHost: host,
Labels: cfg.Labels,
}
return kubeHost
}
// CorednsClusterIP is used to get the coredns service address inside the cluster.
func (cfg *ClusterSpec) CorednsClusterIP() string {
return util.ParseIp(cfg.Network.KubeServiceCIDR)[2]
}
// ClusterDNS is used to get the dns server address inside the cluster.
func (cfg *ClusterSpec) ClusterDNS() string {
if cfg.Kubernetes.EnableNodelocaldns() {
return "169.254.25.10"
} else {
return cfg.CorednsClusterIP()
}
}
// ParseRolesList is used to parse the host grouping list.
func (cfg *ClusterSpec) ParseRolesList(hostMap map[string]*KubeHost) map[string][]*KubeHost {
roleGroupLists := make(map[string][]*KubeHost)
for role, hosts := range cfg.RoleGroups {
roleGroup := make([]string, 0)
for _, host := range hosts {
h := make([]string, 0)
if strings.Contains(host, "[") && strings.Contains(host, "]") && strings.Contains(host, ":") {
rangeHosts := getHostsRange(host, hostMap, role)
h = append(h, rangeHosts...)
} else {
if err := hostVerify(hostMap, host, role); err != nil {
logger.Fatal(err)
}
h = append(h, host)
}
roleGroup = append(roleGroup, h...)
for _, hostName := range h {
if h, ok := hostMap[hostName]; ok {
roleGroupAppend(roleGroupLists, role, h)
} else {
logger.Fatal(fmt.Errorf("incorrect nodeName under roleGroups/%s in the configuration file", role))
}
}
}
}
return roleGroupLists
}
func roleGroupAppend(roleGroupLists map[string][]*KubeHost, role string, host *KubeHost) {
host.SetRole(role)
r := roleGroupLists[role]
r = append(r, host)
roleGroupLists[role] = r
}
func getHostsRange(rangeStr string, hostMap map[string]*KubeHost, group string) []string {
hostRangeList := make([]string, 0)
r := regexp.MustCompile(`\[(\d+)\:(\d+)\]`)
nameSuffix := r.FindStringSubmatch(rangeStr)
namePrefix := strings.Split(rangeStr, nameSuffix[0])[0]
nameSuffixStart, _ := strconv.Atoi(nameSuffix[1])
nameSuffixEnd, _ := strconv.Atoi(nameSuffix[2])
for i := nameSuffixStart; i <= nameSuffixEnd; i++ {
if err := hostVerify(hostMap, fmt.Sprintf("%s%d", namePrefix, i), group); err != nil {
logger.Fatal(err)
}
hostRangeList = append(hostRangeList, fmt.Sprintf("%s%d", namePrefix, i))
}
return hostRangeList
}
func hostVerify(hostMap map[string]*KubeHost, hostName string, group string) error {
if _, ok := hostMap[hostName]; !ok {
return fmt.Errorf("[%s] is in [%s] group, but not in hosts list", hostName, group)
}
return nil
}
func (c ControlPlaneEndpoint) IsInternalLBEnabled() bool {
return c.InternalLoadbalancer == Haproxy
}
func (c ControlPlaneEndpoint) IsInternalLBEnabledVip() bool {
return c.InternalLoadbalancer == Kubevip
}

View File

@@ -0,0 +1,373 @@
/*
Copyright 2021 The KubeSphere Authors.
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 v1alpha2
import (
"fmt"
"os"
"strings"
"bytetrade.io/web3os/installer/pkg/core/util"
)
const (
DefaultPreDir = "kubekey"
DefaultTmpDir = "/tmp/kubekey"
DefaultSSHPort = 22
DefaultLBPort = 6443
DefaultApiserverPort = 6443
DefaultLBDomain = "lb.kubesphere.local"
DefaultNetworkPlugin = "calico"
DefaultPodsCIDR = "10.233.64.0/18"
DefaultServiceCIDR = "10.233.0.0/18"
DefaultKubeImageNamespace = "kubesphere"
DefaultClusterName = "cluster.local"
DefaultDNSDomain = "cluster.local"
DefaultArch = "amd64"
DefaultSSHTimeout = 30
DefaultEtcdVersion = "v3.4.13"
DefaultEtcdPort = "2379"
DefaultDockerVersion = "20.10.8"
DefaultContainerdVersion = "1.6.4"
DefaultRuncVersion = "v1.1.1"
DefaultRuncVersion_v_1_1_4 = "v1.1.4"
DefaultCrictlVersion = "v1.24.0"
DefaultKubeVersion = "v1.23.10"
DefaultCalicoVersion = "v3.29.2"
DefaultFlannelVersion = "v0.12.0"
DefaultCniVersion = "v0.9.1"
DefaultCniVersion_v_1_1_1 = "v1.1.1"
DefaultCiliumVersion = "v1.11.6"
DefaultKubeovnVersion = "v1.10.6"
DefalutMultusVersion = "v3.8"
DefaultHelmVersion = "v3.9.0"
DefaultDockerComposeVersion = "v2.2.2"
DefaultRegistryVersion = "2"
DefaultHarborVersion = "v2.5.3"
DefaultUbuntu24AppArmonVersion = "4.0.1"
DefaultSocatVersion = "1.7.3.4"
DefaultFlexVersion = "2.6.4"
DefaultConntrackVersion = "1.4.1"
DefaultOssUtilVersion = "v1.7.18"
DefaultCosUtilVersion = "v1.0.2"
DefaultMinioVersion = "RELEASE.2023-05-04T21-44-30Z"
DefaultMinioOperatorVersion = "0.0.1"
DefaultRedisVersion = "5.0.14"
DefaultJuiceFsVersion = "v11.1.0"
CudaKeyringVersion1_0 = "1.0"
CudaKeyringVersion1_1 = "1.1"
DefaultVeleroVersion = "v1.11.3"
DefaultWSLInstallPackageVersion = "2.3.26.0"
DefaultShutdownGracePeriod = "30s"
DefaultShutdownGracePeriodCriticalPods = "10s"
DefaultMaxPods = 200
DefaultPodPidsLimit = 10000
DefaultNodeCidrMaskSize = 24
DefaultIPIPMode = "Always"
DefaultVXLANMode = "Never"
DefaultVethMTU = 0
DefaultBackendMode = "vxlan"
DefaultProxyMode = "ipvs"
DefaultCrioEndpoint = "unix:///var/run/crio/crio.sock"
DefaultContainerdEndpoint = "unix:///run/containerd/containerd.sock"
DefaultIsulaEndpoint = "unix:///var/run/isulad.sock"
Etcd = "etcd"
Master = "master"
ControlPlane = "control-plane"
Worker = "worker"
K8s = "k8s"
Registry = "registry"
DefaultEtcdBackupDir = "/var/backups/kube_etcd"
DefaultEtcdBackupPeriod = 30
DefaultKeepBackNumber = 5
DefaultEtcdBackupScriptDir = "/usr/local/bin/kube-scripts"
DefaultPodGateway = "10.233.64.1"
DefaultJoinCIDR = "100.64.0.0/16"
DefaultNetworkType = "geneve"
DefaultTunnelType = "geneve"
DefaultPodNicType = "veth-pair"
DefaultModules = "kube_ovn_fastpath.ko"
DefaultRPMs = "openvswitch-kmod"
DefaultVlanID = "100"
DefaultOvnLabel = "node-role.kubernetes.io/control-plane"
DefaultDPDKVersion = "19.11"
DefaultDNSAddress = "114.114.114.114"
DefaultDpdkTunnelIface = "br-phy"
DefaultCNIConfigPriority = "01"
Docker = "docker"
Containerd = "containerd"
Crio = "crio"
Isula = "isula"
Haproxy = "haproxy"
Kubevip = "kube-vip"
DefaultKubeVipMode = "ARP"
)
func (cfg *ClusterSpec) SetDefaultClusterSpec(incluster bool, macos bool) (*ClusterSpec, map[string][]*KubeHost) {
clusterCfg := ClusterSpec{}
clusterCfg.Hosts = SetDefaultHostsCfg(cfg)
clusterCfg.RoleGroups = cfg.RoleGroups
clusterCfg.Etcd = SetDefaultEtcdCfg(cfg, macos)
roleGroups := clusterCfg.GroupHosts()
clusterCfg.ControlPlaneEndpoint = SetDefaultLBCfg(cfg, roleGroups[Master], incluster)
clusterCfg.Network = SetDefaultNetworkCfg(cfg)
clusterCfg.System = cfg.System
clusterCfg.Kubernetes = SetDefaultClusterCfg(cfg)
clusterCfg.Registry = cfg.Registry
clusterCfg.Addons = cfg.Addons
clusterCfg.KubeSphere = cfg.KubeSphere
if cfg.Kubernetes.ClusterName == "" {
clusterCfg.Kubernetes.ClusterName = DefaultClusterName
}
if cfg.Kubernetes.Version == "" {
clusterCfg.Kubernetes.Version = DefaultKubeVersion
}
if cfg.Kubernetes.ShutdownGracePeriod == "" {
clusterCfg.Kubernetes.ShutdownGracePeriod = DefaultShutdownGracePeriod
}
if cfg.Kubernetes.ShutdownGracePeriodCriticalPods == "" {
clusterCfg.Kubernetes.ShutdownGracePeriodCriticalPods = DefaultShutdownGracePeriodCriticalPods
}
if cfg.Kubernetes.MaxPods == 0 {
clusterCfg.Kubernetes.MaxPods = DefaultMaxPods
}
if cfg.Kubernetes.PodPidsLimit == 0 {
clusterCfg.Kubernetes.PodPidsLimit = DefaultPodPidsLimit
}
if cfg.Kubernetes.NodeCidrMaskSize == 0 {
clusterCfg.Kubernetes.NodeCidrMaskSize = DefaultNodeCidrMaskSize
}
if cfg.Kubernetes.ProxyMode == "" {
clusterCfg.Kubernetes.ProxyMode = DefaultProxyMode
}
return &clusterCfg, roleGroups
}
func SetDefaultHostsCfg(cfg *ClusterSpec) []HostCfg {
var hostCfg []HostCfg
if len(cfg.Hosts) == 0 {
return nil
}
for _, host := range cfg.Hosts {
if len(host.Address) == 0 && len(host.InternalAddress) > 0 {
host.Address = host.InternalAddress
}
if len(host.InternalAddress) == 0 && len(host.Address) > 0 {
host.InternalAddress = host.Address
}
if host.User == "" {
host.User = "root"
}
if host.Port == 0 {
host.Port = DefaultSSHPort
}
if host.PrivateKey == "" {
if host.Password == "" && host.PrivateKeyPath == "" {
host.PrivateKeyPath = "~/.ssh/id_rsa"
}
if host.PrivateKeyPath != "" && strings.HasPrefix(strings.TrimSpace(host.PrivateKeyPath), "~/") {
homeDir, _ := util.Home()
host.PrivateKeyPath = strings.Replace(host.PrivateKeyPath, "~/", fmt.Sprintf("%s/", homeDir), 1)
}
}
if host.Arch == "" {
host.Arch = DefaultArch
}
if host.Timeout == nil {
var timeout int64
timeout = DefaultSSHTimeout
host.Timeout = &timeout
}
hostCfg = append(hostCfg, host)
}
return hostCfg
}
func SetDefaultLBCfg(cfg *ClusterSpec, masterGroup []*KubeHost, incluster bool) ControlPlaneEndpoint {
if !incluster {
//The detection is not an HA environment, and the address at LB does not need input
if len(masterGroup) == 1 && cfg.ControlPlaneEndpoint.Address != "" {
fmt.Println("When the environment is not HA, the LB address does not need to be entered, so delete the corresponding value.")
os.Exit(0)
}
//Check whether LB should be configured
if len(masterGroup) >= 3 && !cfg.ControlPlaneEndpoint.IsInternalLBEnabled() && cfg.ControlPlaneEndpoint.Address == "" {
fmt.Println("When the environment has at least three masters, You must set the value of the LB address or enable the internal loadbalancer.")
os.Exit(0)
}
// Check whether LB address and the internal LB are both enabled
if cfg.ControlPlaneEndpoint.IsInternalLBEnabled() && cfg.ControlPlaneEndpoint.Address != "" {
fmt.Println("You cannot set up the internal load balancer and the LB address at the same time.")
os.Exit(0)
}
}
if cfg.ControlPlaneEndpoint.Address == "" || cfg.ControlPlaneEndpoint.Address == "127.0.0.1" {
cfg.ControlPlaneEndpoint.Address = masterGroup[0].InternalAddress
}
if cfg.ControlPlaneEndpoint.Domain == "" {
cfg.ControlPlaneEndpoint.Domain = DefaultLBDomain
}
if cfg.ControlPlaneEndpoint.Port == 0 {
cfg.ControlPlaneEndpoint.Port = DefaultLBPort
}
if cfg.ControlPlaneEndpoint.KubeVip.Mode == "" {
cfg.ControlPlaneEndpoint.KubeVip.Mode = DefaultKubeVipMode
}
defaultLbCfg := cfg.ControlPlaneEndpoint
return defaultLbCfg
}
func SetDefaultNetworkCfg(cfg *ClusterSpec) NetworkConfig {
if cfg.Network.Plugin == "" {
cfg.Network.Plugin = DefaultNetworkPlugin
}
if cfg.Network.KubePodsCIDR == "" {
cfg.Network.KubePodsCIDR = DefaultPodsCIDR
}
if cfg.Network.KubeServiceCIDR == "" {
cfg.Network.KubeServiceCIDR = DefaultServiceCIDR
}
if cfg.Network.Calico.IPIPMode == "" {
cfg.Network.Calico.IPIPMode = DefaultIPIPMode
}
if cfg.Network.Calico.VXLANMode == "" {
cfg.Network.Calico.VXLANMode = DefaultVXLANMode
}
if cfg.Network.Calico.VethMTU == 0 {
cfg.Network.Calico.VethMTU = DefaultVethMTU
}
if cfg.Network.Flannel.BackendMode == "" {
cfg.Network.Flannel.BackendMode = DefaultBackendMode
}
// kube-ovn default config
if cfg.Network.Kubeovn.KubeOvnController.PodGateway == "" {
cfg.Network.Kubeovn.KubeOvnController.PodGateway = DefaultPodGateway
}
if cfg.Network.Kubeovn.JoinCIDR == "" {
cfg.Network.Kubeovn.JoinCIDR = DefaultJoinCIDR
}
if cfg.Network.Kubeovn.Label == "" {
cfg.Network.Kubeovn.Label = DefaultOvnLabel
}
if cfg.Network.Kubeovn.KubeOvnController.VlanID == "" {
cfg.Network.Kubeovn.KubeOvnController.VlanID = DefaultVlanID
}
if cfg.Network.Kubeovn.KubeOvnController.NetworkType == "" {
cfg.Network.Kubeovn.KubeOvnController.NetworkType = DefaultNetworkType
}
if cfg.Network.Kubeovn.TunnelType == "" {
cfg.Network.Kubeovn.TunnelType = DefaultTunnelType
}
if cfg.Network.Kubeovn.KubeOvnController.PodNicType == "" {
cfg.Network.Kubeovn.KubeOvnController.PodNicType = DefaultPodNicType
}
if cfg.Network.Kubeovn.KubeOvnCni.Modules == "" {
cfg.Network.Kubeovn.KubeOvnCni.Modules = DefaultModules
}
if cfg.Network.Kubeovn.KubeOvnCni.RPMs == "" {
cfg.Network.Kubeovn.KubeOvnCni.RPMs = DefaultRPMs
}
if cfg.Network.Kubeovn.KubeOvnPinger.PingerExternalAddress == "" {
cfg.Network.Kubeovn.KubeOvnPinger.PingerExternalAddress = DefaultDNSAddress
}
if cfg.Network.Kubeovn.Dpdk.DpdkVersion == "" {
cfg.Network.Kubeovn.Dpdk.DpdkVersion = DefaultDPDKVersion
}
if cfg.Network.Kubeovn.Dpdk.DpdkTunnelIface == "" {
cfg.Network.Kubeovn.Dpdk.DpdkTunnelIface = DefaultDpdkTunnelIface
}
if cfg.Network.Kubeovn.KubeOvnCni.CNIConfigPriority == "" {
cfg.Network.Kubeovn.KubeOvnCni.CNIConfigPriority = DefaultCNIConfigPriority
}
defaultNetworkCfg := cfg.Network
return defaultNetworkCfg
}
func SetDefaultClusterCfg(cfg *ClusterSpec) Kubernetes {
if cfg.Kubernetes.Version == "" {
cfg.Kubernetes.Version = DefaultKubeVersion
} else {
s := strings.Split(cfg.Kubernetes.Version, "-")
if len(s) > 1 {
cfg.Kubernetes.Version = s[0]
cfg.Kubernetes.Type = s[1]
}
}
if cfg.Kubernetes.Type == "" {
cfg.Kubernetes.Type = "kubernetes"
}
if cfg.Kubernetes.ClusterName == "" {
cfg.Kubernetes.ClusterName = DefaultClusterName
}
if cfg.Kubernetes.DNSDomain == "" {
cfg.Kubernetes.DNSDomain = DefaultDNSDomain
}
if cfg.Kubernetes.ContainerManager == "" {
cfg.Kubernetes.ContainerManager = Docker
}
if cfg.Kubernetes.ContainerRuntimeEndpoint == "" {
switch cfg.Kubernetes.ContainerManager {
case Docker:
cfg.Kubernetes.ContainerRuntimeEndpoint = ""
case Crio:
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultCrioEndpoint
case Containerd:
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultContainerdEndpoint
case Isula:
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultIsulaEndpoint
default:
cfg.Kubernetes.ContainerRuntimeEndpoint = ""
}
}
defaultClusterCfg := cfg.Kubernetes
return defaultClusterCfg
}
func SetDefaultEtcdCfg(cfg *ClusterSpec, macos bool) EtcdCluster {
if macos {
cfg.Etcd.Type = MiniKube
} else if cfg.Etcd.Type == "" || ((cfg.Kubernetes.Type == "k3s" || (len(strings.Split(cfg.Kubernetes.Version, "-")) > 1) && strings.Split(cfg.Kubernetes.Version, "-")[1] == "k3s") && cfg.Etcd.Type == Kubeadm) {
cfg.Etcd.Type = KubeKey
}
if cfg.Etcd.BackupDir == "" {
cfg.Etcd.BackupDir = DefaultEtcdBackupDir
}
if cfg.Etcd.BackupPeriod == 0 {
cfg.Etcd.BackupPeriod = DefaultEtcdBackupPeriod
}
if cfg.Etcd.KeepBackupNumber == 0 {
cfg.Etcd.KeepBackupNumber = DefaultKeepBackNumber
}
if cfg.Etcd.BackupScriptDir == "" {
cfg.Etcd.BackupScriptDir = DefaultEtcdBackupScriptDir
}
return cfg.Etcd
}

View File

@@ -0,0 +1,49 @@
/*
Copyright 2021 The KubeSphere Authors.
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 v1alpha2
const (
KubeKey = "kubekey"
Kubeadm = "kubeadm"
External = "external"
MiniKube = "minikube"
)
type EtcdCluster struct {
// Type of etcd cluster, can be set to 'kubekey' 'kubeadm' 'external'
Type string `yaml:"type" json:"type,omitempty"`
// ExternalEtcd describes how to connect to an external etcd cluster when type is set to external
External ExternalEtcd `yaml:"external" json:"external,omitempty"`
BackupDir string `yaml:"backupDir" json:"backupDir,omitempty"`
BackupPeriod int `yaml:"backupPeriod" json:"backupPeriod,omitempty"`
KeepBackupNumber int `yaml:"keepBackupNumber" json:"keepBackupNumber,omitempty"`
BackupScriptDir string `yaml:"backupScript" json:"backupScript,omitempty"`
}
// ExternalEtcd describes how to connect to an external etcd cluster
// KubeKey, Kubeadm and External are mutually exclusive
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 `yaml:"endpoints" json:"endpoints,omitempty"`
// CAFile is an SSL Certificate Authority file used to secure etcd communication.
CAFile string `yaml:"caFile" json:"caFile,omitempty"`
// CertFile is an SSL certification file used to secure etcd communication.
CertFile string `yaml:"certFile" json:"certFile,omitempty"`
// KeyFile is an SSL key file used to secure etcd communication.
KeyFile string `yaml:"keyFile" json:"keyFile,omitempty"`
}

View File

@@ -0,0 +1,23 @@
/*
Copyright 2021 The KubeSphere Authors.
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 v1alpha2
type Event struct {
Step string `yaml:"step" json:"step,omitempty"`
Status string `yaml:"status" json:"status,omitempty"`
Message string `yaml:"message" json:"message,omitempty"`
}

View File

@@ -0,0 +1,43 @@
/*
Copyright 2021 The KubeSphere Authors.
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 v1alpha2 contains API Schema definitions for the kubekey v1alpha2 API group
// +kubebuilder:object:generate=true
// +groupName=kubekey.kubesphere.io
package v1alpha2
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = GroupVersion
var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "kubekey.kubesphere.io", Version: "v1alpha2"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
func Resource(resource string) schema.GroupResource {
return GroupVersion.WithResource(resource).GroupResource()
}

View File

@@ -0,0 +1,92 @@
/*
Copyright 2021 The KubeSphere Authors.
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 v1alpha2
import "k8s.io/apimachinery/pkg/runtime"
// Kubernetes contains the configuration for the cluster
type Kubernetes struct {
Type string `yaml:"type" json:"type,omitempty"`
Version string `yaml:"version" json:"version,omitempty"`
ClusterName string `yaml:"clusterName" json:"clusterName,omitempty"`
DNSDomain string `yaml:"dnsDomain" json:"dnsDomain,omitempty"`
DisableKubeProxy bool `yaml:"disableKubeProxy" json:"disableKubeProxy,omitempty"`
MasqueradeAll bool `yaml:"masqueradeAll" json:"masqueradeAll,omitempty"`
ShutdownGracePeriod string `yaml:"shutdownGracePeriod" json:"shutdownGracePeriod,omitempty"`
ShutdownGracePeriodCriticalPods string `json:"shutdownGracePeriodCriticalPods,omitempty"`
MaxPods int `yaml:"maxPods" json:"maxPods,omitempty"`
PodPidsLimit int `yaml:"podPidsLimit" json:"podPidsLimit,omitempty"`
NodeCidrMaskSize int `yaml:"nodeCidrMaskSize" json:"nodeCidrMaskSize,omitempty"`
ApiserverCertExtraSans []string `yaml:"apiserverCertExtraSans" json:"apiserverCertExtraSans,omitempty"`
ProxyMode string `yaml:"proxyMode" json:"proxyMode,omitempty"`
AutoRenewCerts *bool `yaml:"autoRenewCerts" json:"autoRenewCerts,omitempty"`
// +optional
Nodelocaldns *bool `yaml:"nodelocaldns" json:"nodelocaldns,omitempty"`
ContainerManager string `yaml:"containerManager" json:"containerManager,omitempty"`
ContainerRuntimeEndpoint string `yaml:"containerRuntimeEndpoint" json:"containerRuntimeEndpoint,omitempty"`
NodeFeatureDiscovery NodeFeatureDiscovery `yaml:"nodeFeatureDiscovery" json:"nodeFeatureDiscovery,omitempty"`
Kata Kata `yaml:"kata" json:"kata,omitempty"`
ApiServerArgs []string `yaml:"apiserverArgs" json:"apiserverArgs,omitempty"`
ControllerManagerArgs []string `yaml:"controllerManagerArgs" json:"controllerManagerArgs,omitempty"`
SchedulerArgs []string `yaml:"schedulerArgs" json:"schedulerArgs,omitempty"`
KubeletArgs []string `yaml:"kubeletArgs" json:"kubeletArgs,omitempty"`
KubeProxyArgs []string `yaml:"kubeProxyArgs" json:"kubeProxyArgs,omitempty"`
FeatureGates map[string]bool `yaml:"featureGates" json:"featureGates,omitempty"`
KubeletConfiguration runtime.RawExtension `yaml:"kubeletConfiguration" json:"kubeletConfiguration,omitempty"`
KubeProxyConfiguration runtime.RawExtension `yaml:"kubeProxyConfiguration" json:"kubeProxyConfiguration,omitempty"`
}
// Kata contains the configuration for the kata in cluster
type Kata struct {
Enabled *bool `yaml:"enabled" json:"enabled,omitempty"`
}
// NodeFeatureDiscovery contains the configuration for the node-feature-discovery in cluster
type NodeFeatureDiscovery struct {
Enabled *bool `yaml:"enabled" json:"enabled,omitempty"`
}
// EnableNodelocaldns is used to determine whether to deploy nodelocaldns.
func (k *Kubernetes) EnableNodelocaldns() bool {
if k.Nodelocaldns == nil {
return true
}
return *k.Nodelocaldns
}
// EnableKataDeploy is used to determine whether to deploy kata.
func (k *Kubernetes) EnableKataDeploy() bool {
if k.Kata.Enabled == nil {
return false
}
return *k.Kata.Enabled
}
// EnableNodeFeatureDiscovery is used to determine whether to deploy node-feature-discovery.
func (k *Kubernetes) EnableNodeFeatureDiscovery() bool {
if k.NodeFeatureDiscovery.Enabled == nil {
return false
}
return *k.NodeFeatureDiscovery.Enabled
}
func (k *Kubernetes) EnableAutoRenewCerts() bool {
if k.AutoRenewCerts == nil {
return false
}
return *k.AutoRenewCerts
}

View File

@@ -0,0 +1,144 @@
/*
Copyright 2020 The KubeSphere Authors.
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 v1alpha2
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
type Iso struct {
LocalPath string `yaml:"localPath" json:"localPath"`
Url string `yaml:"url" json:"url"`
}
type Repository struct {
Iso Iso `yaml:"iso" json:"iso"`
}
type OperatingSystem struct {
Arch string `yaml:"arch" json:"arch"`
Type string `yaml:"type" json:"type,omitempty"`
Id string `yaml:"id" json:"id"`
Version string `yaml:"version" json:"version"`
OsImage string `yaml:"osImage" json:"osImage"`
Repository Repository `yaml:"repository" json:"repository"`
}
type KubernetesDistribution struct {
Type string `yaml:"type" json:"type"`
Version string `yaml:"version" json:"version"`
}
type Helm struct {
Version string `yaml:"version" json:"version"`
}
type CNI struct {
Version string `yaml:"version" json:"version"`
}
type ETCD struct {
Version string `yaml:"version" json:"version"`
}
type DockerManifest struct {
Version string `yaml:"version" json:"version"`
}
type Crictl struct {
Version string `yaml:"version" json:"version"`
}
type ContainerRuntime struct {
Type string `yaml:"type" json:"type"`
Version string `yaml:"version" json:"version"`
}
type DockerRegistry struct {
Version string `yaml:"version" json:"version"`
}
type Harbor struct {
Version string `yaml:"version" json:"version"`
}
type DockerCompose struct {
Version string `yaml:"version" json:"version"`
}
type Components struct {
Helm Helm `yaml:"helm" json:"helm"`
CNI CNI `yaml:"cni" json:"cni"`
ETCD ETCD `yaml:"etcd" json:"etcd"`
ContainerRuntimes []ContainerRuntime `yaml:"containerRuntimes" json:"containerRuntimes"`
Crictl Crictl `yaml:"crictl" json:"crictl,omitempty"`
DockerRegistry DockerRegistry `yaml:"docker-registry" json:"docker-registry"`
Harbor Harbor `yaml:"harbor" json:"harbor"`
DockerCompose DockerCompose `yaml:"docker-compose" json:"docker-compose"`
}
type ManifestRegistry struct {
Auths runtime.RawExtension `yaml:"auths" json:"auths,omitempty"`
}
// ManifestSpec defines the desired state of Manifest
type ManifestSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
Arches []string `yaml:"arches" json:"arches"`
OperatingSystems []OperatingSystem `yaml:"operatingSystems" json:"operatingSystems"`
KubernetesDistributions []KubernetesDistribution `yaml:"kubernetesDistributions" json:"kubernetesDistributions"`
Components Components `yaml:"components" json:"components"`
Images []string `yaml:"images" json:"images"`
ManifestRegistry ManifestRegistry `yaml:"registry" json:"registry"`
}
// ManifestStatus defines the observed state of Manifest
type ManifestStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// Manifest is the Schema for the manifests API
type Manifest struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ManifestSpec `json:"spec,omitempty"`
Status ManifestStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// ManifestList contains a list of Manifest
type ManifestList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Manifest `json:"items"`
}
func init() {
SchemeBuilder.Register(&Manifest{}, &ManifestList{})
}

View File

@@ -0,0 +1,135 @@
/*
Copyright 2021 The KubeSphere Authors.
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 v1alpha2
type NetworkConfig struct {
Plugin string `yaml:"plugin" json:"plugin,omitempty"`
KubePodsCIDR string `yaml:"kubePodsCIDR" json:"kubePodsCIDR,omitempty"`
KubeServiceCIDR string `yaml:"kubeServiceCIDR" json:"kubeServiceCIDR,omitempty"`
Calico CalicoCfg `yaml:"calico" json:"calico,omitempty"`
Flannel FlannelCfg `yaml:"flannel" json:"flannel,omitempty"`
Kubeovn KubeovnCfg `yaml:"kubeovn" json:"kubeovn,omitempty"`
MultusCNI MultusCNI `yaml:"multusCNI" json:"multusCNI,omitempty"`
}
type CalicoCfg struct {
IPIPMode string `yaml:"ipipMode" json:"ipipMode,omitempty"`
VXLANMode string `yaml:"vxlanMode" json:"vxlanMode,omitempty"`
VethMTU int `yaml:"vethMTU" json:"vethMTU,omitempty"`
}
type FlannelCfg struct {
BackendMode string `yaml:"backendMode" json:"backendMode,omitempty"`
Directrouting bool `yaml:"directRouting" json:"directRouting,omitempty"`
}
type KubeovnCfg struct {
EnableSSL bool `yaml:"enableSSL" json:"enableSSL,omitempty"`
JoinCIDR string `yaml:"joinCIDR" json:"joinCIDR,omitempty"`
Label string `yaml:"label" json:"label,omitempty"`
TunnelType string `yaml:"tunnelType" json:"tunnelType,omitempty"`
SvcYamlIpfamilypolicy string `yaml:"svcYamlIpfamilypolicy" json:"svcYamlIpfamilypolicy,omitempty"`
Dpdk Dpdk `yaml:"dpdk" json:"dpdk,omitempty"`
OvsOvn OvsOvn `yaml:"ovs-ovn" json:"ovs-ovn,omitempty"`
KubeOvnController KubeOvnController `yaml:"kube-ovn-controller" json:"kube-ovn-controller,omitempty"`
KubeOvnCni KubeOvnCni `yaml:"kube-ovn-cni" json:"kube-ovn-cni,omitempty"`
KubeOvnPinger KubeOvnPinger `yaml:"kube-ovn-pinger" json:"kube-ovn-pinger,omitempty"`
}
type Dpdk struct {
DpdkMode bool `yaml:"dpdkMode" json:"dpdkMode,omitempty"`
DpdkTunnelIface string `yaml:"dpdkTunnelIface" json:"dpdkTunnelIface,omitempty"`
DpdkVersion string `yaml:"dpdkVersion" json:"dpdkVersion,omitempty"`
}
type OvsOvn struct {
HwOffload bool `yaml:"hwOffload" json:"hwOffload,omitempty"`
}
type KubeOvnController struct {
PodGateway string `yaml:"podGateway" json:"podGateway,omitempty"`
CheckGateway *bool `yaml:"checkGateway" json:"checkGateway,omitempty"`
LogicalGateway bool `yaml:"logicalGateway" json:"logicalGateway,omitempty"`
ExcludeIps string `yaml:"excludeIps" json:"excludeIps,omitempty"`
NetworkType string `yaml:"networkType" json:"networkType,omitempty"`
VlanInterfaceName string `yaml:"vlanInterfaceName" json:"vlanInterfaceName,omitempty"`
VlanID string `yaml:"vlanID" json:"vlanID,omitempty"`
PodNicType string `yaml:"podNicType" json:"podNicType,omitempty"`
EnableLB *bool `yaml:"enableLB" json:"enableLB,omitempty"`
EnableNP *bool `yaml:"enableNP" json:"enableNP,omitempty"`
EnableEipSnat *bool `yaml:"enableEipSnat" json:"enableEipSnat,omitempty"`
EnableExternalVPC *bool `yaml:"enableExternalVPC" json:"enableExternalVPC,omitempty"`
}
type KubeOvnCni struct {
EnableMirror bool `yaml:"enableMirror" json:"enableMirror,omitempty"`
Iface string `yaml:"iface" json:"iface,omitempty"`
CNIConfigPriority string `yaml:"CNIConfigPriority" json:"CNIConfigPriority,omitempty"`
Modules string `yaml:"modules" json:"modules,omitempty"`
RPMs string `yaml:"RPMs" json:"RPMs,omitempty"`
}
type KubeOvnPinger struct {
PingerExternalAddress string `yaml:"pingerExternalAddress" json:"pingerExternalAddress,omitempty"`
PingerExternalDomain string `yaml:"pingerExternalDomain" json:"pingerExternalDomain,omitempty"`
}
func (k *KubeovnCfg) KubeovnCheckGateway() bool {
if k.KubeOvnController.CheckGateway == nil {
return true
}
return *k.KubeOvnController.CheckGateway
}
func (k *KubeovnCfg) KubeovnEnableLB() bool {
if k.KubeOvnController.EnableLB == nil {
return true
}
return *k.KubeOvnController.EnableLB
}
func (k *KubeovnCfg) KubeovnEnableNP() bool {
if k.KubeOvnController.EnableNP == nil {
return true
}
return *k.KubeOvnController.EnableNP
}
func (k *KubeovnCfg) KubeovnEnableEipSnat() bool {
if k.KubeOvnController.EnableEipSnat == nil {
return true
}
return *k.KubeOvnController.EnableEipSnat
}
func (k *KubeovnCfg) KubeovnEnableExternalVPC() bool {
if k.KubeOvnController.EnableExternalVPC == nil {
return true
}
return *k.KubeOvnController.EnableExternalVPC
}
type MultusCNI struct {
Enabled *bool `yaml:"enabled" json:"enabled,omitempty"`
}
func (n *NetworkConfig) EnableMultusCNI() bool {
if n.MultusCNI.Enabled == nil {
return false
}
return *n.MultusCNI.Enabled
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,110 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package versioned
import (
"fmt"
kubekeyv1alpha1 "bytetrade.io/web3os/installer/clients/clientset/versioned/typed/kubekey/v1alpha1"
kubekeyv1alpha2 "bytetrade.io/web3os/installer/clients/clientset/versioned/typed/kubekey/v1alpha2"
discovery "k8s.io/client-go/discovery"
rest "k8s.io/client-go/rest"
flowcontrol "k8s.io/client-go/util/flowcontrol"
)
type Interface interface {
Discovery() discovery.DiscoveryInterface
KubekeyV1alpha1() kubekeyv1alpha1.KubekeyV1alpha1Interface
KubekeyV1alpha2() kubekeyv1alpha2.KubekeyV1alpha2Interface
}
// Clientset contains the clients for groups. Each group has exactly one
// version included in a Clientset.
type Clientset struct {
*discovery.DiscoveryClient
kubekeyV1alpha1 *kubekeyv1alpha1.KubekeyV1alpha1Client
kubekeyV1alpha2 *kubekeyv1alpha2.KubekeyV1alpha2Client
}
// KubekeyV1alpha1 retrieves the KubekeyV1alpha1Client
func (c *Clientset) KubekeyV1alpha1() kubekeyv1alpha1.KubekeyV1alpha1Interface {
return c.kubekeyV1alpha1
}
// KubekeyV1alpha2 retrieves the KubekeyV1alpha2Client
func (c *Clientset) KubekeyV1alpha2() kubekeyv1alpha2.KubekeyV1alpha2Interface {
return c.kubekeyV1alpha2
}
// Discovery retrieves the DiscoveryClient
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
if c == nil {
return nil
}
return c.DiscoveryClient
}
// NewForConfig creates a new Clientset for the given config.
// If config's RateLimiter is not set and QPS and Burst are acceptable,
// NewForConfig will generate a rate-limiter in configShallowCopy.
func NewForConfig(c *rest.Config) (*Clientset, error) {
configShallowCopy := *c
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
if configShallowCopy.Burst <= 0 {
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
}
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
}
var cs Clientset
var err error
cs.kubekeyV1alpha1, err = kubekeyv1alpha1.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
cs.kubekeyV1alpha2, err = kubekeyv1alpha2.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
return &cs, nil
}
// NewForConfigOrDie creates a new Clientset for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *Clientset {
var cs Clientset
cs.kubekeyV1alpha1 = kubekeyv1alpha1.NewForConfigOrDie(c)
cs.kubekeyV1alpha2 = kubekeyv1alpha2.NewForConfigOrDie(c)
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &cs
}
// New creates a new Clientset for the given RESTClient.
func New(c rest.Interface) *Clientset {
var cs Clientset
cs.kubekeyV1alpha1 = kubekeyv1alpha1.New(c)
cs.kubekeyV1alpha2 = kubekeyv1alpha2.New(c)
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &cs
}

View File

@@ -0,0 +1,19 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated clientset.
package versioned

View File

@@ -0,0 +1,91 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
clientset "bytetrade.io/web3os/installer/clients/clientset/versioned"
kubekeyv1alpha1 "bytetrade.io/web3os/installer/clients/clientset/versioned/typed/kubekey/v1alpha1"
fakekubekeyv1alpha1 "bytetrade.io/web3os/installer/clients/clientset/versioned/typed/kubekey/v1alpha1/fake"
kubekeyv1alpha2 "bytetrade.io/web3os/installer/clients/clientset/versioned/typed/kubekey/v1alpha2"
fakekubekeyv1alpha2 "bytetrade.io/web3os/installer/clients/clientset/versioned/typed/kubekey/v1alpha2/fake"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/discovery"
fakediscovery "k8s.io/client-go/discovery/fake"
"k8s.io/client-go/testing"
)
// NewSimpleClientset returns a clientset that will respond with the provided objects.
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
// without applying any validations and/or defaults. It shouldn't be considered a replacement
// for a real clientset and is mostly useful in simple unit tests.
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
for _, obj := range objects {
if err := o.Add(obj); err != nil {
panic(err)
}
}
cs := &Clientset{tracker: o}
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
cs.AddReactor("*", "*", testing.ObjectReaction(o))
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
gvr := action.GetResource()
ns := action.GetNamespace()
watch, err := o.Watch(gvr, ns)
if err != nil {
return false, nil, err
}
return true, watch, nil
})
return cs
}
// Clientset implements clientset.Interface. Meant to be embedded into a
// struct to get a default implementation. This makes faking out just the method
// you want to test easier.
type Clientset struct {
testing.Fake
discovery *fakediscovery.FakeDiscovery
tracker testing.ObjectTracker
}
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
return c.discovery
}
func (c *Clientset) Tracker() testing.ObjectTracker {
return c.tracker
}
var (
_ clientset.Interface = &Clientset{}
_ testing.FakeClient = &Clientset{}
)
// KubekeyV1alpha1 retrieves the KubekeyV1alpha1Client
func (c *Clientset) KubekeyV1alpha1() kubekeyv1alpha1.KubekeyV1alpha1Interface {
return &fakekubekeyv1alpha1.FakeKubekeyV1alpha1{Fake: &c.Fake}
}
// KubekeyV1alpha2 retrieves the KubekeyV1alpha2Client
func (c *Clientset) KubekeyV1alpha2() kubekeyv1alpha2.KubekeyV1alpha2Interface {
return &fakekubekeyv1alpha2.FakeKubekeyV1alpha2{Fake: &c.Fake}
}

View File

@@ -0,0 +1,19 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated fake clientset.
package fake

View File

@@ -0,0 +1,57 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
kubekeyv1alpha1 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha1"
kubekeyv1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
)
var scheme = runtime.NewScheme()
var codecs = serializer.NewCodecFactory(scheme)
var localSchemeBuilder = runtime.SchemeBuilder{
kubekeyv1alpha1.AddToScheme,
kubekeyv1alpha2.AddToScheme,
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
// of clientsets, like in:
//
// import (
// "k8s.io/client-go/kubernetes"
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
// )
//
// kclientset, _ := kubernetes.NewForConfig(c)
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
//
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
// correctly.
var AddToScheme = localSchemeBuilder.AddToScheme
func init() {
v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
utilruntime.Must(AddToScheme(scheme))
}

View File

@@ -0,0 +1,19 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package contains the scheme of the automatically generated clientset.
package scheme

View File

@@ -0,0 +1,57 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package scheme
import (
kubekeyv1alpha1 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha1"
kubekeyv1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
)
var Scheme = runtime.NewScheme()
var Codecs = serializer.NewCodecFactory(Scheme)
var ParameterCodec = runtime.NewParameterCodec(Scheme)
var localSchemeBuilder = runtime.SchemeBuilder{
kubekeyv1alpha1.AddToScheme,
kubekeyv1alpha2.AddToScheme,
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
// of clientsets, like in:
//
// import (
// "k8s.io/client-go/kubernetes"
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
// )
//
// kclientset, _ := kubernetes.NewForConfig(c)
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
//
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
// correctly.
var AddToScheme = localSchemeBuilder.AddToScheme
func init() {
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
utilruntime.Must(AddToScheme(Scheme))
}

View File

@@ -0,0 +1,183 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
import (
"context"
"time"
v1alpha1 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha1"
scheme "bytetrade.io/web3os/installer/clients/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
)
// ClustersGetter has a method to return a ClusterInterface.
// A group's client should implement this interface.
type ClustersGetter interface {
Clusters() ClusterInterface
}
// ClusterInterface has methods to work with Cluster resources.
type ClusterInterface interface {
Create(ctx context.Context, cluster *v1alpha1.Cluster, opts v1.CreateOptions) (*v1alpha1.Cluster, error)
Update(ctx context.Context, cluster *v1alpha1.Cluster, opts v1.UpdateOptions) (*v1alpha1.Cluster, error)
UpdateStatus(ctx context.Context, cluster *v1alpha1.Cluster, opts v1.UpdateOptions) (*v1alpha1.Cluster, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.Cluster, error)
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ClusterList, error)
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Cluster, err error)
ClusterExpansion
}
// clusters implements ClusterInterface
type clusters struct {
client rest.Interface
}
// newClusters returns a Clusters
func newClusters(c *KubekeyV1alpha1Client) *clusters {
return &clusters{
client: c.RESTClient(),
}
}
// Get takes name of the cluster, and returns the corresponding cluster object, and an error if there is any.
func (c *clusters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Cluster, err error) {
result = &v1alpha1.Cluster{}
err = c.client.Get().
Resource("clusters").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of Clusters that match those selectors.
func (c *clusters) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha1.ClusterList{}
err = c.client.Get().
Resource("clusters").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested clusters.
func (c *clusters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Resource("clusters").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a cluster and creates it. Returns the server's representation of the cluster, and an error, if there is any.
func (c *clusters) Create(ctx context.Context, cluster *v1alpha1.Cluster, opts v1.CreateOptions) (result *v1alpha1.Cluster, err error) {
result = &v1alpha1.Cluster{}
err = c.client.Post().
Resource("clusters").
VersionedParams(&opts, scheme.ParameterCodec).
Body(cluster).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a cluster and updates it. Returns the server's representation of the cluster, and an error, if there is any.
func (c *clusters) Update(ctx context.Context, cluster *v1alpha1.Cluster, opts v1.UpdateOptions) (result *v1alpha1.Cluster, err error) {
result = &v1alpha1.Cluster{}
err = c.client.Put().
Resource("clusters").
Name(cluster.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(cluster).
Do(ctx).
Into(result)
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *clusters) UpdateStatus(ctx context.Context, cluster *v1alpha1.Cluster, opts v1.UpdateOptions) (result *v1alpha1.Cluster, err error) {
result = &v1alpha1.Cluster{}
err = c.client.Put().
Resource("clusters").
Name(cluster.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(cluster).
Do(ctx).
Into(result)
return
}
// Delete takes name of the cluster and deletes it. Returns an error if one occurs.
func (c *clusters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Resource("clusters").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *clusters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Resource("clusters").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched cluster.
func (c *clusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Cluster, err error) {
result = &v1alpha1.Cluster{}
err = c.client.Patch(pt).
Resource("clusters").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View File

@@ -0,0 +1,19 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated typed clients.
package v1alpha1

View File

@@ -0,0 +1,19 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// Package fake has the automatically generated clients.
package fake

View File

@@ -0,0 +1,132 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
v1alpha1 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
)
// FakeClusters implements ClusterInterface
type FakeClusters struct {
Fake *FakeKubekeyV1alpha1
}
var clustersResource = schema.GroupVersionResource{Group: "kubekey", Version: "v1alpha1", Resource: "clusters"}
var clustersKind = schema.GroupVersionKind{Group: "kubekey", Version: "v1alpha1", Kind: "Cluster"}
// Get takes name of the cluster, and returns the corresponding cluster object, and an error if there is any.
func (c *FakeClusters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Cluster, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootGetAction(clustersResource, name), &v1alpha1.Cluster{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.Cluster), err
}
// List takes label and field selectors, and returns the list of Clusters that match those selectors.
func (c *FakeClusters) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterList, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootListAction(clustersResource, clustersKind, opts), &v1alpha1.ClusterList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1alpha1.ClusterList{ListMeta: obj.(*v1alpha1.ClusterList).ListMeta}
for _, item := range obj.(*v1alpha1.ClusterList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested clusters.
func (c *FakeClusters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewRootWatchAction(clustersResource, opts))
}
// Create takes the representation of a cluster and creates it. Returns the server's representation of the cluster, and an error, if there is any.
func (c *FakeClusters) Create(ctx context.Context, cluster *v1alpha1.Cluster, opts v1.CreateOptions) (result *v1alpha1.Cluster, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(clustersResource, cluster), &v1alpha1.Cluster{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.Cluster), err
}
// Update takes the representation of a cluster and updates it. Returns the server's representation of the cluster, and an error, if there is any.
func (c *FakeClusters) Update(ctx context.Context, cluster *v1alpha1.Cluster, opts v1.UpdateOptions) (result *v1alpha1.Cluster, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(clustersResource, cluster), &v1alpha1.Cluster{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.Cluster), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeClusters) UpdateStatus(ctx context.Context, cluster *v1alpha1.Cluster, opts v1.UpdateOptions) (*v1alpha1.Cluster, error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateSubresourceAction(clustersResource, "status", cluster), &v1alpha1.Cluster{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.Cluster), err
}
// Delete takes name of the cluster and deletes it. Returns an error if one occurs.
func (c *FakeClusters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewRootDeleteAction(clustersResource, name), &v1alpha1.Cluster{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeClusters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(clustersResource, listOpts)
_, err := c.Fake.Invokes(action, &v1alpha1.ClusterList{})
return err
}
// Patch applies the patch and returns the patched cluster.
func (c *FakeClusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Cluster, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(clustersResource, name, pt, data, subresources...), &v1alpha1.Cluster{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.Cluster), err
}

View File

@@ -0,0 +1,39 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
v1alpha1 "bytetrade.io/web3os/installer/clients/clientset/versioned/typed/kubekey/v1alpha1"
rest "k8s.io/client-go/rest"
testing "k8s.io/client-go/testing"
)
type FakeKubekeyV1alpha1 struct {
*testing.Fake
}
func (c *FakeKubekeyV1alpha1) Clusters() v1alpha1.ClusterInterface {
return &FakeClusters{c}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeKubekeyV1alpha1) RESTClient() rest.Interface {
var ret *rest.RESTClient
return ret
}

View File

@@ -0,0 +1,20 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
type ClusterExpansion interface{}

View File

@@ -0,0 +1,88 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
import (
v1alpha1 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha1"
"bytetrade.io/web3os/installer/clients/clientset/versioned/scheme"
rest "k8s.io/client-go/rest"
)
type KubekeyV1alpha1Interface interface {
RESTClient() rest.Interface
ClustersGetter
}
// KubekeyV1alpha1Client is used to interact with features provided by the kubekey group.
type KubekeyV1alpha1Client struct {
restClient rest.Interface
}
func (c *KubekeyV1alpha1Client) Clusters() ClusterInterface {
return newClusters(c)
}
// NewForConfig creates a new KubekeyV1alpha1Client for the given config.
func NewForConfig(c *rest.Config) (*KubekeyV1alpha1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &KubekeyV1alpha1Client{client}, nil
}
// NewForConfigOrDie creates a new KubekeyV1alpha1Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *KubekeyV1alpha1Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new KubekeyV1alpha1Client for the given RESTClient.
func New(c rest.Interface) *KubekeyV1alpha1Client {
return &KubekeyV1alpha1Client{c}
}
func setConfigDefaults(config *rest.Config) error {
gv := v1alpha1.GroupVersion
config.GroupVersion = &gv
config.APIPath = "/apis"
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
if config.UserAgent == "" {
config.UserAgent = rest.DefaultKubernetesUserAgent()
}
return nil
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *KubekeyV1alpha1Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
return c.restClient
}

View File

@@ -0,0 +1,183 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha2
import (
"context"
"time"
v1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
scheme "bytetrade.io/web3os/installer/clients/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
)
// ClustersGetter has a method to return a ClusterInterface.
// A group's client should implement this interface.
type ClustersGetter interface {
Clusters() ClusterInterface
}
// ClusterInterface has methods to work with Cluster resources.
type ClusterInterface interface {
Create(ctx context.Context, cluster *v1alpha2.Cluster, opts v1.CreateOptions) (*v1alpha2.Cluster, error)
Update(ctx context.Context, cluster *v1alpha2.Cluster, opts v1.UpdateOptions) (*v1alpha2.Cluster, error)
UpdateStatus(ctx context.Context, cluster *v1alpha2.Cluster, opts v1.UpdateOptions) (*v1alpha2.Cluster, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.Cluster, error)
List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ClusterList, error)
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.Cluster, err error)
ClusterExpansion
}
// clusters implements ClusterInterface
type clusters struct {
client rest.Interface
}
// newClusters returns a Clusters
func newClusters(c *KubekeyV1alpha2Client) *clusters {
return &clusters{
client: c.RESTClient(),
}
}
// Get takes name of the cluster, and returns the corresponding cluster object, and an error if there is any.
func (c *clusters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.Cluster, err error) {
result = &v1alpha2.Cluster{}
err = c.client.Get().
Resource("clusters").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of Clusters that match those selectors.
func (c *clusters) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ClusterList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha2.ClusterList{}
err = c.client.Get().
Resource("clusters").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested clusters.
func (c *clusters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Resource("clusters").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a cluster and creates it. Returns the server's representation of the cluster, and an error, if there is any.
func (c *clusters) Create(ctx context.Context, cluster *v1alpha2.Cluster, opts v1.CreateOptions) (result *v1alpha2.Cluster, err error) {
result = &v1alpha2.Cluster{}
err = c.client.Post().
Resource("clusters").
VersionedParams(&opts, scheme.ParameterCodec).
Body(cluster).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a cluster and updates it. Returns the server's representation of the cluster, and an error, if there is any.
func (c *clusters) Update(ctx context.Context, cluster *v1alpha2.Cluster, opts v1.UpdateOptions) (result *v1alpha2.Cluster, err error) {
result = &v1alpha2.Cluster{}
err = c.client.Put().
Resource("clusters").
Name(cluster.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(cluster).
Do(ctx).
Into(result)
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *clusters) UpdateStatus(ctx context.Context, cluster *v1alpha2.Cluster, opts v1.UpdateOptions) (result *v1alpha2.Cluster, err error) {
result = &v1alpha2.Cluster{}
err = c.client.Put().
Resource("clusters").
Name(cluster.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(cluster).
Do(ctx).
Into(result)
return
}
// Delete takes name of the cluster and deletes it. Returns an error if one occurs.
func (c *clusters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Resource("clusters").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *clusters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Resource("clusters").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched cluster.
func (c *clusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.Cluster, err error) {
result = &v1alpha2.Cluster{}
err = c.client.Patch(pt).
Resource("clusters").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View File

@@ -0,0 +1,19 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated typed clients.
package v1alpha2

View File

@@ -0,0 +1,19 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// Package fake has the automatically generated clients.
package fake

View File

@@ -0,0 +1,132 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
v1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
)
// FakeClusters implements ClusterInterface
type FakeClusters struct {
Fake *FakeKubekeyV1alpha2
}
var clustersResource = schema.GroupVersionResource{Group: "kubekey", Version: "v1alpha2", Resource: "clusters"}
var clustersKind = schema.GroupVersionKind{Group: "kubekey", Version: "v1alpha2", Kind: "Cluster"}
// Get takes name of the cluster, and returns the corresponding cluster object, and an error if there is any.
func (c *FakeClusters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.Cluster, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootGetAction(clustersResource, name), &v1alpha2.Cluster{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.Cluster), err
}
// List takes label and field selectors, and returns the list of Clusters that match those selectors.
func (c *FakeClusters) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ClusterList, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootListAction(clustersResource, clustersKind, opts), &v1alpha2.ClusterList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1alpha2.ClusterList{ListMeta: obj.(*v1alpha2.ClusterList).ListMeta}
for _, item := range obj.(*v1alpha2.ClusterList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested clusters.
func (c *FakeClusters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewRootWatchAction(clustersResource, opts))
}
// Create takes the representation of a cluster and creates it. Returns the server's representation of the cluster, and an error, if there is any.
func (c *FakeClusters) Create(ctx context.Context, cluster *v1alpha2.Cluster, opts v1.CreateOptions) (result *v1alpha2.Cluster, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(clustersResource, cluster), &v1alpha2.Cluster{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.Cluster), err
}
// Update takes the representation of a cluster and updates it. Returns the server's representation of the cluster, and an error, if there is any.
func (c *FakeClusters) Update(ctx context.Context, cluster *v1alpha2.Cluster, opts v1.UpdateOptions) (result *v1alpha2.Cluster, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(clustersResource, cluster), &v1alpha2.Cluster{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.Cluster), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeClusters) UpdateStatus(ctx context.Context, cluster *v1alpha2.Cluster, opts v1.UpdateOptions) (*v1alpha2.Cluster, error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateSubresourceAction(clustersResource, "status", cluster), &v1alpha2.Cluster{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.Cluster), err
}
// Delete takes name of the cluster and deletes it. Returns an error if one occurs.
func (c *FakeClusters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewRootDeleteAction(clustersResource, name), &v1alpha2.Cluster{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeClusters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(clustersResource, listOpts)
_, err := c.Fake.Invokes(action, &v1alpha2.ClusterList{})
return err
}
// Patch applies the patch and returns the patched cluster.
func (c *FakeClusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.Cluster, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(clustersResource, name, pt, data, subresources...), &v1alpha2.Cluster{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.Cluster), err
}

View File

@@ -0,0 +1,39 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
v1alpha2 "bytetrade.io/web3os/installer/clients/clientset/versioned/typed/kubekey/v1alpha2"
rest "k8s.io/client-go/rest"
testing "k8s.io/client-go/testing"
)
type FakeKubekeyV1alpha2 struct {
*testing.Fake
}
func (c *FakeKubekeyV1alpha2) Clusters() v1alpha2.ClusterInterface {
return &FakeClusters{c}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeKubekeyV1alpha2) RESTClient() rest.Interface {
var ret *rest.RESTClient
return ret
}

View File

@@ -0,0 +1,20 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha2
type ClusterExpansion interface{}

View File

@@ -0,0 +1,88 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha2
import (
v1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
"bytetrade.io/web3os/installer/clients/clientset/versioned/scheme"
rest "k8s.io/client-go/rest"
)
type KubekeyV1alpha2Interface interface {
RESTClient() rest.Interface
ClustersGetter
}
// KubekeyV1alpha2Client is used to interact with features provided by the kubekey group.
type KubekeyV1alpha2Client struct {
restClient rest.Interface
}
func (c *KubekeyV1alpha2Client) Clusters() ClusterInterface {
return newClusters(c)
}
// NewForConfig creates a new KubekeyV1alpha2Client for the given config.
func NewForConfig(c *rest.Config) (*KubekeyV1alpha2Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &KubekeyV1alpha2Client{client}, nil
}
// NewForConfigOrDie creates a new KubekeyV1alpha2Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *KubekeyV1alpha2Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new KubekeyV1alpha2Client for the given RESTClient.
func New(c rest.Interface) *KubekeyV1alpha2Client {
return &KubekeyV1alpha2Client{c}
}
func setConfigDefaults(config *rest.Config) error {
gv := v1alpha2.GroupVersion
config.GroupVersion = &gv
config.APIPath = "/apis"
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
if config.UserAgent == "" {
config.UserAgent = rest.DefaultKubernetesUserAgent()
}
return nil
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *KubekeyV1alpha2Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
return c.restClient
}

View File

@@ -0,0 +1,179 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package externalversions
import (
reflect "reflect"
sync "sync"
time "time"
versioned "bytetrade.io/web3os/installer/clients/clientset/versioned"
internalinterfaces "bytetrade.io/web3os/installer/clients/informers/externalversions/internalinterfaces"
kubekey "bytetrade.io/web3os/installer/clients/informers/externalversions/kubekey"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache"
)
// SharedInformerOption defines the functional option type for SharedInformerFactory.
type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory
type sharedInformerFactory struct {
client versioned.Interface
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
lock sync.Mutex
defaultResync time.Duration
customResync map[reflect.Type]time.Duration
informers map[reflect.Type]cache.SharedIndexInformer
// startedInformers is used for tracking which informers have been started.
// This allows Start() to be called multiple times safely.
startedInformers map[reflect.Type]bool
}
// WithCustomResyncConfig sets a custom resync period for the specified informer types.
func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption {
return func(factory *sharedInformerFactory) *sharedInformerFactory {
for k, v := range resyncConfig {
factory.customResync[reflect.TypeOf(k)] = v
}
return factory
}
}
// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory.
func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption {
return func(factory *sharedInformerFactory) *sharedInformerFactory {
factory.tweakListOptions = tweakListOptions
return factory
}
}
// WithNamespace limits the SharedInformerFactory to the specified namespace.
func WithNamespace(namespace string) SharedInformerOption {
return func(factory *sharedInformerFactory) *sharedInformerFactory {
factory.namespace = namespace
return factory
}
}
// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces.
func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
return NewSharedInformerFactoryWithOptions(client, defaultResync)
}
// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory.
// Listers obtained via this SharedInformerFactory will be subject to the same filters
// as specified here.
// Deprecated: Please use NewSharedInformerFactoryWithOptions instead
func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {
return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))
}
// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
factory := &sharedInformerFactory{
client: client,
namespace: v1.NamespaceAll,
defaultResync: defaultResync,
informers: make(map[reflect.Type]cache.SharedIndexInformer),
startedInformers: make(map[reflect.Type]bool),
customResync: make(map[reflect.Type]time.Duration),
}
// Apply all options
for _, opt := range options {
factory = opt(factory)
}
return factory
}
// Start initializes all requested informers.
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
f.lock.Lock()
defer f.lock.Unlock()
for informerType, informer := range f.informers {
if !f.startedInformers[informerType] {
go informer.Run(stopCh)
f.startedInformers[informerType] = true
}
}
}
// WaitForCacheSync waits for all started informers' cache were synced.
func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
informers := func() map[reflect.Type]cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informers := map[reflect.Type]cache.SharedIndexInformer{}
for informerType, informer := range f.informers {
if f.startedInformers[informerType] {
informers[informerType] = informer
}
}
return informers
}()
res := map[reflect.Type]bool{}
for informType, informer := range informers {
res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)
}
return res
}
// InternalInformerFor returns the SharedIndexInformer for obj using an internal
// client.
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(obj)
informer, exists := f.informers[informerType]
if exists {
return informer
}
resyncPeriod, exists := f.customResync[informerType]
if !exists {
resyncPeriod = f.defaultResync
}
informer = newFunc(f.client, resyncPeriod)
f.informers[informerType] = informer
return informer
}
// SharedInformerFactory provides shared informers for resources in all known
// API group versions.
type SharedInformerFactory interface {
internalinterfaces.SharedInformerFactory
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
Kubekey() kubekey.Interface
}
func (f *sharedInformerFactory) Kubekey() kubekey.Interface {
return kubekey.New(f, f.namespace, f.tweakListOptions)
}

View File

@@ -0,0 +1,66 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package externalversions
import (
"fmt"
v1alpha1 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha1"
v1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache"
)
// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
// sharedInformers based on type
type GenericInformer interface {
Informer() cache.SharedIndexInformer
Lister() cache.GenericLister
}
type genericInformer struct {
informer cache.SharedIndexInformer
resource schema.GroupResource
}
// Informer returns the SharedIndexInformer.
func (f *genericInformer) Informer() cache.SharedIndexInformer {
return f.informer
}
// Lister returns the GenericLister.
func (f *genericInformer) Lister() cache.GenericLister {
return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)
}
// ForResource gives generic access to a shared informer of the matching type
// TODO extend this to unknown resources with a client pool
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
switch resource {
// Group=kubekey, Version=v1alpha1
case v1alpha1.SchemeGroupVersion.WithResource("clusters"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Kubekey().V1alpha1().Clusters().Informer()}, nil
// Group=kubekey, Version=v1alpha2
case v1alpha2.SchemeGroupVersion.WithResource("clusters"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Kubekey().V1alpha2().Clusters().Informer()}, nil
}
return nil, fmt.Errorf("no informer found for %v", resource)
}

View File

@@ -0,0 +1,39 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package internalinterfaces
import (
time "time"
versioned "bytetrade.io/web3os/installer/clients/clientset/versioned"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
cache "k8s.io/client-go/tools/cache"
)
// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
type SharedInformerFactory interface {
Start(stopCh <-chan struct{})
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
}
// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
type TweakListOptionsFunc func(*v1.ListOptions)

View File

@@ -0,0 +1,53 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package kubekey
import (
internalinterfaces "bytetrade.io/web3os/installer/clients/informers/externalversions/internalinterfaces"
v1alpha1 "bytetrade.io/web3os/installer/clients/informers/externalversions/kubekey/v1alpha1"
v1alpha2 "bytetrade.io/web3os/installer/clients/informers/externalversions/kubekey/v1alpha2"
)
// Interface provides access to each of this group's versions.
type Interface interface {
// V1alpha1 provides access to shared informers for resources in V1alpha1.
V1alpha1() v1alpha1.Interface
// V1alpha2 provides access to shared informers for resources in V1alpha2.
V1alpha2() v1alpha2.Interface
}
type group struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// V1alpha1 returns a new v1alpha1.Interface.
func (g *group) V1alpha1() v1alpha1.Interface {
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
}
// V1alpha2 returns a new v1alpha2.Interface.
func (g *group) V1alpha2() v1alpha2.Interface {
return v1alpha2.New(g.factory, g.namespace, g.tweakListOptions)
}

View File

@@ -0,0 +1,88 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha1
import (
"context"
time "time"
kubekeyv1alpha1 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha1"
versioned "bytetrade.io/web3os/installer/clients/clientset/versioned"
internalinterfaces "bytetrade.io/web3os/installer/clients/informers/externalversions/internalinterfaces"
v1alpha1 "bytetrade.io/web3os/installer/clients/listers/kubekey/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
cache "k8s.io/client-go/tools/cache"
)
// ClusterInformer provides access to a shared informer and lister for
// Clusters.
type ClusterInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1alpha1.ClusterLister
}
type clusterInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// NewClusterInformer constructs a new informer for Cluster type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewClusterInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredClusterInformer(client, resyncPeriod, indexers, nil)
}
// NewFilteredClusterInformer constructs a new informer for Cluster type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredClusterInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.KubekeyV1alpha1().Clusters().List(context.TODO(), options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.KubekeyV1alpha1().Clusters().Watch(context.TODO(), options)
},
},
&kubekeyv1alpha1.Cluster{},
resyncPeriod,
indexers,
)
}
func (f *clusterInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredClusterInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *clusterInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&kubekeyv1alpha1.Cluster{}, f.defaultInformer)
}
func (f *clusterInformer) Lister() v1alpha1.ClusterLister {
return v1alpha1.NewClusterLister(f.Informer().GetIndexer())
}

View File

@@ -0,0 +1,44 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha1
import (
internalinterfaces "bytetrade.io/web3os/installer/clients/informers/externalversions/internalinterfaces"
)
// Interface provides access to all the informers in this group version.
type Interface interface {
// Clusters returns a ClusterInformer.
Clusters() ClusterInformer
}
type version struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// Clusters returns a ClusterInformer.
func (v *version) Clusters() ClusterInformer {
return &clusterInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
}

View File

@@ -0,0 +1,88 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha2
import (
"context"
time "time"
kubekeyv1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
versioned "bytetrade.io/web3os/installer/clients/clientset/versioned"
internalinterfaces "bytetrade.io/web3os/installer/clients/informers/externalversions/internalinterfaces"
v1alpha2 "bytetrade.io/web3os/installer/clients/listers/kubekey/v1alpha2"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
cache "k8s.io/client-go/tools/cache"
)
// ClusterInformer provides access to a shared informer and lister for
// Clusters.
type ClusterInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1alpha2.ClusterLister
}
type clusterInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// NewClusterInformer constructs a new informer for Cluster type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewClusterInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredClusterInformer(client, resyncPeriod, indexers, nil)
}
// NewFilteredClusterInformer constructs a new informer for Cluster type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredClusterInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.KubekeyV1alpha2().Clusters().List(context.TODO(), options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.KubekeyV1alpha2().Clusters().Watch(context.TODO(), options)
},
},
&kubekeyv1alpha2.Cluster{},
resyncPeriod,
indexers,
)
}
func (f *clusterInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredClusterInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *clusterInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&kubekeyv1alpha2.Cluster{}, f.defaultInformer)
}
func (f *clusterInformer) Lister() v1alpha2.ClusterLister {
return v1alpha2.NewClusterLister(f.Informer().GetIndexer())
}

View File

@@ -0,0 +1,44 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha2
import (
internalinterfaces "bytetrade.io/web3os/installer/clients/informers/externalversions/internalinterfaces"
)
// Interface provides access to all the informers in this group version.
type Interface interface {
// Clusters returns a ClusterInformer.
Clusters() ClusterInformer
}
type version struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// Clusters returns a ClusterInformer.
func (v *version) Clusters() ClusterInformer {
return &clusterInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
}

View File

@@ -0,0 +1,67 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha1
import (
v1alpha1 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
// ClusterLister helps list Clusters.
// All objects returned here must be treated as read-only.
type ClusterLister interface {
// List lists all Clusters in the indexer.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1alpha1.Cluster, err error)
// Get retrieves the Cluster from the index for a given name.
// Objects returned here must be treated as read-only.
Get(name string) (*v1alpha1.Cluster, error)
ClusterListerExpansion
}
// clusterLister implements the ClusterLister interface.
type clusterLister struct {
indexer cache.Indexer
}
// NewClusterLister returns a new ClusterLister.
func NewClusterLister(indexer cache.Indexer) ClusterLister {
return &clusterLister{indexer: indexer}
}
// List lists all Clusters in the indexer.
func (s *clusterLister) List(selector labels.Selector) (ret []*v1alpha1.Cluster, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.Cluster))
})
return ret, err
}
// Get retrieves the Cluster from the index for a given name.
func (s *clusterLister) Get(name string) (*v1alpha1.Cluster, error) {
obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("cluster"), name)
}
return obj.(*v1alpha1.Cluster), nil
}

View File

@@ -0,0 +1,22 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha1
// ClusterListerExpansion allows custom methods to be added to
// ClusterLister.
type ClusterListerExpansion interface{}

View File

@@ -0,0 +1,67 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha2
import (
v1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
// ClusterLister helps list Clusters.
// All objects returned here must be treated as read-only.
type ClusterLister interface {
// List lists all Clusters in the indexer.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1alpha2.Cluster, err error)
// Get retrieves the Cluster from the index for a given name.
// Objects returned here must be treated as read-only.
Get(name string) (*v1alpha2.Cluster, error)
ClusterListerExpansion
}
// clusterLister implements the ClusterLister interface.
type clusterLister struct {
indexer cache.Indexer
}
// NewClusterLister returns a new ClusterLister.
func NewClusterLister(indexer cache.Indexer) ClusterLister {
return &clusterLister{indexer: indexer}
}
// List lists all Clusters in the indexer.
func (s *clusterLister) List(selector labels.Selector) (ret []*v1alpha2.Cluster, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha2.Cluster))
})
return ret, err
}
// Get retrieves the Cluster from the index for a given name.
func (s *clusterLister) Get(name string) (*v1alpha2.Cluster, error) {
obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha2.Resource("cluster"), name)
}
return obj.(*v1alpha2.Cluster), nil
}

View File

@@ -0,0 +1,22 @@
/*
Copyright 2020 The KubeSphere Authors.
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.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha2
// ClusterListerExpansion allows custom methods to be added to
// ClusterLister.
type ClusterListerExpansion interface{}

View File

@@ -0,0 +1,21 @@
package gpu
import (
"log"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
)
func NewCmdDisableGpu() *cobra.Command {
cmd := &cobra.Command{
Use: "disable",
Short: "Disable GPU drivers for Olares node",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.DisableGpuNode(); err != nil {
log.Fatalf("error: %v", err)
}
},
}
return cmd
}

21
cli/cmd/ctl/gpu/enable.go Normal file
View File

@@ -0,0 +1,21 @@
package gpu
import (
"log"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
)
func NewCmdEnableGpu() *cobra.Command {
cmd := &cobra.Command{
Use: "enable",
Short: "Enable GPU drivers for Olares node",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.EnableGpuNode(); err != nil {
log.Fatalf("error: %v", err)
}
},
}
return cmd
}

View File

@@ -0,0 +1,24 @@
package gpu
import (
"log"
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
)
func NewCmdInstallGpu() *cobra.Command {
o := options.NewInstallGpuOptions()
cmd := &cobra.Command{
Use: "install",
Short: "Install GPU drivers for Olares",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.InstallGpuDrivers(o); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.AddFlags(cmd)
return cmd
}

20
cli/cmd/ctl/gpu/root.go Normal file
View File

@@ -0,0 +1,20 @@
package gpu
import (
"github.com/spf13/cobra"
)
func NewCmdGpu() *cobra.Command {
rootGpuCmd := &cobra.Command{
Use: "gpu",
Short: "install / uninstall / status / disbale gpu commands for olares.",
}
rootGpuCmd.AddCommand(NewCmdInstallGpu())
rootGpuCmd.AddCommand(NewCmdUninstallpu())
rootGpuCmd.AddCommand(NewCmdEnableGpu())
rootGpuCmd.AddCommand(NewCmdDisableGpu())
rootGpuCmd.AddCommand(NewCmdUpgradeGpu())
rootGpuCmd.AddCommand(NewCmdGpuStatus())
return rootGpuCmd
}

21
cli/cmd/ctl/gpu/status.go Normal file
View File

@@ -0,0 +1,21 @@
package gpu
import (
"log"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
)
func NewCmdGpuStatus() *cobra.Command {
cmd := &cobra.Command{
Use: "status",
Short: "Print GPU drivers status",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.GpuDriverStatus(); err != nil {
log.Fatalf("error: %v", err)
}
},
}
return cmd
}

View File

@@ -0,0 +1,21 @@
package gpu
import (
"log"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
)
func NewCmdUninstallpu() *cobra.Command {
cmd := &cobra.Command{
Use: "uninstall",
Short: "uninstall GPU drivers for Olares",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.UninstallGpuDrivers(); err != nil {
log.Fatalf("error: %v", err)
}
},
}
return cmd
}

View File

@@ -0,0 +1,24 @@
package gpu
import (
"log"
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
)
func NewCmdUpgradeGpu() *cobra.Command {
o := options.NewInstallGpuOptions()
cmd := &cobra.Command{
Use: "upgrade",
Short: "upgrade GPU drivers for Olares",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.UpgradeGpuDrivers(o); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.AddFlags(cmd)
return cmd
}

23
cli/cmd/ctl/node/add.go Normal file
View File

@@ -0,0 +1,23 @@
package node
import (
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
"log"
)
func NewCmdAddNode() *cobra.Command {
o := options.NewAddNodeOptions()
cmd := &cobra.Command{
Use: "add",
Short: "add worker node to the cluster",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.AddNodePipeline(o); err != nil {
log.Fatal(err)
}
},
}
o.AddFlags(cmd)
return cmd
}

View File

@@ -0,0 +1 @@
package node

View File

@@ -0,0 +1,23 @@
package node
import (
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
"log"
)
func NewCmdMasterInfo() *cobra.Command {
o := options.NewMasterInfoOptions()
cmd := &cobra.Command{
Use: "masterinfo",
Short: "get information about master node, and check whether current node can be added to the cluster",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.MasterInfoPipeline(o); err != nil {
log.Fatal(err)
}
},
}
o.AddFlags(cmd)
return cmd
}

13
cli/cmd/ctl/node/root.go Normal file
View File

@@ -0,0 +1,13 @@
package node
import "github.com/spf13/cobra"
func NewNodeCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "node",
Short: "cluster node related operations",
}
cmd.AddCommand(NewCmdMasterInfo())
cmd.AddCommand(NewCmdAddNode())
return cmd
}

View File

@@ -0,0 +1,162 @@
package options
import (
"bytetrade.io/web3os/installer/pkg/common"
cc "bytetrade.io/web3os/installer/pkg/core/common"
"bytetrade.io/web3os/installer/pkg/phase/cluster"
"github.com/spf13/cobra"
)
type CliTerminusUninstallOptions struct {
Version string
BaseDir string
All bool
Phase string
Quiet bool
}
func NewCliTerminusUninstallOptions() *CliTerminusUninstallOptions {
return &CliTerminusUninstallOptions{}
}
func (o *CliTerminusUninstallOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
cmd.Flags().BoolVar(&o.All, "all", false, "Uninstall Olares completely, including prepared dependencies")
cmd.Flags().StringVar(&o.Phase, "phase", cluster.PhaseInstall.String(), "Uninstall from a specified phase and revert to the previous one. For example, using --phase install will remove the tasks performed in the 'install' phase, effectively returning the system to the 'prepare' state.")
cmd.Flags().BoolVar(&o.Quiet, "quiet", false, "Quiet mode, default: false")
}
type CliTerminusInstallOptions struct {
Version string
KubeType string
WithJuiceFS bool
MiniKubeProfile string
BaseDir string
common.SwapConfig
}
func NewCliTerminusInstallOptions() *CliTerminusInstallOptions {
return &CliTerminusInstallOptions{}
}
func (o *CliTerminusInstallOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
cmd.Flags().BoolVar(&o.WithJuiceFS, "with-juicefs", false, "Use JuiceFS as the rootfs for Olares workloads, rather than the local disk.")
cmd.Flags().StringVarP(&o.MiniKubeProfile, "profile", "p", "", "Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile)
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
(&o.SwapConfig).AddFlags(cmd.Flags())
}
type CliPrepareSystemOptions struct {
Version string
KubeType string
RegistryMirrors string
BaseDir string
MinikubeProfile string
}
func NewCliPrepareSystemOptions() *CliPrepareSystemOptions {
return &CliPrepareSystemOptions{}
}
func (o *CliPrepareSystemOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
cmd.Flags().StringVarP(&o.RegistryMirrors, "registry-mirrors", "r", "", "Docker Container registry mirrors, multiple mirrors are separated by commas")
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
cmd.Flags().StringVarP(&o.MinikubeProfile, "profile", "p", "", "Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile)
}
type ChangeIPOptions struct {
Version string
BaseDir string
NewMasterHost string
WSLDistribution string
MinikubeProfile string
}
func NewChangeIPOptions() *ChangeIPOptions {
return &ChangeIPOptions{}
}
func (o *ChangeIPOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
cmd.Flags().StringVar(&o.NewMasterHost, "new-master-host", "", "Update the master node's IP if it's changed, only in Linux worker node")
cmd.Flags().StringVarP(&o.WSLDistribution, "distribution", "d", "", "Set WSL distribution name, only in Windows platform, defaults to "+common.WSLDefaultDistribution)
cmd.Flags().StringVarP(&o.MinikubeProfile, "profile", "p", "", "Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile)
}
type PreCheckOptions struct {
Version string
BaseDir string
}
func NewPreCheckOptions() *PreCheckOptions {
return &PreCheckOptions{}
}
func (o *PreCheckOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
}
type InstallStorageOptions struct {
Version string
BaseDir string
}
func NewInstallStorageOptions() *InstallStorageOptions {
return &InstallStorageOptions{}
}
func (o *InstallStorageOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
}
type AddNodeOptions struct {
common.MasterHostConfig
Version string
BaseDir string
}
func NewAddNodeOptions() *AddNodeOptions {
return &AddNodeOptions{}
}
func (o *AddNodeOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
(&o.MasterHostConfig).AddFlags(cmd.Flags())
}
type MasterInfoOptions struct {
BaseDir string
common.MasterHostConfig
}
func NewMasterInfoOptions() *MasterInfoOptions {
return &MasterInfoOptions{}
}
func (o *MasterInfoOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
(&o.MasterHostConfig).AddFlags(cmd.Flags())
}
type UpgradeOptions struct {
Version string
BaseDir string
}
func NewUpgradeOptions() *UpgradeOptions {
return &UpgradeOptions{}
}
func (o *UpgradeOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set target Olares version to upgrade to, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
}

View File

@@ -0,0 +1,44 @@
package options
import (
cc "bytetrade.io/web3os/installer/pkg/core/common"
"github.com/spf13/cobra"
)
type CliDownloadWizardOptions struct {
Version string
KubeType string
BaseDir string
DownloadCdnUrl string
}
func NewCliDownloadWizardOptions() *CliDownloadWizardOptions {
return &CliDownloadWizardOptions{}
}
func (o *CliDownloadWizardOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
cmd.Flags().StringVar(&o.DownloadCdnUrl, "download-cdn-url", "", "Set the CDN accelerated download address in the format https://example.cdn.com. If not set, the default download address will be used")
}
type CliDownloadOptions struct {
Version string
KubeType string
Manifest string
BaseDir string
DownloadCdnUrl string
}
func NewCliDownloadOptions() *CliDownloadOptions {
return &CliDownloadOptions{}
}
func (o *CliDownloadOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir , defaults to $HOME/"+cc.DefaultBaseDir)
cmd.Flags().StringVar(&o.Manifest, "manifest", "", "Set package manifest file , defaults to {base-dir}/versions/v{version}/installation.manifest")
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
cmd.Flags().StringVar(&o.DownloadCdnUrl, "download-cdn-url", "", "Set the CDN accelerated download address in the format https://example.cdn.com. If not set, the default download address will be used")
}

View File

@@ -0,0 +1,32 @@
package options
import (
"bytetrade.io/web3os/installer/pkg/common"
cc "bytetrade.io/web3os/installer/pkg/core/common"
"fmt"
"github.com/spf13/cobra"
)
type GpuOptions struct {
Version string
BaseDir string
}
func (o *GpuOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
}
type InstallGpuOptions struct {
GpuOptions
Cuda string
}
func NewInstallGpuOptions() *InstallGpuOptions {
return &InstallGpuOptions{}
}
func (o *InstallGpuOptions) AddFlags(cmd *cobra.Command) {
o.GpuOptions.AddFlags(cmd)
cmd.Flags().StringVar(&o.Cuda, "cuda", "", fmt.Sprintf("The version of the CUDA driver, current supported versions are %s", common.CurrentVerifiedCudaVersion))
}

10
cli/cmd/ctl/os/backup.go Normal file
View File

@@ -0,0 +1,10 @@
package os
import (
backupssdk "bytetrade.io/web3os/backups-sdk"
"github.com/spf13/cobra"
)
func NewCmdBackup() *cobra.Command {
return backupssdk.NewBackupCommands()
}

View File

@@ -0,0 +1,23 @@
package os
import (
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
"log"
)
func NewCmdChangeIP() *cobra.Command {
o := options.NewChangeIPOptions()
cmd := &cobra.Command{
Use: "change-ip",
Short: "change The IP address of Olares OS",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.ChangeIPPipeline(o); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.AddFlags(cmd)
return cmd
}

View File

@@ -0,0 +1,72 @@
package os
import (
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
"log"
)
func NewCmdRootDownload() *cobra.Command {
rootDownloadCmd := &cobra.Command{
Use: "download",
Short: "Download the packages and components needed to install Olares",
}
rootDownloadCmd.AddCommand(NewCmdCheckDownload())
rootDownloadCmd.AddCommand(NewCmdDownload())
rootDownloadCmd.AddCommand(NewCmdDownloadWizard())
return rootDownloadCmd
}
func NewCmdDownload() *cobra.Command {
o := options.NewCliDownloadOptions()
cmd := &cobra.Command{
Use: "component",
Short: "Download the packages and components needed to install Olares",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.DownloadInstallationPackage(o); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.AddFlags(cmd)
return cmd
}
func NewCmdDownloadWizard() *cobra.Command {
o := options.NewCliDownloadWizardOptions()
cmd := &cobra.Command{
Use: "wizard",
Short: "Download the Olares installation wizard",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.DownloadInstallationWizard(o); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.AddFlags(cmd)
return cmd
}
func NewCmdCheckDownload() *cobra.Command {
o := options.NewCliDownloadOptions()
cmd := &cobra.Command{
Use: "check",
Short: "Check Downloaded Olares Installation Package",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.CheckDownloadInstallationPackage(o); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.AddFlags(cmd)
return cmd
}

17
cli/cmd/ctl/os/info.go Normal file
View File

@@ -0,0 +1,17 @@
package os
import (
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
)
func NewCmdPrintInfo() *cobra.Command {
cmd := &cobra.Command{
Use: "info",
Short: "Print Olares info",
Run: func(cmd *cobra.Command, args []string) {
pipelines.PrintTerminusInfo()
},
}
return cmd
}

35
cli/cmd/ctl/os/install.go Normal file
View File

@@ -0,0 +1,35 @@
package os
import (
"log"
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
)
type InstallOsOptions struct {
InstallOptions *options.CliTerminusInstallOptions
}
func NewInstallOsOptions() *InstallOsOptions {
return &InstallOsOptions{
InstallOptions: options.NewCliTerminusInstallOptions(),
}
}
func NewCmdInstallOs() *cobra.Command {
o := NewInstallOsOptions()
cmd := &cobra.Command{
Use: "install",
Short: "Install Olares",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.CliInstallTerminusPipeline(o.InstallOptions); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.InstallOptions.AddFlags(cmd)
cmd.AddCommand(NewCmdInstallStorage())
return cmd
}

522
cli/cmd/ctl/os/logs.go Normal file
View File

@@ -0,0 +1,522 @@
package os
import (
"archive/tar"
"bytetrade.io/web3os/installer/pkg/common"
"bytetrade.io/web3os/installer/pkg/core/util"
"compress/gzip"
"fmt"
"io"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/spf13/cobra"
)
// LogCollectOptions holds options for collecting logs
type LogCollectOptions struct {
// Time duration to collect logs for (empty means all available logs)
Since string
// Maximum number of lines to collect per log source
MaxLines int
// Output directory for collected logs
OutputDir string
// Components to collect logs from (empty means all)
Components []string
// Whether to ignore errors from kubectl commands
IgnoreKubeErrors bool
}
var servicesToCollectLogs = []string{"k3s", "containerd", "olaresd", "kubelet", "juicefs", "redis", "minio", "etcd", "NetworkManager"}
func collectLogs(options *LogCollectOptions) error {
if os.Getuid() != 0 {
return fmt.Errorf("os: please run as root")
}
if err := os.MkdirAll(options.OutputDir, 0755); err != nil {
return fmt.Errorf("failed to create output directory: %v", err)
}
timestamp := time.Now().Format("20060102-150405")
archiveName := filepath.Join(options.OutputDir, fmt.Sprintf("olares-logs-%s.tar.gz", timestamp))
archive, err := os.Create(archiveName)
if err != nil {
return fmt.Errorf("failed to create archive: %v", err)
}
defer archive.Close()
gw := gzip.NewWriter(archive)
defer gw.Close()
tw := tar.NewWriter(gw)
defer tw.Close()
// collect systemd service logs
if err := collectSystemdLogs(tw, options); err != nil {
return fmt.Errorf("failed to collect systemd logs: %v", err)
}
fmt.Println("collecting dmesg logs ...")
if err := collectDmesgLogs(tw, options); err != nil {
return fmt.Errorf("failed to collect dmesg logs: %v", err)
}
fmt.Println("collecting logs from kubernetes cluster...")
if err := collectKubernetesLogs(tw, options); err != nil {
return fmt.Errorf("failed to collect kubernetes logs: %v", err)
}
fmt.Println("collecting olares-cli logs...")
if err := collectOlaresCLILogs(tw, options); err != nil {
return fmt.Errorf("failed to collect OlaresCLI logs: %v", err)
}
fmt.Println("collecting network configs...")
if err := collectNetworkConfigs(tw, options); err != nil {
return fmt.Errorf("failed to collect network configs: %v", err)
}
fmt.Printf("logs have been collected and archived in: %s\n", archiveName)
return nil
}
func collectOlaresCLILogs(tw *tar.Writer, options *LogCollectOptions) error {
basedir, err := getBaseDir()
if err != nil {
return err
}
cliLogDir := filepath.Join(basedir, "logs")
if _, err := os.Stat(cliLogDir); err != nil {
fmt.Printf("warning: directory %s does not exist, skipping collecting olares-cli logs\n", cliLogDir)
return nil
}
err = filepath.Walk(cliLogDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
srcFile, err := os.Open(path)
if err != nil {
return fmt.Errorf("failed to open file %s: %v", path, err)
}
defer srcFile.Close()
relPath, err := filepath.Rel(cliLogDir, path)
if err != nil {
return fmt.Errorf("failed to get relative path: %v", err)
}
header := &tar.Header{
Name: filepath.Join("olares-cli", relPath),
Mode: 0644,
Size: info.Size(),
ModTime: info.ModTime(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write header for %s: %v", path, err)
}
// stream file contents to tar
if _, err := io.CopyN(tw, srcFile, header.Size); err != nil {
return fmt.Errorf("failed to write data for %s: %v", path, err)
}
return nil
})
if err != nil {
return fmt.Errorf("failed to collect olares-cli logs from %s: %v", cliLogDir, err)
}
return nil
}
func collectSystemdLogs(tw *tar.Writer, options *LogCollectOptions) error {
// Create temp directory for log files
tempDir, err := os.MkdirTemp("", "olares-logs-*")
if err != nil {
return fmt.Errorf("failed to create temp directory: %v", err)
}
defer os.RemoveAll(tempDir)
var services []string
if len(options.Components) > 0 {
services = options.Components
} else {
services = servicesToCollectLogs
}
for _, service := range services {
if !checkServiceExists(service) {
if len(options.Components) > 0 {
fmt.Printf("warning: required service %s not found\n", service)
}
continue
}
fmt.Printf("collecting logs for service: %s\n", service)
// create temp file for this service's logs
tempFile := filepath.Join(tempDir, fmt.Sprintf("%s.log", service))
logFile, err := os.Create(tempFile)
if err != nil {
return fmt.Errorf("failed to create temp file for %s: %v", service, err)
}
args := []string{"-u", service}
if options.Since != "" {
if !strings.HasPrefix(options.Since, "-") {
options.Since = "-" + options.Since
}
args = append(args, "--since", options.Since)
}
if options.MaxLines > 0 {
args = append(args, "-n", fmt.Sprintf("%d", options.MaxLines))
}
if options.Since != "" && options.MaxLines > 0 {
// this is a journalctl bug
// where -S and -n combined results in the latest logs truncated
// rather than the old logs
// a -r corrects the truncate behavior
args = append(args, "-r")
}
// execute journalctl and write directly to temp file
// don't just use the command output because that's too memory-consuming
// the same logic goes to the os.Open and io.Copy rather than os.ReadFile
cmd := exec.Command("journalctl", args...)
cmd.Stdout = logFile
if err := cmd.Run(); err != nil {
logFile.Close()
return fmt.Errorf("failed to collect logs for %s: %v", service, err)
continue
}
logFile.Close()
// get file info for the tar header
fi, err := os.Stat(tempFile)
if err != nil {
return fmt.Errorf("failed to stat temp file for %s: %v", service, err)
}
logFile, err = os.Open(tempFile)
if err != nil {
return fmt.Errorf("failed to open temp file for %s: %v", service, err)
}
defer logFile.Close()
header := &tar.Header{
Name: fmt.Sprintf("%s.log", service),
Mode: 0644,
Size: fi.Size(),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write header for %s: %v", service, err)
}
if _, err := io.CopyN(tw, logFile, header.Size); err != nil {
return fmt.Errorf("failed to write logs for %s: %v", service, err)
}
}
return nil
}
func collectDmesgLogs(tw *tar.Writer, options *LogCollectOptions) error {
cmd := exec.Command("dmesg")
output, err := cmd.Output()
if err != nil {
return err
}
header := &tar.Header{
Name: "dmesg.log",
Mode: 0644,
Size: int64(len(output)),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write dmesg header: %v", err)
}
if _, err := tw.Write(output); err != nil {
return fmt.Errorf("failed to write dmesg data: %v", err)
}
return nil
}
func collectKubernetesLogs(tw *tar.Writer, options *LogCollectOptions) error {
podsLogDir := "/var/log/pods"
if _, err := os.Stat(podsLogDir); err != nil {
fmt.Printf("warning: directory %s does not exist, skipping collecting pod logs\n", podsLogDir)
} else {
err := filepath.Walk(podsLogDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
srcFile, err := os.Open(path)
if err != nil {
return fmt.Errorf("failed to open file %s: %v", path, err)
}
defer srcFile.Close()
relPath, err := filepath.Rel(podsLogDir, path)
if err != nil {
return fmt.Errorf("failed to get relative path: %v", err)
}
header := &tar.Header{
Name: filepath.Join("pods", relPath),
Mode: 0644,
Size: info.Size(),
ModTime: info.ModTime(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write header for %s: %v", path, err)
}
// stream file contents to tar
if _, err := io.CopyN(tw, srcFile, header.Size); err != nil {
return fmt.Errorf("failed to write data for %s: %v", path, err)
}
return nil
})
if err != nil {
return fmt.Errorf("failed to collect pod logs from /var/log/pods: %v", err)
}
}
if _, err := util.GetCommand("kubectl"); err != nil {
fmt.Printf("warning: kubectl not found, skipping collecting cluster info from kube-apiserver\n")
return nil
}
cmd := exec.Command("kubectl", "get", "pods", "--all-namespaces", "-o", "wide")
output, err := tryKubectlCommand(cmd, "get pods", options)
if err != nil && !options.IgnoreKubeErrors {
return err
}
if err == nil {
header := &tar.Header{
Name: "pods-list.txt",
Mode: 0644,
Size: int64(len(output)),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write pods list header: %v", err)
}
if _, err := tw.Write(output); err != nil {
return fmt.Errorf("failed to write pods list data: %v", err)
}
}
cmd = exec.Command("kubectl", "describe", "pods", "--all-namespaces")
output, err = tryKubectlCommand(cmd, "describe pods", options)
if err != nil && !options.IgnoreKubeErrors {
return err
}
if err == nil {
header := &tar.Header{
Name: "pods-describe.txt",
Mode: 0644,
Size: int64(len(output)),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write pods description header: %v", err)
}
if _, err := tw.Write(output); err != nil {
return fmt.Errorf("failed to write pods description data: %v", err)
}
}
cmd = exec.Command("kubectl", "describe", "node")
output, err = tryKubectlCommand(cmd, "describe node", options)
if err != nil && !options.IgnoreKubeErrors {
return err
}
if err == nil {
header := &tar.Header{
Name: "node-describe.txt",
Mode: 0644,
Size: int64(len(output)),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write node description header: %v", err)
}
if _, err := tw.Write(output); err != nil {
return fmt.Errorf("failed to write node description data: %v", err)
}
}
return nil
}
func collectNetworkConfigs(tw *tar.Writer, options *LogCollectOptions) error {
if _, err := util.GetCommand("ip"); err == nil {
cmd := exec.Command("ip", "address")
output, err := cmd.Output()
if err != nil {
return err
}
header := &tar.Header{
Name: "ip-address.txt",
Mode: 0644,
Size: int64(len(output)),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write ip address header: %v", err)
}
if _, err := tw.Write(output); err != nil {
return fmt.Errorf("failed to write ip address data: %v", err)
}
cmd = exec.Command("ip", "route")
output, err = cmd.Output()
if err != nil {
return err
}
header = &tar.Header{
Name: "ip-route.txt",
Mode: 0644,
Size: int64(len(output)),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write ip route header: %v", err)
}
if _, err := tw.Write(output); err != nil {
return fmt.Errorf("failed to write ip route data: %v", err)
}
}
if _, err := util.GetCommand("iptables-save"); err == nil {
cmd := exec.Command("iptables-save")
output, err := cmd.Output()
if err != nil {
return err
}
header := &tar.Header{
Name: "iptables.txt",
Mode: 0644,
Size: int64(len(output)),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write iptables header: %v", err)
}
if _, err := tw.Write(output); err != nil {
return fmt.Errorf("failed to write iptables data: %v", err)
}
}
if _, err := util.GetCommand("nft"); err == nil {
cmd := exec.Command("nft", "list", "ruleset")
output, err := cmd.Output()
if err != nil {
return err
}
header := &tar.Header{
Name: "nftables.txt",
Mode: 0644,
Size: int64(len(output)),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write nftables header: %v", err)
}
if _, err := tw.Write(output); err != nil {
return fmt.Errorf("failed to write nftables data: %v", err)
}
}
return nil
}
func getBaseDir() (string, error) {
// quick path to get basedir from argument instance
arg := &common.Argument{}
if err := arg.LoadReleaseInfo(); err != nil {
return "", fmt.Errorf("failed to load olares release info: %v", err)
}
if arg.BaseDir != "" {
return arg.BaseDir, nil
}
homeDir, err := util.Home()
if err != nil {
return "", fmt.Errorf("failed to get home dir: %v", err)
}
return filepath.Join(homeDir, ".olares"), nil
}
func tryKubectlCommand(cmd *exec.Cmd, description string, options *LogCollectOptions) ([]byte, error) {
output, err := cmd.Output()
if err != nil {
if options.IgnoreKubeErrors {
fmt.Printf("warning: failed to %s: %v\n", description, err)
return nil, err
}
return nil, fmt.Errorf("failed to %s: %v", description, err)
}
return output, nil
}
// checkService verifies if a systemd service exists
func checkServiceExists(service string) bool {
if !strings.HasSuffix(service, ".service") {
service += ".service"
}
cmd := exec.Command("systemctl", "list-unit-files", "--no-legend", service)
return cmd.Run() == nil
}
func NewCmdLogs() *cobra.Command {
options := &LogCollectOptions{
Since: "7d",
MaxLines: 3000,
OutputDir: "./olares-logs",
IgnoreKubeErrors: false,
}
cmd := &cobra.Command{
Use: "logs",
Short: "Collect logs from all Olares system components",
Long: `Collect logs from various Olares system components, that may or may not be installed on this machine, including:
- K3s/Kubelet logs
- Containerd logs
- JuiceFS logs
- Redis logs
- MinIO logs
- etcd logs
- Olaresd logs
- olares-cli logs
- network configurations
- Kubernetes pod info and logs
- Kubernetes node info`,
Run: func(cmd *cobra.Command, args []string) {
if err := collectLogs(options); err != nil {
log.Fatalf("error: %v", err)
}
},
}
cmd.Flags().StringVar(&options.Since, "since", options.Since, "Only return logs newer than a relative duration like 5s, 2m, or 3h, to limit the log file")
cmd.Flags().IntVar(&options.MaxLines, "max-lines", options.MaxLines, "Maximum number of lines to collect per log source, to limit the log file size")
cmd.Flags().StringVar(&options.OutputDir, "output-dir", options.OutputDir, "Directory to store collected logs, will be created if not existing")
cmd.Flags().StringSliceVar(&options.Components, "components", nil, "Specific components (systemd service) to collect logs from (comma-separated). If empty, collects from all Olares-related components that can be found")
cmd.Flags().BoolVar(&options.IgnoreKubeErrors, "ignore-kube-errors", options.IgnoreKubeErrors, "Continue collecting logs even if kubectl commands fail, e.g., when kube-apiserver is not reachable")
return cmd
}

View File

@@ -0,0 +1,23 @@
package os
import (
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
"log"
)
func NewCmdPrecheck() *cobra.Command {
o := options.NewPreCheckOptions()
cmd := &cobra.Command{
Use: "precheck",
Short: "precheck the installation compatibility of the system",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.StartPreCheckPipeline(o); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.AddFlags(cmd)
return cmd
}

34
cli/cmd/ctl/os/prepare.go Normal file
View File

@@ -0,0 +1,34 @@
package os
import (
"log"
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
)
type PrepareSystemOptions struct {
PrepareOptions *options.CliPrepareSystemOptions
}
func NewPrepareSystemOptions() *PrepareSystemOptions {
return &PrepareSystemOptions{
PrepareOptions: options.NewCliPrepareSystemOptions(),
}
}
func NewCmdPrepare() *cobra.Command {
o := NewPrepareSystemOptions()
cmd := &cobra.Command{
Use: "prepare [component1 component2 ...]",
Short: "Prepare install",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.PrepareSystemPipeline(o.PrepareOptions, args); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.PrepareOptions.AddFlags(cmd)
return cmd
}

84
cli/cmd/ctl/os/release.go Normal file
View File

@@ -0,0 +1,84 @@
package os
import (
"bytetrade.io/web3os/installer/pkg/core/common"
"bytetrade.io/web3os/installer/pkg/core/util"
"bytetrade.io/web3os/installer/pkg/release/builder"
"fmt"
"os"
"os/user"
"path/filepath"
"strings"
"time"
"github.com/spf13/cobra"
)
func NewCmdRelease() *cobra.Command {
var (
baseDir string
version string
cdn string
ignoreMissingImages bool
extract bool
)
cmd := &cobra.Command{
Use: "release",
Short: "Build release based on a local Olares repository",
Run: func(cmd *cobra.Command, args []string) {
cwd, err := os.Getwd()
if err != nil {
fmt.Printf("failed to get current working directory: %s\n", err)
os.Exit(1)
}
if !strings.HasPrefix(strings.ToLower(filepath.Base(cwd)), "olares") {
fmt.Println("error: please run release command under the root path of Olares repo")
os.Exit(1)
}
if baseDir == "" {
usr, err := user.Current()
if err != nil {
fmt.Printf("failed to get current user: %s\n", err)
os.Exit(1)
}
baseDir = filepath.Join(usr.HomeDir, common.DefaultBaseDir)
fmt.Printf("--base-dir unspecified, using: %s\n", baseDir)
time.Sleep(1 * time.Second)
}
if version == "" {
version = fmt.Sprintf("0.0.0-local-dev-%s", time.Now().Format("20060102150405"))
fmt.Printf("--version unspecified, using: %s\n", version)
time.Sleep(1 * time.Second)
}
wizardFile, err := builder.NewBuilder(cwd, version, cdn, ignoreMissingImages).Build()
if err != nil {
fmt.Printf("failed to build release: %s\n", err)
os.Exit(1)
}
fmt.Printf("\nsuccessfully built release\nversion: %s\n package: %s\n", version, wizardFile)
if extract {
dest := filepath.Join(baseDir, "versions", "v"+version)
if err := os.MkdirAll(dest, 0755); err != nil {
fmt.Printf("Failed to create new version directory for this release: %s\n", err)
os.Exit(1)
}
if err := util.Untar(wizardFile, dest); err != nil {
fmt.Printf("failed to extract release package: %s\n", err)
os.Exit(1)
}
fmt.Printf("\nrelease package is extracted to: %s\n", dest)
}
},
}
cmd.Flags().StringVarP(&baseDir, "base-dir", "b", "", "base directory of Olares, where this release will be extracted to as a new version if --extract/-e is not disabled, defaults to $HOME/"+common.DefaultBaseDir)
cmd.Flags().StringVarP(&version, "version", "v", "", "version of this release, defaults to 0.0.0-local-dev-{yyyymmddhhmmss}")
cmd.Flags().StringVar(&cdn, "download-cdn-url", common.DownloadUrl, "CDN used for downloading checksums of dependencies and images")
cmd.Flags().BoolVar(&ignoreMissingImages, "ignore-missing-images", true, "ignore missing images when downloading cheksums from CDN, only disable this if no new image is added, or the build may fail because the image is not uploaded to the CDN yet")
cmd.Flags().BoolVarP(&extract, "extract", "e", true, "extract this release to --base-dir after build, this can be disabled if only the release file itself is needed")
return cmd
}

28
cli/cmd/ctl/os/root.go Normal file
View File

@@ -0,0 +1,28 @@
package os
import (
"os/exec"
"github.com/spf13/cobra"
)
func NewOSCommands() []*cobra.Command {
_ = exec.Command("/bin/bash", "-c", "ulimit -u 65535").Run()
_ = exec.Command("/bin/bash", "-c", "ulimit -n 65535").Run()
return []*cobra.Command{
NewCmdPrecheck(),
NewCmdRootDownload(),
NewCmdPrepare(),
NewCmdInstallOs(),
NewCmdUninstallOs(),
NewCmdChangeIP(),
NewCmdRelease(),
NewCmdPrintInfo(),
NewCmdBackup(),
NewCmdLogs(),
NewCmdStart(),
NewCmdStop(),
NewCmdUpgradeOs(),
}
}

View File

@@ -0,0 +1,41 @@
package os
import (
"time"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
"log"
)
func NewCmdStart() *cobra.Command {
cmd := &cobra.Command{
Use: "start",
Short: "Start the Olares OS",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.StartOlares(); err != nil {
log.Fatalf("error: %v", err)
}
},
}
return cmd
}
func NewCmdStop() *cobra.Command {
var (
timeout time.Duration
checkInterval time.Duration
)
cmd := &cobra.Command{
Use: "stop",
Short: "Stop the Olares OS",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.StopOlares(timeout, checkInterval); err != nil {
log.Fatalf("error: %v", err)
}
},
}
cmd.Flags().DurationVarP(&timeout, "timeout", "t", 1*time.Minute, "Timeout for graceful shutdown before using SIGKILL")
cmd.Flags().DurationVarP(&checkInterval, "check-interval", "i", 10*time.Second, "Interval between checks for remaining processes")
return cmd
}

24
cli/cmd/ctl/os/storage.go Normal file
View File

@@ -0,0 +1,24 @@
package os
import (
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
"log"
)
func NewCmdInstallStorage() *cobra.Command {
o := options.NewInstallStorageOptions()
cmd := &cobra.Command{
Use: "storage",
Short: "install a storage backend for the Olares shared filesystem, or in the case of external storage, validate the config",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.CliInstallStoragePipeline(o); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.AddFlags(cmd)
return cmd
}

View File

@@ -0,0 +1,34 @@
package os
import (
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
"log"
)
type UninstallOsOptions struct {
UninstallOptions *options.CliTerminusUninstallOptions
}
func NewUninstallOsOptions() *UninstallOsOptions {
return &UninstallOsOptions{
UninstallOptions: options.NewCliTerminusUninstallOptions(),
}
}
func NewCmdUninstallOs() *cobra.Command {
o := NewUninstallOsOptions()
cmd := &cobra.Command{
Use: "uninstall",
Short: "Uninstall Olares",
Run: func(cmd *cobra.Command, args []string) {
err := pipelines.UninstallTerminusPipeline(o.UninstallOptions)
if err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.UninstallOptions.AddFlags(cmd)
return cmd
}

48
cli/cmd/ctl/os/upgrade.go Normal file
View File

@@ -0,0 +1,48 @@
package os
import (
"log"
"bytetrade.io/web3os/installer/cmd/ctl/options"
"bytetrade.io/web3os/installer/pkg/pipelines"
"github.com/spf13/cobra"
)
type UpgradeOsOptions struct {
UpgradeOptions *options.UpgradeOptions
}
func NewUpgradeOsOptions() *UpgradeOsOptions {
return &UpgradeOsOptions{
UpgradeOptions: options.NewUpgradeOptions(),
}
}
func NewCmdUpgradeOs() *cobra.Command {
o := NewUpgradeOsOptions()
cmd := &cobra.Command{
Use: "upgrade",
Short: "Upgrade Olares to a newer version",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.UpgradeOlaresPipeline(o.UpgradeOptions); err != nil {
log.Fatalf("error: %v", err)
}
},
}
o.UpgradeOptions.AddFlags(cmd)
cmd.AddCommand(NewCmdUpgradePrecheck())
return cmd
}
func NewCmdUpgradePrecheck() *cobra.Command {
cmd := &cobra.Command{
Use: "precheck",
Short: "Precheck Olares for Upgrade",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.UpgradePreCheckPipeline(); err != nil {
log.Fatalf("error: %v", err)
}
},
}
return cmd
}

View File

@@ -0,0 +1,39 @@
package osinfo
import (
"fmt"
"bytetrade.io/web3os/installer/pkg/core/connector"
"github.com/spf13/cobra"
)
func NewCmdInfo() *cobra.Command {
infoCmd := &cobra.Command{
Use: "osinfo",
Short: "Print system information, etc.",
Long: "help for printing info",
}
infoCmd.AddCommand(showInfoCommand())
return infoCmd
}
func showInfoCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "show",
Short: "Print os information",
Long: "help for printing os info",
Run: func(cmd *cobra.Command, args []string) {
systemInfo := connector.GetSystemInfo()
host := systemInfo.HostInfo
fmt.Printf(`OS_TYPE=%s
OS_PLATFORM=%s
OS_ARCH=%s
OS_VERSION=%s
OS_KERNEL=%s
OS_INFO=%s
`, host.OsType, host.OsPlatformFamily, host.OsArch, host.OsVersion, host.OsKernel, host.OsInfo)
},
}
return cmd
}

26
cli/cmd/ctl/root.go Executable file
View File

@@ -0,0 +1,26 @@
package ctl
import (
"bytetrade.io/web3os/installer/cmd/ctl/gpu"
"bytetrade.io/web3os/installer/cmd/ctl/node"
"bytetrade.io/web3os/installer/cmd/ctl/os"
"bytetrade.io/web3os/installer/cmd/ctl/osinfo"
"bytetrade.io/web3os/installer/version"
"github.com/spf13/cobra"
)
func NewDefaultCommand() *cobra.Command {
cmds := &cobra.Command{
Use: "olares-cli",
Short: "Olares Installer",
CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true},
Version: version.VERSION,
}
cmds.AddCommand(osinfo.NewCmdInfo())
cmds.AddCommand(os.NewOSCommands()...)
cmds.AddCommand(node.NewNodeCommand())
cmds.AddCommand(gpu.NewCmdGpu())
return cmds
}

19
cli/cmd/main.go Executable file
View File

@@ -0,0 +1,19 @@
package main
import (
"os"
"os/exec"
"bytetrade.io/web3os/installer/cmd/ctl"
)
func main() {
cmd := ctl.NewDefaultCommand()
_ = exec.Command("/bin/bash", "-c", "ulimit -u 65535").Run()
_ = exec.Command("/bin/bash", "-c", "ulimit -n 65535").Run()
if err := cmd.Execute(); err != nil {
// fmt.Println(err)
os.Exit(1)
}
}

View File

@@ -0,0 +1,985 @@
/*
Copyright 2020 The KubeSphere Authors.
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 kubekey
import (
"bytes"
"bytetrade.io/web3os/installer/pkg/core/logger"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"os"
"regexp"
"strings"
"time"
"sigs.k8s.io/yaml"
kubekeyv1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/util/wait"
yamlV2 "gopkg.in/yaml.v2"
kubeErr "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/predicate"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
)
const (
CreateCluster = "create cluster"
AddNodes = "add nodes"
)
// ClusterReconciler reconciles a Cluster object
type ClusterReconciler struct {
client.Client
Scheme *runtime.Scheme
}
// +kubebuilder:rbac:groups=kubekey.kubesphere.io,resources=clusters,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=kubekey.kubesphere.io,resources=clusters/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=core,resources=*,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=storage.k8s.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=*
// +kubebuilder:rbac:groups=installer.kubesphere.io,resources=clusterconfigurations,verbs=*
// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=apiregistration.k8s.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=auditing.kubesphere.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=autoscaling,resources=*,verbs=*
// +kubebuilder:rbac:groups=certificates.k8s.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=config.istio.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=core.kubefed.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=devops.kubesphere.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=events.kubesphere.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=batch,resources=*,verbs=*
// +kubebuilder:rbac:groups=extensions,resources=*,verbs=*
// +kubebuilder:rbac:groups=iam.kubesphere.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=jaegertracing.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=logging.kubesphere.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=*,verbs=*
// +kubebuilder:rbac:groups=networking.istio.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=notification.kubesphere.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=policy,resources=*,verbs=*
// +kubebuilder:rbac:groups=storage.kubesphere.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=tenant.kubesphere.io,resources=*,verbs=*
// +kubebuilder:rbac:groups=cluster.kubesphere.io,resources=*,verbs=*
func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
cluster := &kubekeyv1alpha2.Cluster{}
cmFound := &corev1.ConfigMap{}
jobFound := &batchv1.Job{}
var (
clusterAlreadyExist bool
addHosts, removeHosts []kubekeyv1alpha2.HostCfg
)
// Fetch the Cluster object
if err := r.Get(ctx, req.NamespacedName, cluster); err != nil {
if kubeErr.IsNotFound(err) {
logger.Info("Cluster resource not found. Ignoring since object must be deleted")
return ctrl.Result{}, nil
}
logger.Error(err, "Failed to get Cluster")
return ctrl.Result{}, err
}
// Check if the configMap already exists
if err := r.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: req.Namespace}, cmFound); err == nil {
clusterAlreadyExist = true
}
// create a new cluster
if cluster.Status.NodesCount == 0 {
// Ensure that the current pipeline execution is complete
if cluster.Status.PiplineInfo.Status != "" {
return ctrl.Result{RequeueAfter: 3 * time.Second}, nil
}
if !clusterAlreadyExist {
// create kubesphere cluster
if err := newKubeSphereCluster(r, cluster); err != nil {
return ctrl.Result{RequeueAfter: 2 * time.Second}, err
}
if err := updateClusterConfigMap(r, ctx, cluster, cmFound); err != nil {
return ctrl.Result{RequeueAfter: 2 * time.Second}, err
}
return ctrl.Result{RequeueAfter: 1 * time.Second}, nil
}
// If the CR cluster define current cluster
nodes, err := currentClusterDiff(r, ctx, cluster)
if err != nil {
return ctrl.Result{RequeueAfter: 2 * time.Second}, err
}
if len(nodes) != 0 {
logger.Info("Cluster resource defines current cluster")
if err := adaptExistedCluster(nodes, cluster); err != nil {
return ctrl.Result{RequeueAfter: 2 * time.Second}, err
}
if err := r.Status().Update(context.TODO(), cluster); err != nil {
return ctrl.Result{RequeueAfter: 2 * time.Second}, err
}
return ctrl.Result{RequeueAfter: 1 * time.Second}, nil
}
// If the CR cluster define other existed cluster
otherClusterNodes, err := otherClusterDiff(r, ctx, cluster)
if err != nil {
return ctrl.Result{RequeueAfter: 2 * time.Second}, err
}
if len(otherClusterNodes) != 0 {
logger.Info("Cluster resource defines other existed cluster")
if err := adaptExistedCluster(otherClusterNodes, cluster); err != nil {
return ctrl.Result{RequeueAfter: 2 * time.Second}, err
}
if err := r.Status().Update(context.TODO(), cluster); err != nil {
return ctrl.Result{RequeueAfter: 2 * time.Second}, err
}
return ctrl.Result{RequeueAfter: 1 * time.Second}, nil
}
if err := updateRunJob(r, req, ctx, cluster, jobFound, CreateCluster); err != nil {
return ctrl.Result{RequeueAfter: 2 * time.Second}, err
}
addHosts = cluster.Spec.Hosts
sendHostsAction(1, addHosts)
// Ensure that the cluster has been created successfully, otherwise re-enter Reconcile.
return ctrl.Result{RequeueAfter: 3 * time.Second}, nil
}
// add nodes to cluster
if cluster.Status.NodesCount != 0 && len(cluster.Spec.Hosts) > cluster.Status.NodesCount {
// Ensure that the current pipeline execution is complete
if cluster.Status.PiplineInfo.Status != "" {
return ctrl.Result{RequeueAfter: 3 * time.Second}, nil
}
if err := updateClusterConfigMap(r, ctx, cluster, cmFound); err != nil {
return ctrl.Result{}, err
}
if err := updateRunJob(r, req, ctx, cluster, jobFound, AddNodes); err != nil {
return ctrl.Result{Requeue: true}, err
}
currentNodes := map[string]string{}
for _, node := range cluster.Status.Nodes {
currentNodes[node.Hostname] = node.Hostname
}
for _, host := range cluster.Spec.Hosts {
if _, ok := currentNodes[host.Name]; !ok {
addHosts = append(addHosts, host)
}
}
sendHostsAction(1, addHosts)
// Ensure that the nodes has been added successfully, otherwise re-enter Reconcile.
return ctrl.Result{RequeueAfter: 3 * time.Second}, nil
}
// Completion of pipeline execution, clearing pipeline status information
cluster.Status.PiplineInfo.Status = ""
if err := r.Status().Update(context.TODO(), cluster); err != nil {
return ctrl.Result{RequeueAfter: 3 * time.Second}, err
}
// Synchronizing Node Information
kubeConfigCm := &corev1.ConfigMap{}
if err := r.Get(ctx, types.NamespacedName{Name: fmt.Sprintf("%s-kubeconfig", cluster.Name), Namespace: req.Namespace}, kubeConfigCm); err == nil && len(cluster.Status.Nodes) != 0 {
// fixme: this code will delete the kube config configmap when user delete the CR cluster.
// And if user apply this deleted CR cluster again, kk will no longer be able to find the kube config.
//kubeConfigCm.OwnerReferences = []metav1.OwnerReference{{
// APIVersion: cluster.APIVersion,
// Kind: cluster.Kind,
// Name: cluster.Name,
// UID: cluster.UID,
//}}
//if err := r.Update(ctx, kubeConfigCm); err != nil {
// return ctrl.Result{Requeue: true}, err
//}
kubeconfig, err := base64.StdEncoding.DecodeString(kubeConfigCm.Data["kubeconfig"])
if err != nil {
return ctrl.Result{Requeue: true}, err
}
config, err := clientcmd.RESTConfigFromKubeConfig(kubeconfig)
if err != nil {
return ctrl.Result{Requeue: true}, err
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
return ctrl.Result{Requeue: true}, err
}
nodeList, err := clientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
if err != nil {
return ctrl.Result{Requeue: true}, err
}
currentNodes := map[string]string{}
for _, node := range nodeList.Items {
currentNodes[node.Name] = node.Name
}
for _, etcd := range cluster.Spec.RoleGroups["etcd"] {
if _, ok := currentNodes[etcd]; !ok {
currentNodes[etcd] = etcd
}
}
nodes := cluster.Status.Nodes
var newNodes []kubekeyv1alpha2.NodeStatus
for _, node := range nodes {
if _, ok := currentNodes[node.Hostname]; ok {
newNodes = append(newNodes, node)
}
}
hosts := cluster.Spec.Hosts
var newHosts []kubekeyv1alpha2.HostCfg
for _, host := range hosts {
if _, ok := currentNodes[host.Name]; ok {
newHosts = append(newHosts, host)
} else {
removeHosts = append(removeHosts, host)
}
}
sendHostsAction(0, removeHosts)
var newEtcd, newMaster, newWorker []string
for _, node := range newNodes {
if node.Roles["etcd"] {
newEtcd = append(newEtcd, node.Hostname)
}
if node.Roles["master"] {
newMaster = append(newMaster, node.Hostname)
}
if node.Roles["worker"] {
newWorker = append(newWorker, node.Hostname)
}
}
cluster.Spec.Hosts = newHosts
cluster.Spec.RoleGroups = map[string][]string{
"master": newMaster,
"etcd": newEtcd,
"worker": newWorker,
}
if err := r.Update(ctx, cluster); err != nil {
return ctrl.Result{Requeue: true}, nil
}
// Fetch the Cluster object
if err := r.Get(ctx, req.NamespacedName, cluster); err != nil {
if kubeErr.IsNotFound(err) {
logger.Info("Cluster resource not found. Ignoring since object must be deleted")
return ctrl.Result{}, nil
}
logger.Error(err, "Failed to get Cluster")
return ctrl.Result{}, err
}
cluster.Status.Nodes = newNodes
cluster.Status.NodesCount = len(newNodes)
cluster.Status.MasterCount = len(newMaster)
cluster.Status.WorkerCount = len(newWorker)
if err := r.Status().Update(ctx, cluster); err != nil {
return ctrl.Result{Requeue: true}, nil
}
}
return ctrl.Result{RequeueAfter: 2 * time.Minute}, nil
}
func (r *ClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&kubekeyv1alpha2.Cluster{}).
WithEventFilter(ignoreDeletionPredicate()).
Complete(r)
}
func ignoreDeletionPredicate() predicate.Predicate {
return predicate.Funcs{
UpdateFunc: func(e event.UpdateEvent) bool {
// Ignore updates to CR status in which case metadata.Generation does not change
return e.ObjectOld.GetGeneration() != e.ObjectNew.GetGeneration()
},
DeleteFunc: func(e event.DeleteEvent) bool {
// Evaluates to false if the object has been confirmed deleted.
return !e.DeleteStateUnknown
},
}
}
func (r *ClusterReconciler) configMapForCluster(c *kubekeyv1alpha2.Cluster) *corev1.ConfigMap {
type Metadata struct {
Name string `yaml:"name" json:"name,omitempty"`
}
clusterConfiguration := struct {
ApiVersion string `yaml:"apiVersion" json:"apiVersion,omitempty"`
Kind string `yaml:"kind" json:"kind,omitempty"`
Metadata Metadata `yaml:"metadata" json:"metadata,omitempty"`
Spec kubekeyv1alpha2.ClusterSpec `yaml:"spec" json:"spec,omitempty"`
}{ApiVersion: c.APIVersion, Kind: c.Kind, Metadata: Metadata{Name: c.Name}, Spec: c.Spec}
clusterStr, _ := yaml.Marshal(clusterConfiguration)
cm := &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: c.Name,
Namespace: c.Namespace,
Labels: map[string]string{"kubekey.kubesphere.io/name": c.Name},
OwnerReferences: []metav1.OwnerReference{{
APIVersion: c.APIVersion,
Kind: c.Kind,
Name: c.Name,
UID: c.UID,
}},
},
Data: map[string]string{"cluster.yaml": string(clusterStr)},
}
return cm
}
func (r *ClusterReconciler) jobForCluster(c *kubekeyv1alpha2.Cluster, action string) *batchv1.Job {
var (
backoffLimit int32 = 0
name string
args []string
)
if action == CreateCluster {
name = fmt.Sprintf("%s-create-cluster", c.Name)
args = []string{"create", "cluster", "-f", "/home/kubekey/config/cluster.yaml", "-y", "--in-cluster", "true", "--namespace", c.Namespace}
} else if action == AddNodes {
name = fmt.Sprintf("%s-add-nodes", c.Name)
args = []string{"add", "nodes", "-f", "/home/kubekey/config/cluster.yaml", "-y", "--in-cluster", "true", "--ignore-err", "true", "--namespace", c.Namespace}
}
podlist := &corev1.PodList{}
listOpts := []client.ListOption{
client.InNamespace(c.Namespace),
client.MatchingLabels{"control-plane": "controller-manager"},
}
err := r.List(context.TODO(), podlist, listOpts...)
if err != nil {
logger.Error(err, "Failed to list kubekey controller-manager pod")
}
nodeName := podlist.Items[0].Spec.NodeName
var image string
for _, container := range podlist.Items[0].Spec.Containers {
if container.Name == "manager" {
image = container.Image
}
}
imageRepoList := strings.Split(image, "/")
var kubekey int64
kubekey = 1000
job := &batchv1.Job{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: c.Namespace,
Labels: map[string]string{"kubekey.kubesphere.io/name": c.Name},
OwnerReferences: []metav1.OwnerReference{{
APIVersion: c.APIVersion,
Kind: c.Kind,
Name: c.Name,
UID: c.UID,
}},
},
Spec: batchv1.JobSpec{
BackoffLimit: &backoffLimit,
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{},
Spec: corev1.PodSpec{
Volumes: []corev1.Volume{
{
Name: "config",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: c.Name,
},
Items: []corev1.KeyToPath{{
Key: "cluster.yaml",
Path: "cluster.yaml",
}},
},
},
},
{
Name: "kube-binaries",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
},
},
SecurityContext: &corev1.PodSecurityContext{
RunAsUser: &kubekey,
FSGroup: &kubekey,
},
InitContainers: []corev1.Container{
{
Name: "kube-binaries",
Image: fmt.Sprintf("%s/kube-binaries:%s", strings.Join(imageRepoList[:len(imageRepoList)-1], "/"), c.Spec.Kubernetes.Version),
Command: []string{
"sh",
"-c",
"cp -r -f /kubekey/* /home/kubekey/kubekey/",
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "kube-binaries",
MountPath: "/home/kubekey/kubekey",
},
},
},
},
Containers: []corev1.Container{{
Name: "runner",
Image: image,
ImagePullPolicy: "IfNotPresent",
Command: []string{"/home/kubekey/kk"},
Args: args,
VolumeMounts: []corev1.VolumeMount{
{
Name: "config",
MountPath: "/home/kubekey/config",
},
{
Name: "kube-binaries",
MountPath: "/home/kubekey/kubekey",
},
},
}},
NodeName: nodeName,
ServiceAccountName: "kubekey-controller-manager",
RestartPolicy: "Never",
},
},
},
}
return job
}
func updateStatusRunner(r *ClusterReconciler, req ctrl.Request, cluster *kubekeyv1alpha2.Cluster, action string) error {
var (
name string
)
if action == CreateCluster {
name = fmt.Sprintf("%s-create-cluster", cluster.Name)
} else if action == AddNodes {
name = fmt.Sprintf("%s-add-nodes", cluster.Name)
}
podlist := &corev1.PodList{}
listOpts := []client.ListOption{
client.InNamespace(req.Namespace),
client.MatchingLabels{"job-name": name},
}
for i := 0; i < 100; i++ {
_ = r.List(context.TODO(), podlist, listOpts...)
if len(podlist.Items) == 1 {
// Fetch the Cluster object
if err := r.Get(context.TODO(), req.NamespacedName, cluster); err != nil {
if kubeErr.IsNotFound(err) {
return nil
}
return err
}
if len(podlist.Items[0].ObjectMeta.GetName()) != 0 && len(podlist.Items[0].Status.ContainerStatuses[0].Name) != 0 && podlist.Items[0].Status.Phase != "Pending" {
cluster.Status.JobInfo = kubekeyv1alpha2.JobInfo{
Namespace: req.Namespace,
Name: name,
Pods: []kubekeyv1alpha2.PodInfo{{
Name: podlist.Items[0].ObjectMeta.GetName(),
Containers: []kubekeyv1alpha2.ContainerInfo{{Name: podlist.Items[0].Status.ContainerStatuses[0].Name}},
}},
}
if err := r.Status().Update(context.TODO(), cluster); err != nil {
return err
}
break
}
}
time.Sleep(6 * time.Second)
}
return nil
}
func updateClusterConfigMap(r *ClusterReconciler, ctx context.Context, cluster *kubekeyv1alpha2.Cluster, cmFound *corev1.ConfigMap) error {
// Check if the configmap already exists, if not create a new one
if err := r.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, cmFound); err != nil && !kubeErr.IsNotFound(err) {
logger.Error(err, "Failed to get ConfigMap", "ConfigMap.Namespace", cmFound.Namespace, "ConfigMap.Name", cmFound.Name)
return err
} else if err == nil {
if err := r.Delete(ctx, cmFound); err != nil {
logger.Error(err, "Failed to delete old ConfigMap", "ConfigMap.Namespace", cmFound.Namespace, "ConfigMap.Name", cmFound.Name)
return err
}
}
// Define a new configmap
cmCluster := r.configMapForCluster(cluster)
logger.Info("Creating a new ConfigMap", "ConfigMap.Namespace", cmCluster.Namespace, "ConfigMap.Name", cmCluster.Name)
if err := r.Create(ctx, cmCluster); err != nil {
logger.Error(err, "Failed to create new ConfigMap", "ConfigMap.Namespace", cmCluster.Namespace, "ConfigMap.Name", cmCluster.Name)
return err
}
return nil
}
func updateRunJob(r *ClusterReconciler, req ctrl.Request, ctx context.Context, cluster *kubekeyv1alpha2.Cluster, jobFound *batchv1.Job, action string) error {
var (
name string
)
if action == CreateCluster {
name = fmt.Sprintf("%s-create-cluster", cluster.Name)
} else if action == AddNodes {
name = fmt.Sprintf("%s-add-nodes", cluster.Name)
}
// Check if the job already exists, if not create a new one
if err := r.Get(ctx, types.NamespacedName{Name: name, Namespace: req.Namespace}, jobFound); err != nil && !kubeErr.IsNotFound(err) {
return err
} else if err == nil && (jobFound.Status.Failed != 0 || jobFound.Status.Succeeded != 0) {
// delete old pods
podlist := &corev1.PodList{}
listOpts := []client.ListOption{
client.InNamespace(req.Namespace),
client.MatchingLabels{"job-name": name},
}
if err := r.List(context.TODO(), podlist, listOpts...); err == nil && len(podlist.Items) != 0 {
for _, pod := range podlist.Items {
_ = r.Delete(ctx, &pod)
}
}
logger.Info("Prepare to delete old job", "Job.Namespace", jobFound.Namespace, "Job.Name", jobFound.Name)
if err := r.Delete(ctx, jobFound); err != nil {
logger.Error(err, "Failed to delete old Job", "Job.Namespace", jobFound.Namespace, "Job.Name", jobFound.Name)
return err
}
logger.Info("Deleting old job success", "Job.Namespace", jobFound.Namespace, "Job.Name", jobFound.Name)
err := wait.PollInfinite(1*time.Second, func() (bool, error) {
logger.Info("Checking old job is deleted", "Job.Namespace", jobFound.Namespace, "Job.Name", jobFound.Name)
if e := r.Get(ctx, types.NamespacedName{Name: name, Namespace: req.Namespace}, jobFound); e != nil {
if kubeErr.IsNotFound(e) {
return true, nil
}
return false, e
}
return false, nil
})
if err != nil {
logger.Error(err, "Failed to loop check old job is deleted", "Job.Namespace", jobFound.Namespace, "Job.Name", jobFound.Name)
return err
}
jobCluster := r.jobForCluster(cluster, action)
logger.Info("Creating a new Job to scale cluster", "Job.Namespace", jobCluster.Namespace, "Job.Name", jobCluster.Name)
if err := r.Create(ctx, jobCluster); err != nil {
logger.Error(err, "Failed to create new Job", "Job.Namespace", jobCluster.Namespace, "Job.Name", jobCluster.Name)
return err
}
} else if kubeErr.IsNotFound(err) {
jobCluster := r.jobForCluster(cluster, action)
logger.Info("Creating a new Job to create cluster", "Job.Namespace", jobCluster.Namespace, "Job.Name", jobCluster.Name)
if err := r.Create(ctx, jobCluster); err != nil {
logger.Error(err, "Failed to create new Job", "Job.Namespace", jobCluster.Namespace, "Job.Name", jobCluster.Name)
return err
}
}
if err := updateStatusRunner(r, req, cluster, action); err != nil {
return err
}
return nil
}
func sendHostsAction(action int, hosts []kubekeyv1alpha2.HostCfg) {
if os.Getenv("HOSTS_MANAGER") == "true" {
type HostsAction struct {
Hosts []kubekeyv1alpha2.HostCfg `json:"hosts,omitempty"`
Action int `json:"action,omitempty"`
}
newHostsAction := HostsAction{
Hosts: hosts,
Action: action,
}
fmt.Println(newHostsAction)
hostsInfoBytes, err := json.Marshal(newHostsAction)
if err != nil {
logger.Error(err, "Failed to marshal hosts info")
}
fmt.Println(string(hostsInfoBytes))
req, err := http.NewRequest("POST", "http://localhost:8090/api/v1alpha2/hosts", bytes.NewReader(hostsInfoBytes))
if err != nil {
logger.Error(err, "Failed to create request")
}
req.Header.Add("Content-Type", "application/json")
_, err = http.DefaultClient.Do(req)
if err != nil {
logger.Error(err, "Failed to send hosts info")
}
}
}
type NodeInfo struct {
Name string
Address string
Master bool
Worker bool
Etcd bool
}
type Configuration struct {
Etcd Etcd `yaml:"etcd"`
}
type Etcd struct {
External External `yaml:"external"`
}
type External struct {
Endpoints []string `yaml:"endpoints"`
}
func currentClusterDiff(r *ClusterReconciler, ctx context.Context, c *kubekeyv1alpha2.Cluster) ([]kubekeyv1alpha2.NodeStatus, error) {
newNodes := make([]kubekeyv1alpha2.NodeStatus, 0)
allSpecHostsMap := make(map[string]NodeInfo)
for _, host := range c.Spec.Hosts {
allSpecHostsMap[host.InternalAddress] = NodeInfo{
Name: host.Name,
Address: host.InternalAddress,
}
}
nodeList := &corev1.NodeList{}
if err := r.List(ctx, nodeList, &client.ListOptions{}); err != nil {
return newNodes, err
}
// get cluster nodes which in spec hosts
currentHostsMap := make(map[string]NodeInfo)
for _, node := range nodeList.Items {
isMaster := false
isWorker := false
if _, ok := node.Labels["node-role.kubernetes.io/control-plane"]; ok {
isMaster = true
}
if _, ok := node.Labels["node-role.kubernetes.io/master"]; ok {
isMaster = true
}
if _, ok := node.Labels["node-role.kubernetes.io/worker"]; ok {
isWorker = true
}
for _, address := range node.Status.Addresses {
if address.Type == corev1.NodeInternalIP {
if _, ok := allSpecHostsMap[address.Address]; ok {
currentHostsMap[address.Address] = NodeInfo{
Address: address.Address,
Name: node.Name,
Master: isMaster,
Worker: isWorker,
}
}
}
}
}
// spec cluster is different from current cluster
if len(currentHostsMap) == 0 {
return newNodes, nil
}
if len(currentHostsMap) < len(nodeList.Items) {
return newNodes, errors.New("the number of spec hosts are not enough compared with the cluster exist hosts")
}
// mark which ip or node name is etcd role
etcdSpecMap := make(map[string]bool)
kubeadmConfig := &corev1.ConfigMap{}
err := r.Get(ctx, types.NamespacedName{Name: "kubeadm-config", Namespace: "kube-system"}, kubeadmConfig)
if err == nil {
configuration, ok := kubeadmConfig.Data["ClusterConfiguration"]
if !ok {
return newNodes, errors.Errorf("Failed to get ClusterConfiguration key in kubeadm-config configmap")
}
conf := &Configuration{}
if err := yamlV2.Unmarshal([]byte(configuration), conf); err != nil {
return newNodes, err
}
for _, endpoint := range conf.Etcd.External.Endpoints {
ip, err := findIpAddress(endpoint)
if err != nil {
return newNodes, errors.Wrap(err, "Failed to find etcd external endpoints")
}
etcdSpecMap[ip] = true
}
} else {
if kubeErr.IsNotFound(err) {
for _, etcdHostName := range c.Spec.RoleGroups["etcd"] {
etcdSpecMap[etcdHostName] = true
}
} else {
return newNodes, errors.Wrap(errors.WithStack(err), "Failed to get kubeadm-config")
}
}
// add etcd node info to current hosts map
for _, host := range allSpecHostsMap {
_, nameOk := etcdSpecMap[host.Name]
_, ipOk := etcdSpecMap[host.Address]
if !nameOk && !ipOk {
continue
}
if exist, ok := currentHostsMap[host.Address]; ok {
exist.Etcd = true
currentHostsMap[host.Address] = exist
} else {
currentHostsMap[host.Address] = NodeInfo{
Address: host.Address,
Name: host.Name,
Etcd: true,
}
}
}
for _, host := range currentHostsMap {
newNodes = append(newNodes, kubekeyv1alpha2.NodeStatus{
InternalIP: host.Address,
Hostname: host.Name,
Roles: map[string]bool{"master": host.Master, "worker": host.Worker, "etcd": host.Etcd},
})
}
return newNodes, nil
}
func findIpAddress(endpoint string) (string, error) {
ipv4Regexp, err := regexp.Compile(`[\d]+\.[\d]+\.[\d]+\.[\d]+`)
if err != nil {
return "", err
}
ip := ipv4Regexp.FindStringSubmatch(endpoint)
if len(ip) != 0 {
return ip[0], nil
}
return "", errors.Errorf("Failed to find ip address in %s", endpoint)
}
func adaptExistedCluster(newNodes []kubekeyv1alpha2.NodeStatus, c *kubekeyv1alpha2.Cluster) error {
var newMaster, newWorker, newEtcd []string
for _, node := range newNodes {
if node.Roles["etcd"] {
newEtcd = append(newEtcd, node.Hostname)
}
if node.Roles["master"] {
newMaster = append(newMaster, node.Hostname)
}
if node.Roles["worker"] {
newWorker = append(newWorker, node.Hostname)
}
}
c.Status.NodesCount = len(newNodes)
c.Status.MasterCount = len(newMaster)
c.Status.EtcdCount = len(newEtcd)
c.Status.WorkerCount = len(newWorker)
c.Status.Nodes = newNodes
c.Status.Version = c.Spec.Kubernetes.Version
c.Status.NetworkPlugin = c.Spec.Network.Plugin
return nil
}
func otherClusterDiff(r *ClusterReconciler, ctx context.Context, c *kubekeyv1alpha2.Cluster) ([]kubekeyv1alpha2.NodeStatus, error) {
newNodes := make([]kubekeyv1alpha2.NodeStatus, 0)
allSpecHostsMap := make(map[string]NodeInfo)
for _, host := range c.Spec.Hosts {
allSpecHostsMap[host.InternalAddress] = NodeInfo{
Name: host.Name,
Address: host.InternalAddress,
}
}
kubeConfigFound := &corev1.ConfigMap{}
if err := r.Get(ctx, types.NamespacedName{Name: fmt.Sprintf("%s-kubeconfig", c.Name), Namespace: c.Namespace}, kubeConfigFound); err != nil {
if kubeErr.IsNotFound(err) {
return newNodes, nil
}
return newNodes, err
}
kubeconfig, err := base64.StdEncoding.DecodeString(kubeConfigFound.Data["kubeconfig"])
if err != nil {
return newNodes, err
}
config, err := clientcmd.RESTConfigFromKubeConfig(kubeconfig)
if err != nil {
return newNodes, err
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
return newNodes, err
}
nodeList, err := clientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
if err != nil {
return newNodes, err
}
// get cluster nodes which in spec hosts
currentHostsMap := make(map[string]NodeInfo)
for _, node := range nodeList.Items {
isMaster := false
isWorker := false
if _, ok := node.Labels["node-role.kubernetes.io/control-plane"]; ok {
isMaster = true
}
if _, ok := node.Labels["node-role.kubernetes.io/master"]; ok {
isMaster = true
}
if _, ok := node.Labels["node-role.kubernetes.io/worker"]; ok {
isWorker = true
}
for _, address := range node.Status.Addresses {
if address.Type == corev1.NodeInternalIP {
if _, ok := allSpecHostsMap[address.Address]; ok {
currentHostsMap[address.Address] = NodeInfo{
Address: address.Address,
Name: node.Name,
Master: isMaster,
Worker: isWorker,
}
}
}
}
}
// spec cluster is different from current cluster
if len(currentHostsMap) == 0 {
return newNodes, nil
}
if len(currentHostsMap) < len(nodeList.Items) {
return newNodes, errors.New("the number of spec hosts are not enough compared with the cluster exist hosts")
}
// mark which ip or node name is etcd role
etcdSpecMap := make(map[string]bool)
kubeadmConfig, err := clientset.CoreV1().ConfigMaps("kube-system").Get(ctx, "kubeadm-config", metav1.GetOptions{})
if err == nil {
configuration, ok := kubeadmConfig.Data["ClusterConfiguration"]
if !ok {
return newNodes, errors.Errorf("Failed to get ClusterConfiguration key in kubeadm-config configmap")
}
conf := &Configuration{}
if err := yamlV2.Unmarshal([]byte(configuration), conf); err != nil {
return newNodes, err
}
for _, endpoint := range conf.Etcd.External.Endpoints {
ip, err := findIpAddress(endpoint)
if err != nil {
return newNodes, errors.Wrap(err, "Failed to find etcd external endpoints")
}
etcdSpecMap[ip] = true
}
} else {
if kubeErr.IsNotFound(err) {
for _, etcdHostName := range c.Spec.RoleGroups["etcd"] {
etcdSpecMap[etcdHostName] = true
}
} else {
return newNodes, errors.Wrap(errors.WithStack(err), "Failed to get kubeadm-config")
}
}
// add etcd node info to current hosts map
for _, host := range allSpecHostsMap {
_, nameOk := etcdSpecMap[host.Name]
_, ipOk := etcdSpecMap[host.Address]
if !nameOk && !ipOk {
continue
}
if exist, ok := currentHostsMap[host.Address]; ok {
exist.Etcd = true
currentHostsMap[host.Address] = exist
} else {
currentHostsMap[host.Address] = NodeInfo{
Address: host.Address,
Name: host.Name,
Etcd: true,
}
}
}
for _, host := range currentHostsMap {
newNodes = append(newNodes, kubekeyv1alpha2.NodeStatus{
InternalIP: host.Address,
Hostname: host.Name,
Roles: map[string]bool{"master": host.Master, "worker": host.Worker, "etcd": host.Etcd},
})
}
return newNodes, nil
}

View File

@@ -0,0 +1,436 @@
/*
Copyright 2020 The KubeSphere Authors.
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 kubekey
import (
"context"
"encoding/base64"
"fmt"
"text/template"
kubekeyapiv1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
"bytetrade.io/web3os/installer/pkg/addons"
"bytetrade.io/web3os/installer/pkg/common"
"bytetrade.io/web3os/installer/pkg/core/ending"
"github.com/pkg/errors"
kubekeyclientset "bytetrade.io/web3os/installer/clients/clientset/versioned"
"bytetrade.io/web3os/installer/pkg/core/util"
"github.com/lithammer/dedent"
corev1 "k8s.io/api/core/v1"
kubeErr "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
kube "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/controller-runtime/pkg/client"
)
const (
// Pending representative the cluster is being created.
Pending = "pending"
// Success representative the cluster cluster has been created successfully.
Success = "success"
// Failed creation failure.
Failed = "failed"
)
var (
newNodes []string
clusterKubeSphere = template.Must(template.New("cluster.kubesphere.io").Parse(
dedent.Dedent(`apiVersion: cluster.kubesphere.io/v1alpha1
kind: Cluster
metadata:
finalizers:
- finalizer.cluster.kubesphere.io
labels:
cluster-role.kubesphere.io/member: ""
kubesphere.io/managed: "true"
kubekey.kubesphere.io/name: {{ .Name }}
name: {{ .Name }}
spec:
connection:
kubeconfig: {{ .Kubeconfig }}
type: direct
enable: {{ .Enable }}
joinFederation: {{ .JoinFedration }}
provider: kubesphere
`)))
)
func generateClusterKubeSphere(name string, kubeconfig string, enable, joinFedration bool) (string, error) {
return util.Render(clusterKubeSphere, util.Data{
"Name": name,
"Kubeconfig": kubeconfig,
"Enable": enable,
"JoinFedration": joinFedration,
})
}
// CheckClusterRole is used to check the cluster's role (host or member).
func CheckClusterRole() (bool, *rest.Config, error) {
// creates the in-cluster config
config, err := rest.InClusterConfig()
if err != nil {
return false, nil, err
}
// creates the clientset
clientset, err := kube.NewForConfig(config)
if err != nil {
return false, nil, err
}
var hostClusterFlag bool
if err := clientset.RESTClient().Get().
AbsPath("/apis/cluster.kubesphere.io/v1alpha1/clusters").
Name("host").
Do(context.TODO()).Error(); err == nil {
hostClusterFlag = true
}
return hostClusterFlag, config, nil
}
func newKubeSphereCluster(r *ClusterReconciler, c *kubekeyapiv1alpha2.Cluster) error {
if hostClusterFlag, config, err := CheckClusterRole(); err != nil {
return err
} else if hostClusterFlag {
obj, err := generateClusterKubeSphere(c.Name, "Cg==", false, false)
if err != nil {
return err
}
if err := addons.DoServerSideApply(context.TODO(), config, []byte(obj)); err != nil {
err = r.Delete(context.TODO(), c)
if err != nil {
return err
}
return err
}
kscluster, err := addons.GetCluster(c.Name)
if err != nil {
return err
}
ownerReferencePatch := fmt.Sprintf(`{"metadata": {"ownerReferences": [{"apiVersion": "%s", "kind": "%s", "name": "%s", "uid": "%s"}]}}`, kscluster.GetAPIVersion(), kscluster.GetKind(), kscluster.GetName(), kscluster.GetUID())
if err := r.Patch(context.TODO(), c, client.RawPatch(types.MergePatchType, []byte(ownerReferencePatch))); err != nil {
return err
}
}
return nil
}
// UpdateKubeSphereCluster is used to update the cluster object of KubeSphere's multicluster.
func UpdateKubeSphereCluster(runtime *common.KubeRuntime) error {
if hostClusterFlag, config, err := CheckClusterRole(); err != nil {
return err
} else if hostClusterFlag {
obj, err := generateClusterKubeSphere(runtime.ClusterName, runtime.Kubeconfig, true, true)
if err != nil {
return err
}
if err := addons.DoServerSideApply(context.TODO(), config, []byte(obj)); err != nil {
return err
}
}
return nil
}
// NewKubekeyClient is used to create a kubekey cluster client.
func NewKubekeyClient() (*kubekeyclientset.Clientset, error) {
// creates the in-cluster config
config, err := rest.InClusterConfig()
if err != nil {
return nil, err
}
// creates the clientset
clientset := kubekeyclientset.NewForConfigOrDie(config)
return clientset, nil
}
func getCluster(name string) (*kubekeyapiv1alpha2.Cluster, error) {
clientset, err := NewKubekeyClient()
if err != nil {
return nil, err
}
clusterObj, err := clientset.KubekeyV1alpha2().Clusters().Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return nil, err
}
return clusterObj, nil
}
// UpdateClusterConditions is used for updating cluster installation process information or adding nodes.
func UpdateClusterConditions(runtime *common.KubeRuntime, step string, result *ending.ModuleResult) error {
m := make(map[string]kubekeyapiv1alpha2.Event)
allStatus := true
for k, v := range result.HostResults {
if v.GetStatus() == ending.FAILED {
allStatus = false
}
e := kubekeyapiv1alpha2.Event{
Step: step,
Status: v.GetStatus().String(),
}
if v.GetErr() != nil {
e.Message = v.GetErr().Error()
}
m[k] = e
}
condition := kubekeyapiv1alpha2.Condition{
Step: step,
StartTime: metav1.Time{Time: result.StartTime},
EndTime: metav1.Time{Time: result.EndTime},
Status: allStatus,
Events: m,
}
cluster, err := getCluster(runtime.ClusterName)
if err != nil {
return err
}
length := len(cluster.Status.Conditions)
if length <= 0 {
cluster.Status.Conditions = append(cluster.Status.Conditions, condition)
} else if cluster.Status.Conditions[length-1].Step == condition.Step {
cluster.Status.Conditions[length-1] = condition
} else {
cluster.Status.Conditions = append(cluster.Status.Conditions, condition)
}
cluster.Status.PiplineInfo.Status = "Running"
if _, err := runtime.ClientSet.KubekeyV1alpha2().Clusters().UpdateStatus(context.TODO(), cluster, metav1.UpdateOptions{}); err != nil {
return err
}
return nil
}
// UpdateStatus is used to update status for a new or expanded cluster.
func UpdateStatus(runtime *common.KubeRuntime) error {
cluster, err := getCluster(runtime.ClusterName)
if err != nil {
return err
}
cluster.Status.Version = runtime.Cluster.Kubernetes.Version
cluster.Status.NodesCount = len(runtime.GetAllHosts())
cluster.Status.MasterCount = len(runtime.GetHostsByRole(common.Master))
cluster.Status.WorkerCount = len(runtime.GetHostsByRole(common.Worker))
cluster.Status.EtcdCount = len(runtime.GetHostsByRole(common.ETCD))
cluster.Status.NetworkPlugin = runtime.Cluster.Network.Plugin
cluster.Status.Nodes = []kubekeyapiv1alpha2.NodeStatus{}
for _, node := range runtime.GetAllHosts() {
cluster.Status.Nodes = append(cluster.Status.Nodes, kubekeyapiv1alpha2.NodeStatus{
InternalIP: node.GetInternalAddress(),
Hostname: node.GetName(),
Roles: map[string]bool{"etcd": node.IsRole(common.ETCD), "master": node.IsRole(common.Master), "worker": node.IsRole(common.Worker)},
})
}
cluster.Status.PiplineInfo.Status = "Terminated"
if _, err := runtime.ClientSet.KubekeyV1alpha2().Clusters().UpdateStatus(context.TODO(), cluster, metav1.UpdateOptions{}); err != nil {
return err
}
return nil
}
func getClusterClientSet(runtime *common.KubeRuntime) (*kube.Clientset, error) {
// creates the in-cluster config
inClusterConfig, err := rest.InClusterConfig()
if err != nil {
return nil, err
}
// creates the clientset
clientset, err := kube.NewForConfig(inClusterConfig)
if err != nil {
return nil, err
}
cm, err := clientset.
CoreV1().
ConfigMaps(runtime.Arg.Namespace).
Get(context.TODO(), fmt.Sprintf("%s-kubeconfig", runtime.ClusterName), metav1.GetOptions{})
if err != nil {
return nil, err
}
kubeConfigBase64, ok := cm.Data["kubeconfig"]
if !ok {
return nil, errors.Errorf("get kubeconfig from %s configmap failed", runtime.ClusterName)
}
kubeConfigStr, err := base64.StdEncoding.DecodeString(kubeConfigBase64)
if err != nil {
return nil, err
}
config, err := clientcmd.NewClientConfigFromBytes(kubeConfigStr)
if err != nil {
return nil, err
}
restConfig, err := config.ClientConfig()
if err != nil {
return nil, err
}
clientsetForCluster, err := kube.NewForConfig(restConfig)
if err != nil {
return nil, err
}
return clientsetForCluster, nil
}
func nodeForCluster(name string, labels map[string]string) *corev1.Node {
node := &corev1.Node{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: labels,
},
Spec: corev1.NodeSpec{},
Status: corev1.NodeStatus{},
}
return node
}
// CreateNodeForCluster is used to create new nodes for the cluster to be add nodes.
func CreateNodeForCluster(runtime *common.KubeRuntime) error {
clientsetForCluster, err := getClusterClientSet(runtime)
if err != nil {
if kubeErr.IsNotFound(err) {
return nil
}
return err
}
nodeInfo := make(map[string]string)
nodeList, err := clientsetForCluster.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
return err
}
for _, node := range nodeList.Items {
nodeInfo[node.Name] = node.Status.NodeInfo.KubeletVersion
}
for _, host := range runtime.GetHostsByRole(common.K8s) {
if _, ok := nodeInfo[host.GetName()]; !ok {
labels := map[string]string{"kubekey.kubesphere.io/import-status": Pending}
if host.IsRole(common.Master) {
labels["node-role.kubernetes.io/master"] = ""
}
if host.IsRole(common.Worker) {
labels["node-role.kubernetes.io/worker"] = ""
}
node := nodeForCluster(host.GetName(), labels)
if _, err = clientsetForCluster.CoreV1().Nodes().Create(context.TODO(), node, metav1.CreateOptions{}); err != nil {
return err
}
newNodes = append(newNodes, host.GetName())
}
}
return nil
}
// PatchNodeImportStatus is used to update new node's status.
func PatchNodeImportStatus(runtime *common.KubeRuntime, status string) error {
clientsetForCluster, err := getClusterClientSet(runtime)
if err != nil {
if kubeErr.IsNotFound(err) {
return nil
}
return err
}
patchStr := fmt.Sprintf(`{"metadata": {"labels": {"kubekey.kubesphere.io/import-status": "%s"}}}`, status)
nodeList, err := clientsetForCluster.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
return err
}
for _, node := range nodeList.Items {
for k, v := range node.Labels {
if k == "kubekey.kubesphere.io/import-status" && v != Success {
_, err = clientsetForCluster.CoreV1().Nodes().Patch(context.TODO(), node.Name, types.StrategicMergePatchType, []byte(patchStr), metav1.PatchOptions{})
if err != nil {
return err
}
}
}
}
return nil
}
// SaveKubeConfig is used to save the kubeconfig for the new cluster.
func SaveKubeConfig(runtime *common.KubeRuntime) error {
// creates the in-cluster config
inClusterConfig, err := rest.InClusterConfig()
if err != nil {
return err
}
// creates the clientset
clientset, err := kube.NewForConfig(inClusterConfig)
if err != nil {
return err
}
cmClientset := clientset.CoreV1().ConfigMaps(runtime.Arg.Namespace)
if _, err := cmClientset.Get(context.TODO(), fmt.Sprintf("%s-kubeconfig", runtime.ClusterName), metav1.GetOptions{}); err != nil {
if kubeErr.IsNotFound(err) {
_, err = cmClientset.Create(context.TODO(), configMapForKubeconfig(runtime), metav1.CreateOptions{})
if err != nil {
return err
}
} else {
return err
}
} else {
kubeconfigStr := fmt.Sprintf(`{"kubeconfig": "%s"}`, runtime.Kubeconfig)
_, err = cmClientset.Patch(context.TODO(), runtime.ClusterName, types.ApplyPatchType, []byte(kubeconfigStr), metav1.PatchOptions{})
if err != nil {
return err
}
}
// clientset.CoreV1().ConfigMaps("kubekey-system").Create(context.TODO(), kubeconfigConfigMap, metav1.CreateOptions{}
return nil
}
// configMapForKubeconfig is used to generate configmap scheme for cluster's kubeconfig.
func configMapForKubeconfig(runtime *common.KubeRuntime) *corev1.ConfigMap {
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-kubeconfig", runtime.ClusterName),
},
Data: map[string]string{
"kubeconfig": runtime.Kubeconfig,
},
}
return cm
}
func ClearConditions(runtime *common.KubeRuntime) error {
cluster, err := getCluster(runtime.ClusterName)
if err != nil {
return err
}
cluster.Status.Conditions = make([]kubekeyapiv1alpha2.Condition, 0)
if _, err := runtime.ClientSet.KubekeyV1alpha2().Clusters().UpdateStatus(context.TODO(), cluster, metav1.UpdateOptions{}); err != nil {
return err
}
return nil
}

23
cli/generate_vfs.go Normal file
View File

@@ -0,0 +1,23 @@
//go:build ignore
package main
import (
"log"
"net/http"
"path"
"github.com/shurcooL/vfsgen"
)
func main() {
fs := http.Dir(path.Join("pkg", "kubesphere", "plugins", "files"))
dst := path.Join("pkg", "kubesphere", "plugins", "assets_vfsdata.go")
err := vfsgen.Generate(fs, vfsgen.Options{
Filename: dst,
PackageName: "plugins",
})
if err != nil {
log.Fatalln(err)
}
}

238
cli/go.mod Executable file
View File

@@ -0,0 +1,238 @@
module bytetrade.io/web3os/installer
go 1.22.0
toolchain go1.22.4
replace (
bytetrade.io/web3os/backups-sdk => github.com/Above-Os/backups-sdk v0.1.17
github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5
github.com/containerd/containerd => github.com/containerd/containerd v1.6.36
github.com/containers/image/v5 => github.com/containers/image/v5 v5.21.1
github.com/containers/ocicrypt => github.com/containers/ocicrypt v1.1.10
github.com/containers/storage => github.com/containers/storage v1.40.0
github.com/docker/distribution => github.com/docker/distribution v2.8.1+incompatible
github.com/docker/docker => github.com/moby/moby v20.10.14+incompatible
github.com/estesp/manifest-tool/v2 => github.com/estesp/manifest-tool/v2 v2.0.3
github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.1.0
helm.sh/helm/v3 => helm.sh/helm/v3 v3.10.1
k8s.io/api => k8s.io/api v0.24.2
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.24.2
k8s.io/apimachinery => k8s.io/apimachinery v0.24.2
k8s.io/apiserver => k8s.io/apiserver v0.24.2
k8s.io/cli-runtime => k8s.io/cli-runtime v0.24.2
k8s.io/client-go => k8s.io/client-go v0.24.2
k8s.io/component-base => k8s.io/component-base v0.24.2
k8s.io/klog/v2 => k8s.io/klog/v2 v2.60.1
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8
k8s.io/kubectl => k8s.io/kubectl v0.24.2
k8s.io/utils => k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
oras.land/oras-go => oras.land/oras-go v1.2.0
sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.12.2
sigs.k8s.io/json => sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.11.4
sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.13.6
sigs.k8s.io/structured-merge-diff/v4 => sigs.k8s.io/structured-merge-diff/v4 v4.2.1
sigs.k8s.io/yaml => sigs.k8s.io/yaml v1.3.0
)
require (
bytetrade.io/web3os/backups-sdk v0.0.0-00010101000000-000000000000
github.com/Masterminds/semver/v3 v3.2.1
github.com/cavaliergopher/grab/v3 v3.0.1
github.com/containerd/containerd v1.7.18
github.com/containers/image/v5 v5.32.2
github.com/dominodatalab/os-release v0.0.0-20190522011736-bcdb4a3e3c2f
github.com/estesp/manifest-tool/v2 v2.1.6
github.com/go-playground/validator/v10 v10.22.0
github.com/jmoiron/sqlx v1.4.0
github.com/joho/godotenv v1.5.1
github.com/libp2p/go-netroute v0.2.2
github.com/lithammer/dedent v1.1.0
github.com/mattn/go-sqlite3 v1.14.22
github.com/mitchellh/mapstructure v1.5.0
github.com/modood/table v0.0.0-20220527013332-8d47e76dad33
github.com/opencontainers/image-spec v1.1.0
github.com/pelletier/go-toml v1.9.5
github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.13.6
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d
github.com/schollz/progressbar/v3 v3.17.1
github.com/shirou/gopsutil/v4 v4.25.2
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c
github.com/spf13/cobra v1.8.0
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.31.0
golang.org/x/term v0.27.0
golang.org/x/text v0.21.0
gopkg.in/yaml.v2 v2.4.0
helm.sh/helm/v3 v3.15.2
k8s.io/api v0.30.2
k8s.io/apimachinery v0.32.1
k8s.io/cli-runtime v0.30.2
k8s.io/client-go v0.32.1
k8s.io/kubectl v0.30.2
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738
sigs.k8s.io/yaml v1.4.0
)
require (
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Microsoft/hcsshim v0.12.3 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/containerd/cgroups/v3 v3.0.3 // indirect
github.com/containerd/continuity v0.4.2 // indirect
github.com/containerd/errdefs v0.1.0 // indirect
github.com/containerd/fifo v1.1.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/ttrpc v1.2.2 // indirect
github.com/containerd/typeurl v1.0.2 // indirect
github.com/cyphar/filepath-securejoin v0.2.5 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/cli v26.1.3+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v26.1.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.1 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/ebitengine/purego v0.8.2 // indirect
github.com/emicklei/go-restful v2.16.0+incompatible // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-resty/resty/v2 v2.16.5 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/googleapis v1.4.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/sys/mountinfo v0.7.1 // indirect
github.com/moby/sys/signal v0.6.0 // indirect
github.com/moby/sys/user v0.1.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nxadm/tail v1.4.11 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/runtime-spec v1.1.0 // indirect
github.com/opencontainers/selinux v1.10.1 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/prometheus/client_golang v1.19.0 // indirect
github.com/prometheus/client_model v0.6.0 // indirect
github.com/prometheus/common v0.51.1 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rubenv/sql-migrate v1.5.2 // indirect
github.com/russross/blackfriday v1.6.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/smartystreets/goconvey v1.8.1 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/stretchr/testify v1.10.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/etcd/api/v3 v3.5.4 // indirect
go.opencensus.io v0.24.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/oauth2 v0.20.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/time v0.7.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
google.golang.org/grpc v1.62.1 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/apiextensions-apiserver v0.30.1 // indirect
k8s.io/apiserver v0.30.1 // indirect
k8s.io/component-base v0.30.2 // indirect
k8s.io/cri-api v0.25.0 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
oras.land/oras-go v1.2.5 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
)
require (
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/spf13/pflag v1.0.5
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/sys v0.28.0
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.130.1
sigs.k8s.io/controller-runtime v0.18.4
)

2951
cli/go.sum Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
package account

1
cli/pkg/account/tasks.go Normal file
View File

@@ -0,0 +1 @@
package account

66
cli/pkg/addons/addons.go Normal file
View File

@@ -0,0 +1,66 @@
/*
Copyright 2021 The KubeSphere Authors.
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 addons
import (
"net/url"
"os"
"path/filepath"
"strings"
kubekeyapiv1alpha2 "bytetrade.io/web3os/installer/apis/kubekey/v1alpha2"
"bytetrade.io/web3os/installer/pkg/common"
"github.com/pkg/errors"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/getter"
)
func InstallAddons(kubeConf *common.KubeConf, addon *kubekeyapiv1alpha2.Addon, kubeConfig string) error {
// install chart
if addon.Sources.Chart.Name != "" {
_ = os.Setenv("HELM_NAMESPACE", strings.TrimSpace(addon.Namespace))
if err := InstallChart(kubeConf, addon, kubeConfig); err != nil {
return err
}
}
// install yaml
if len(addon.Sources.Yaml.Path) != 0 {
var settings = cli.New()
p := getter.All(settings)
for _, yaml := range addon.Sources.Yaml.Path {
u, _ := url.Parse(yaml)
_, err := p.ByScheme(u.Scheme)
if err != nil {
fp, err := filepath.Abs(yaml)
if err != nil {
return errors.Wrap(err, "Failed to look up current directory")
}
yamlPaths := []string{fp}
if err := InstallYaml(yamlPaths, addon.Namespace, kubeConfig, kubeConf.Cluster.Kubernetes.Version); err != nil {
return err
}
} else {
yamlPaths := []string{yaml}
if err := InstallYaml(yamlPaths, addon.Namespace, kubeConfig, kubeConf.Cluster.Kubernetes.Version); err != nil {
return err
}
}
}
}
return nil
}

Some files were not shown because too many files have changed in this diff Show More