mirror of
https://github.com/kubesphere/kubekey.git
synced 2025-12-25 17:12:50 +00:00
feat: init branch
Signed-off-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
parent
631e39357d
commit
2f4c2fa795
|
|
@ -1,768 +0,0 @@
|
|||
{
|
||||
"projectName": "kubekey",
|
||||
"projectOwner": "kubesphere",
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
"files": [
|
||||
"README.md",
|
||||
"CONTRIBUTORS.md",
|
||||
"README_zh-CN.md"
|
||||
],
|
||||
"imageSize": 100,
|
||||
"commit": true,
|
||||
"commitConvention": "none",
|
||||
"contributors": [
|
||||
{
|
||||
"login": "pixiake",
|
||||
"name": "pixiake",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/22290449?v=4",
|
||||
"profile": "https://github.com/pixiake",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Forest-L",
|
||||
"name": "Forest",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/50984129?v=4",
|
||||
"profile": "https://github.com/Forest-L",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "rayzhou2017",
|
||||
"name": "rayzhou2017",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/28859385?v=4",
|
||||
"profile": "https://kubesphere.io/",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "shaowenchen",
|
||||
"name": "shaowenchen",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/43693241?v=4",
|
||||
"profile": "https://www.chenshaowen.com/",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "LinuxSuRen",
|
||||
"name": "Zhao Xiaojie",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/1450685?v=4",
|
||||
"profile": "http://surenpi.com/",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "zackzhangkai",
|
||||
"name": "Zack Zhang",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/20178386?v=4",
|
||||
"profile": "https://github.com/zackzhangkai",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "akhilerm",
|
||||
"name": "Akhil Mohan",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/7610845?v=4",
|
||||
"profile": "https://akhilerm.com/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "FeynmanZhou",
|
||||
"name": "pengfei",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/40452856?v=4",
|
||||
"profile": "https://github.com/FeynmanZhou",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "min-zh",
|
||||
"name": "min zhang",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/35321102?v=4",
|
||||
"profile": "https://github.com/min-zh",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "zgldh",
|
||||
"name": "zgldh",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/312404?v=4",
|
||||
"profile": "https://github.com/zgldh",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "xrjk",
|
||||
"name": "xrjk",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/16330256?v=4",
|
||||
"profile": "https://github.com/xrjk",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "stoneshi-yunify",
|
||||
"name": "yonghongshi",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/70880165?v=4",
|
||||
"profile": "https://github.com/stoneshi-yunify",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "shenhonglei",
|
||||
"name": "Honglei",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/20896372?v=4",
|
||||
"profile": "https://github.com/shenhonglei",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "liucy1983",
|
||||
"name": "liucy1983",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/2360302?v=4",
|
||||
"profile": "https://github.com/liucy1983",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lilien1010",
|
||||
"name": "Lien",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/3814966?v=4",
|
||||
"profile": "https://github.com/lilien1010",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "klj890",
|
||||
"name": "Tony Wang",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/19380605?v=4",
|
||||
"profile": "https://github.com/klj890",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "hlwanghl",
|
||||
"name": "Hongliang Wang",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/4861515?v=4",
|
||||
"profile": "https://github.com/hlwanghl",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "fafucoder",
|
||||
"name": "dawn",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/16442491?v=4",
|
||||
"profile": "https://fafucoder.github.io/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "duanjiong",
|
||||
"name": "Duan Jiong",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/3678855?v=4",
|
||||
"profile": "https://github.com/duanjiong",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "calvinyv",
|
||||
"name": "calvinyv",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/28883416?v=4",
|
||||
"profile": "https://github.com/calvinyv",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "benjaminhuo",
|
||||
"name": "Benjamin Huo",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/18525465?v=4",
|
||||
"profile": "https://github.com/benjaminhuo",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Sherlock113",
|
||||
"name": "Sherlock113",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/65327072?v=4",
|
||||
"profile": "https://github.com/Sherlock113",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Fuchange",
|
||||
"name": "fu_changjie",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/31716848?v=4",
|
||||
"profile": "https://github.com/Fuchange",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "yuswift",
|
||||
"name": "yuswift",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/37265389?v=4",
|
||||
"profile": "https://github.com/yuswift",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ruiyaoOps",
|
||||
"name": "ruiyaoOps",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/35256376?v=4",
|
||||
"profile": "https://github.com/ruiyaoOps",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lxm",
|
||||
"name": "LXM",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1918195?v=4",
|
||||
"profile": "http://www.luxingmin.com",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "sbhnet",
|
||||
"name": "sbhnet",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2368131?v=4",
|
||||
"profile": "https://github.com/sbhnet",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "misteruly",
|
||||
"name": "misteruly",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/31399968?v=4",
|
||||
"profile": "https://github.com/misteruly",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "JohnNiang",
|
||||
"name": "John Niang",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/16865714?v=4",
|
||||
"profile": "https://johnniang.me",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "alimy",
|
||||
"name": "Michael Li",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/10525842?v=4",
|
||||
"profile": "https://alimy.me",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "duguhaotian",
|
||||
"name": "独孤昊天",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3174621?v=4",
|
||||
"profile": "https://github.com/duguhaotian",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lshmouse",
|
||||
"name": "Liu Shaohui",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/118687?v=4",
|
||||
"profile": "https://github.com/lshmouse",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "24sama",
|
||||
"name": "Leo Li",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/43993589?v=4",
|
||||
"profile": "https://github.com/24sama",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "RolandMa1986",
|
||||
"name": "Roland",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1720333?v=4",
|
||||
"profile": "https://github.com/RolandMa1986",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "vinsonzou",
|
||||
"name": "Vinson Zou",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2347587?v=4",
|
||||
"profile": "https://ops.m114.org",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "tagGeeY",
|
||||
"name": "tag_gee_y",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/35259969?v=4",
|
||||
"profile": "https://github.com/tagGeeY",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "liulangwa",
|
||||
"name": "codebee",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/25916792?v=4",
|
||||
"profile": "https://github.com/liulangwa",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "TheApeMachine",
|
||||
"name": "Daniel Owen van Dommelen",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/9572060?v=4",
|
||||
"profile": "https://github.com/TheApeMachine",
|
||||
"contributions": [
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Naidile-P-N",
|
||||
"name": "Naidile P N",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/29476402?v=4",
|
||||
"profile": "https://github.com/Naidile-P-N",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "haiker2011",
|
||||
"name": "Haiker Sun",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/8073429?v=4",
|
||||
"profile": "https://github.com/haiker2011",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "yj-cloud",
|
||||
"name": "Jing Yu",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/19648473?v=4",
|
||||
"profile": "https://github.com/yj-cloud",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "chaunceyjiang",
|
||||
"name": "Chauncey",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/17962021?v=4",
|
||||
"profile": "https://github.com/chaunceyjiang",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "tanguofu",
|
||||
"name": "Tan Guofu",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/87045830?v=4",
|
||||
"profile": "https://github.com/tanguofu",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lvillis",
|
||||
"name": "lvillis",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/56720445?v=4",
|
||||
"profile": "https://github.com/lvillis",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "vincenthe11",
|
||||
"name": "Vincent He",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/8400716?v=4",
|
||||
"profile": "https://github.com/vincenthe11",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "tpiperatgod",
|
||||
"name": "laminar",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2360535?v=4",
|
||||
"profile": "https://laminar.fun/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "cumirror",
|
||||
"name": "tongjin",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2455429?v=4",
|
||||
"profile": "https://github.com/cumirror",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "muzi502",
|
||||
"name": "Reimu",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/42566386?v=4",
|
||||
"profile": "http://k8s.li",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "eltociear",
|
||||
"name": "Ikko Ashimine",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/22633385?v=4",
|
||||
"profile": "https://bandism.net/",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "yeya24",
|
||||
"name": "Ben Ye",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/25150124?v=4",
|
||||
"profile": "https://yeya24.github.io/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "yinheli",
|
||||
"name": "yinheli",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/235094?v=4",
|
||||
"profile": "https://github.com/yinheli",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "hellocn9",
|
||||
"name": "hellocn9",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/102210430?v=4",
|
||||
"profile": "https://github.com/hellocn9",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "brandan-schmitz",
|
||||
"name": "Brandan Schmitz",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6267549?v=4",
|
||||
"profile": "https://github.com/brandan-schmitz",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "yjqg6666",
|
||||
"name": "yjqg6666",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1879641?v=4",
|
||||
"profile": "https://github.com/yjqg6666",
|
||||
"contributions": [
|
||||
"doc",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "zaunist",
|
||||
"name": "失眠是真滴难受",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/38528079?v=4",
|
||||
"profile": "https://github.com/zaunist",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mangoGoForward",
|
||||
"name": "mango",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/35127166?v=4",
|
||||
"profile": "https://github.com/mangoGoForward",
|
||||
"contributions": [
|
||||
"review"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "wenwutang1",
|
||||
"name": "wenwutang",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/45817987?v=4",
|
||||
"profile": "https://github.com/wenwutang1",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "kuops",
|
||||
"name": "Shiny Hou",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/18283256?v=4",
|
||||
"profile": "http://kuops.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "zhouqiu0103",
|
||||
"name": "zhouqiu0103",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/108912268?v=4",
|
||||
"profile": "https://github.com/zhouqiu0103",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "77yu77",
|
||||
"name": "77yu77",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/73932296?v=4",
|
||||
"profile": "https://github.com/77yu77",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "hzhhong",
|
||||
"name": "hzhhong",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/83079531?v=4",
|
||||
"profile": "https://github.com/hzhhong",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "arugal",
|
||||
"name": "zhang-wei",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/26432832?v=4",
|
||||
"profile": "https://github.com/arugal",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "xiaods",
|
||||
"name": "Deshi Xiao",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/37678?v=4",
|
||||
"profile": "https://twitter.com/xds2000",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "besscroft",
|
||||
"name": "besscroft",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/33775809?v=4",
|
||||
"profile": "https://besscroft.com",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "zhangzhiqiangcs",
|
||||
"name": "张志强",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/8319897?v=4",
|
||||
"profile": "https://github.com/zhangzhiqiangcs",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lwabish",
|
||||
"name": "lwabish",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/7044019?v=4",
|
||||
"profile": "https://github.com/lwabish",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "qyz87",
|
||||
"name": "qyz87",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/36068894?v=4",
|
||||
"profile": "https://github.com/qyz87",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "fangzhengjin",
|
||||
"name": "ZhengJin Fang",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/12680972?v=4",
|
||||
"profile": "https://github.com/fangzhengjin",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ExerciseBook",
|
||||
"name": "Eric_Lian",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6327311?v=4",
|
||||
"profile": "http://lhr.wiki",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "nicognaW",
|
||||
"name": "nicognaw",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/66731869?v=4",
|
||||
"profile": "https://github.com/nicognaW",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "deqingLv",
|
||||
"name": "吕德庆",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6064297?v=4",
|
||||
"profile": "https://github.com/deqingLv",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "littleplus",
|
||||
"name": "littleplus",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/11694750?v=4",
|
||||
"profile": "https://github.com/littleplus",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Nello-Angelo",
|
||||
"name": "Konstantin",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/82488489?v=4",
|
||||
"profile": "https://www.linkedin.com/in/%D0%BA%D0%BE%D0%BD%D1%81%D1%82%D0%B0%D0%BD%D1%82%D0%B8%D0%BD-%D0%B0%D0%BA%D0%B0%D0%BA%D0%B8%D0%B5%D0%B2-13130b1b4/",
|
||||
"contributions": [
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "kiragoo",
|
||||
"name": "kiragoo",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/7400711?v=4",
|
||||
"profile": "https://kiragoo.github.io",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jojotong",
|
||||
"name": "jojotong",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/100849526?v=4",
|
||||
"profile": "https://github.com/jojotong",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "littleBlackHouse",
|
||||
"name": "littleBlackHouse",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/54946465?v=4",
|
||||
"profile": "https://github.com/littleBlackHouse",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "testwill",
|
||||
"name": "guangwu",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/8717479?v=4",
|
||||
"profile": "https://github.com/testwill",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "wongearl",
|
||||
"name": "wongearl",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/36498442?v=4",
|
||||
"profile": "https://github.com/wongearl",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "wenwenxiong",
|
||||
"name": "wenwenxiong",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/10548812?v=4",
|
||||
"profile": "https://github.com/wenwenxiong",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "BaiMeow",
|
||||
"name": "柏喵Sakura",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/38121125?v=4",
|
||||
"profile": "https://baimeow.cn/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "cuishuang",
|
||||
"name": "cui fliter",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/15921519?v=4",
|
||||
"profile": "https://dashen.tech",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "liuxu623",
|
||||
"name": "刘旭",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/9653438?v=4",
|
||||
"profile": "https://github.com/liuxu623",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
"skipCi": true,
|
||||
"commitType": "docs"
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 30
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 14
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- frozen
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Any further update will
|
||||
cause the issue/pull request to no longer be considered stale. Thank you for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue is being automatically closed due to inactivity.
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
name: Bug Report
|
||||
description: File a bug report
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
id: preface
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
- type: markdown
|
||||
id: environment
|
||||
attributes:
|
||||
value: "## Environment"
|
||||
- type: input
|
||||
id: version
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: What is version of KubeKey has the issue?
|
||||
description: "You can use the command to get `./kk version`"
|
||||
- type: input
|
||||
id: os
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: What is your os environment?
|
||||
description: "e.g. Ubuntu 16.04"
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: KubeKey config file
|
||||
description: "If applicable, add the KubeKey config file content to help explain your problem."
|
||||
render: yaml
|
||||
- type: markdown
|
||||
id: main
|
||||
attributes:
|
||||
value: "## Main"
|
||||
- type: textarea
|
||||
id: what
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: A clear and concise description of what happend.
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: "Relevant log output"
|
||||
description: "Please copy and paste any relevant log output."
|
||||
render: shell
|
||||
- type: textarea
|
||||
id: additional-information
|
||||
attributes:
|
||||
label: "Additional information"
|
||||
description: "Add any other context about the information here (screenshots, video, etc.)."
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Any other questions about KubeKey
|
||||
url: https://kubesphere.slack.com/
|
||||
about: If you have any other questions, you can join our slack channel.
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
name: Feature Request
|
||||
description: File a feature request
|
||||
body:
|
||||
- type: markdown
|
||||
id: preface
|
||||
attributes:
|
||||
value: "Thank you for submitting new features for KubeKey."
|
||||
- type: markdown
|
||||
id: environment
|
||||
attributes:
|
||||
value: "## Environment"
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: "Your current KubeKey version"
|
||||
description: "You can use the command to get `./kk version`"
|
||||
- type: markdown
|
||||
id: main
|
||||
attributes:
|
||||
value: "## Main"
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: "Describe this feature"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: "Describe the solution you'd like"
|
||||
description: "You can have a concise description of any alternative solutions or ideas you've considered."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: additional-information
|
||||
attributes:
|
||||
label: "Additional information"
|
||||
description: "Add any other context about the information here (screenshots, video, etc.)."
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
approvers:
|
||||
- pixiake
|
||||
- Forest-L
|
||||
- rayzhou2017
|
||||
- LinuxSuRen
|
||||
|
||||
reviewers:
|
||||
- pixiake
|
||||
- Forest-L
|
||||
- rayzhou2017
|
||||
- zryfish
|
||||
- shaowenchen
|
||||
- benjaminhuo
|
||||
- calvinyv
|
||||
- FeynmanZhou
|
||||
- huanggze
|
||||
- wansir
|
||||
- LinuxSuRen
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
<!-- Thanks for sending a pull request! Here are some tips for you:
|
||||
|
||||
1. If you want **faster** PR reviews, read how: https://github.com/kubesphere/community/blob/master/developer-guide/development/the-pr-author-guide-to-getting-through-code-review.md
|
||||
2. In case you want to know how your PR got reviewed, read: https://github.com/kubesphere/community/blob/master/developer-guide/development/code-review-guide.md
|
||||
3. Here are some coding conventions followed by KubeSphere community: https://github.com/kubesphere/community/blob/master/developer-guide/development/coding-conventions.md
|
||||
-->
|
||||
|
||||
### What type of PR is this?
|
||||
<!--
|
||||
Add one of the following kinds:
|
||||
/kind bug
|
||||
/kind cleanup
|
||||
/kind documentation
|
||||
/kind feature
|
||||
/kind design
|
||||
/kind dependencies
|
||||
/kind test
|
||||
|
||||
Optionally add one or more of the following kinds if applicable:
|
||||
/kind api-change
|
||||
/kind deprecation
|
||||
/kind failing-test
|
||||
/kind flake
|
||||
/kind regression
|
||||
-->
|
||||
|
||||
|
||||
### What this PR does / why we need it:
|
||||
|
||||
### Which issue(s) this PR fixes:
|
||||
<!--
|
||||
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
|
||||
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
|
||||
-->
|
||||
Fixes #
|
||||
|
||||
### Special notes for reviewers:
|
||||
```
|
||||
```
|
||||
|
||||
### Does this PR introduced a user-facing change?
|
||||
<!--
|
||||
If no, just write "None" in the release-note block below.
|
||||
If yes, a release note is required:
|
||||
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".
|
||||
|
||||
For more information on release notes see: https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md
|
||||
-->
|
||||
```release-note
|
||||
|
||||
```
|
||||
|
||||
### Additional documentation, usage docs, etc.:
|
||||
<!--
|
||||
This section can be blank if this pull request does not require a release note.
|
||||
Please use the following format for linking documentation or pass the
|
||||
section below:
|
||||
- [KEP]: <link>
|
||||
- [Usage]: <link>
|
||||
- [Other doc]: <link>
|
||||
-->
|
||||
```docs
|
||||
|
||||
```
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
pull-request-branch-name:
|
||||
separator: "-"
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
pull-request-branch-name:
|
||||
separator: "-"
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
# Configuration for Release Drafter: https://github.com/toolmantim/release-drafter
|
||||
name-template: 'v$NEXT_PATCH_VERSION 🌈'
|
||||
tag-template: 'v$NEXT_PATCH_VERSION'
|
||||
version-template: $MAJOR.$MINOR.$PATCH
|
||||
# Emoji reference: https://gitmoji.carloscuesta.me/
|
||||
categories:
|
||||
- title: '🚀 Features'
|
||||
labels:
|
||||
- 'feature'
|
||||
- 'enhancement'
|
||||
- 'kind/feature'
|
||||
- title: '🐛 Bug Fixes'
|
||||
labels:
|
||||
- 'fix'
|
||||
- 'bugfix'
|
||||
- 'bug'
|
||||
- 'regression'
|
||||
- 'kind/bug'
|
||||
- title: 📝 Documentation updates
|
||||
labels:
|
||||
- 'documentation'
|
||||
- 'kind/documentation'
|
||||
- title: 👻 Maintenance
|
||||
labels:
|
||||
- chore
|
||||
- dependencies
|
||||
- 'kind/cleanup'
|
||||
- title: 🚦 Tests
|
||||
labels:
|
||||
- test
|
||||
- tests
|
||||
exclude-labels:
|
||||
- reverted
|
||||
- no-changelog
|
||||
- skip-changelog
|
||||
- invalid
|
||||
change-template: '* $TITLE (#$NUMBER) @$AUTHOR'
|
||||
template: |
|
||||
## What’s Changed
|
||||
|
||||
$CHANGES
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
repository:
|
||||
name: kubekey
|
||||
description: "KubeKey provides a flexible, rapid and convenient way to install Kubernetes only, both Kubernetes and KubeSphere, and related cloud-native add-ons. It is also an efficient tool to scale and upgrade your cluster."
|
||||
homepage: https://kubesphere.io/
|
||||
private: false
|
||||
has_issues: true
|
||||
has_wiki: false
|
||||
has_downloads: false
|
||||
default_branch: master
|
||||
allow_squash_merge: true
|
||||
allow_merge_commit: true
|
||||
allow_rebase_merge: true
|
||||
labels:
|
||||
- name: newbie
|
||||
color: abe7f4
|
||||
description: These're friendly issues for new comers
|
||||
- name: bug
|
||||
color: d73a4a
|
||||
description: Something isn't working
|
||||
- name: feature
|
||||
color: ffc6a3
|
||||
- name: enhancement
|
||||
color: a2eeef
|
||||
description: New feature or request
|
||||
- name: help wanted
|
||||
color: 008672
|
||||
description: Extra attention is needed
|
||||
- name: bugfix
|
||||
color: 0412d6
|
||||
- name: regression
|
||||
color: c5def5
|
||||
- name: documentation
|
||||
color: 5ce05e
|
||||
- name: Hacktoberfest
|
||||
description: More details from https://hacktoberfest.digitalocean.com/
|
||||
color: 5ce05e
|
||||
- name: test
|
||||
color: c2c2fc
|
||||
- name: chore
|
||||
color: c2c2fc
|
||||
- name: dependencies
|
||||
color: 0366d6
|
||||
description: Pull requests that update a dependency file
|
||||
- name: no-changelog
|
||||
color: c2c2fc
|
||||
- name: priority-high
|
||||
color: D93F0B
|
||||
- name: priority-medium
|
||||
color: FBCA04
|
||||
- name: priority-low
|
||||
color: 006B75
|
||||
branches:
|
||||
- name: master
|
||||
protection:
|
||||
required_pull_request_reviews:
|
||||
required_approving_review_count: 1
|
||||
dismiss_stale_reviews: true
|
||||
require_code_owner_reviews: true
|
||||
dismissal_restrictions:
|
||||
users: []
|
||||
teams: []
|
||||
required_status_checks:
|
||||
strict: true
|
||||
contexts: []
|
||||
enforce_admins: false
|
||||
restrictions:
|
||||
users: []
|
||||
teams: []
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
name: BuildContainerImage
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v3*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GO111MODULE: on
|
||||
steps:
|
||||
- name: Set env
|
||||
run: echo "RELEASE_TAG=${GITHUB_REF:10}" >> $GITHUB_ENV
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
with:
|
||||
platforms: all
|
||||
|
||||
- name: Set up Docker buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Build and push docker images
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
|
||||
make release-prod
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'release*'
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GO111MODULE: on
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.19
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Downloading go dependencies
|
||||
run: go mod tidy
|
||||
|
||||
# If there are any diffs from goimports or go mod tidy, fail.
|
||||
- name: Verify no changes from goimports and go mod tidy.
|
||||
run: |
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
echo 'To fix this check, run "go mod tidy"'
|
||||
git status # Show the files that failed to pass the check.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build command-line tool
|
||||
run: |
|
||||
make kk
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
---
|
||||
name: gen-repository-iso
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: centos7-rpms
|
||||
dockerfile: dockerfile.centos7
|
||||
- name: almalinux-9.0-rpms
|
||||
dockerfile: dockerfile.almalinux90
|
||||
- name: debian10-debs
|
||||
dockerfile: dockerfile.debian10
|
||||
- name: debian11-debs
|
||||
dockerfile: dockerfile.debian11
|
||||
- name: ubuntu-16.04-debs
|
||||
dockerfile: dockerfile.ubuntu1604
|
||||
- name: ubuntu-18.04-debs
|
||||
dockerfile: dockerfile.ubuntu1804
|
||||
- name: ubuntu-20.04-debs
|
||||
dockerfile: dockerfile.ubuntu2004
|
||||
- name: ubuntu-22.04-debs
|
||||
dockerfile: dockerfile.ubuntu2204
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Build iso image to local
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: hack/gen-repository-iso
|
||||
file: hack/gen-repository-iso/${{ matrix.dockerfile }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
outputs: type=local,dest=./output
|
||||
|
||||
- name: Prepare for upload iso
|
||||
shell: bash
|
||||
run: |
|
||||
mv ./output/linux_amd64/*.iso ${{ matrix.name }}-amd64.iso
|
||||
mv ./output/linux_arm64/*.iso ${{ matrix.name }}-arm64.iso
|
||||
sha256sum *.iso > ${{ matrix.name }}.iso.sha256sum.txt
|
||||
|
||||
- name: Wait for release workflow to finish
|
||||
uses: lewagon/wait-on-check-action@v1.3.1
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
check-name: 'create draft release'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Release and upload packages
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
draft: true
|
||||
files: |
|
||||
${{ matrix.name }}.iso.sha256sum.txt
|
||||
${{ matrix.name }}-amd64.iso
|
||||
${{ matrix.name }}-arm64.iso
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
name: golangci-lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, synchronize, reopened]
|
||||
|
||||
# Remove all permissions from GITHUB_TOKEN except metadata.
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
golangci:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
working-directory:
|
||||
- ""
|
||||
- test
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3.6.0
|
||||
with:
|
||||
version: v1.50.1
|
||||
working-directory: ${{matrix.working-directory}}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
---
|
||||
name: Kubernetes-Auto-Support
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
update-kubernetes-version:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'kubesphere/kubekey'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Go 1.19
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
id: go
|
||||
|
||||
- name: install dependiencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install skopeo -y
|
||||
pip install natsort
|
||||
wget https://attack-on-titan.gd2.qingstor.com/qsctl/v2.4.3/qsctl_v2.4.3_linux_amd64.tar.gz
|
||||
tar -zxvf qsctl_v2.4.3_linux_amd64.tar.gz
|
||||
mv qsctl_v2.4.3_linux_amd64 /usr/local/bin/qsctl
|
||||
rm -rf qsctl_v2.4.3_linux_amd64.tar.gz
|
||||
|
||||
- name: update components.json
|
||||
id: get_new_version
|
||||
run: |
|
||||
chmod +x hack/auto-update-version.py
|
||||
hack/auto-update-version.py
|
||||
[ -f version.tmp ] && echo "UPDATE_VERSION=true" >> $GITHUB_OUTPUT || :
|
||||
|
||||
- name: sync kubernetes
|
||||
id: sync_kubernetes
|
||||
run: |
|
||||
for v in $(cat version.tmp)
|
||||
do
|
||||
KUBERNETES_VERSION=$v QSCTL_ACCESS_KEY_ID=${{ secrets.QSCTL_ACCESS_KEY_ID }} QSCTL_SECRET_ACCESS_KEY=${{secrets.QSCTL_SECRET_ACCESS_KEY}} DOCKERHUB_USERNAME=${{ secrets.DOCKERHUB_USERNAME }} DOCKERHUB_PASSWORD=${{ secrets.DOCKERHUB_PASSWORD }} ALIYUNCS_USERNAME=${{ secrets.ALIYUNCS_USERNAME }} ALIYUNCS_PASSWORD=${{ secrets.ALIYUNCS_PASSWORD }} bash hack/sync-components.sh
|
||||
done
|
||||
echo "NEW_VERSION=`cat version.tmp | tr '\n' ', '`" >> $GITHUB_OUTPUT
|
||||
rm -rf qsctl-config.yaml
|
||||
rm -rf version.tmp
|
||||
|
||||
make kk
|
||||
chmod +x bin/kk
|
||||
echo "## Kubernetes Versions(amd64/arm64)" > docs/kubernetes-versions.md
|
||||
echo "| Version | Supported |" >> docs/kubernetes-versions.md
|
||||
echo "|----------|--------------------|" >> docs/kubernetes-versions.md
|
||||
bin/kk version --show-supported-k8s | ( while read version; do echo "| $version | :white_check_mark: |" >> docs/kubernetes-versions.md; done )
|
||||
|
||||
if: steps.get_new_version.outputs.UPDATE_VERSION == 'true'
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: Add new kubernetes version
|
||||
committer: GitHub <noreply@github.com>
|
||||
signoff: false
|
||||
branch: new_version
|
||||
delete-branch: true
|
||||
title: 'Add new kubernetes version'
|
||||
body: |
|
||||
Add kubernetes version: ${{ steps.sync_kubernetes.outputs.NEW_VERSION }}
|
||||
|
||||
if: steps.get_new_version.outputs.UPDATE_VERSION == 'true'
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
name: Release Drafter
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
update_release_draft:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: release-drafter/release-drafter@v5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: create draft release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set env
|
||||
run: echo "RELEASE_TAG=${GITHUB_REF:10}" >> $GITHUB_ENV
|
||||
- name: checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.19'
|
||||
- name: generate release artifacts
|
||||
run: |
|
||||
make release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
draft: true
|
||||
files: out/*
|
||||
|
||||
- name: Get Version
|
||||
id: get_version
|
||||
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||||
- name: Synchronize artifacts to OSS
|
||||
run: |
|
||||
rm -rf qsctl_v2.4.3_linux_amd64.tar.gz
|
||||
wget https://attack-on-titan.gd2.qingstor.com/qsctl/v2.4.3/qsctl_v2.4.3_linux_amd64.tar.gz
|
||||
tar -zxvf qsctl_v2.4.3_linux_amd64.tar.gz
|
||||
rm -rf qsctl_v2.4.3_linux_amd64.tar.gz
|
||||
mv qsctl_v2.4.3_linux_amd64 /usr/local/bin/qsctl
|
||||
echo "access_key_id: ${{secrets.KS_QSCTL_ACCESS_KEY_ID}}" > qsctl-config.yaml
|
||||
echo "secret_access_key: ${{ secrets.KS_QSCTL_SECRET_ACCESS_KEY }}" >> qsctl-config.yaml
|
||||
qsctl cp out/kubekey-${{ steps.get_version.outputs.VERSION }}-linux-amd64.tar.gz qs://kubernetes/kubekey/releases/download/${{ steps.get_version.outputs.VERSION }}/kubekey-${{ steps.get_version.outputs.VERSION }}-linux-amd64.tar.gz -c qsctl-config.yaml
|
||||
qsctl cp out/kubekey-${{ steps.get_version.outputs.VERSION }}-linux-arm64.tar.gz qs://kubernetes/kubekey/releases/download/${{ steps.get_version.outputs.VERSION }}/kubekey-${{ steps.get_version.outputs.VERSION }}-linux-arm64.tar.gz -c qsctl-config.yaml
|
||||
rm -rf qsctl-config.yaml
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
*.tmp
|
||||
bin
|
||||
hack/tools/bin
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# E2E test templates
|
||||
test/e2e/data/infrastructure-kubekey/v1beta1/cluster-template*.yaml
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# IntelliJ
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
# Vscode files
|
||||
.vscode
|
||||
|
||||
# rbac and manager config for example provider
|
||||
manager_image_patch.yaml-e
|
||||
manager_pull_policy.yaml-e
|
||||
|
||||
# Sample config files auto-generated by kubebuilder
|
||||
config/samples
|
||||
|
||||
# test results
|
||||
_artifacts
|
||||
|
||||
# Used during parts of the build process. Files _should_ get cleaned up automatically.
|
||||
# This is also a good location for any temporary manfiests used during development
|
||||
tmp
|
||||
288
.golangci.yml
288
.golangci.yml
|
|
@ -1,288 +0,0 @@
|
|||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- asciicheck
|
||||
- bodyclose
|
||||
- containedctx
|
||||
- deadcode
|
||||
- depguard
|
||||
- dogsled
|
||||
- errcheck
|
||||
- exportloopref
|
||||
- gci
|
||||
- goconst
|
||||
- gocritic
|
||||
- gofmt
|
||||
- goimports
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- importas
|
||||
- ineffassign
|
||||
- misspell
|
||||
- nakedret
|
||||
- nilerr
|
||||
- noctx
|
||||
- nolintlint
|
||||
- prealloc
|
||||
- predeclared
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- stylecheck
|
||||
- thelper
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- varcheck
|
||||
- whitespace
|
||||
|
||||
linters-settings:
|
||||
godot:
|
||||
# declarations - for top level declaration comments (default);
|
||||
# toplevel - for top level comments;
|
||||
# all - for all comments.
|
||||
scope: toplevel
|
||||
exclude:
|
||||
- '^ \+.*'
|
||||
- '^ ANCHOR.*'
|
||||
ifshort:
|
||||
# Maximum length of variable declaration measured in number of characters, after which linter won't suggest using short syntax.
|
||||
max-decl-chars: 50
|
||||
gci:
|
||||
local-prefixes: "github.com/kubesphere/kubekey"
|
||||
importas:
|
||||
no-unaliased: true
|
||||
alias:
|
||||
# Kubernetes
|
||||
- pkg: k8s.io/api/core/v1
|
||||
alias: corev1
|
||||
- pkg: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1
|
||||
alias: apiextensionsv1
|
||||
- pkg: k8s.io/apimachinery/pkg/apis/meta/v1
|
||||
alias: metav1
|
||||
- pkg: k8s.io/apimachinery/pkg/api/errors
|
||||
alias: apierrors
|
||||
- pkg: k8s.io/apimachinery/pkg/util/errors
|
||||
alias: kerrors
|
||||
# Controller Runtime
|
||||
- pkg: sigs.k8s.io/controller-runtime
|
||||
alias: ctrl
|
||||
# CABPK
|
||||
- pkg: sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3
|
||||
alias: bootstrapv1alpha3
|
||||
- pkg: sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4
|
||||
alias: bootstrapv1alpha4
|
||||
- pkg: sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1
|
||||
alias: bootstrapv1
|
||||
# KCP
|
||||
- pkg: sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha3
|
||||
alias: controlplanev1alpha3
|
||||
- pkg: sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha4
|
||||
alias: controlplanev1alpha4
|
||||
- pkg: sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1
|
||||
alias: controlplanev1
|
||||
# CAPI
|
||||
- pkg: sigs.k8s.io/cluster-api/api/v1alpha3
|
||||
alias: clusterv1alpha3
|
||||
- pkg: sigs.k8s.io/cluster-api/api/v1alpha4
|
||||
alias: clusterv1alpha4
|
||||
- pkg: sigs.k8s.io/cluster-api/api/v1beta1
|
||||
alias: clusterv1
|
||||
# CAPI exp
|
||||
- pkg: sigs.k8s.io/cluster-api/exp/api/v1alpha3
|
||||
alias: expv1alpha3
|
||||
- pkg: sigs.k8s.io/cluster-api/exp/api/v1alpha4
|
||||
alias: expv1alpha4
|
||||
- pkg: sigs.k8s.io/cluster-api/exp/api/v1beta1
|
||||
alias: expv1
|
||||
# CAPI exp addons
|
||||
- pkg: sigs.k8s.io/cluster-api/exp/addons/api/v1alpha3
|
||||
alias: addonsv1alpha3
|
||||
- pkg: sigs.k8s.io/cluster-api/exp/addons/api/v1alpha4
|
||||
alias: addonsv1alpha4
|
||||
- pkg: sigs.k8s.io/cluster-api/exp/addons/api/v1beta1
|
||||
alias: addonsv1
|
||||
# CAPI exp runtime
|
||||
- pkg: sigs.k8s.io/cluster-api/exp/runtime/api/v1alpha1
|
||||
alias: runtimev1
|
||||
- pkg: sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1
|
||||
alias: runtimehooksv1
|
||||
- pkg: sigs.k8s.io/cluster-api/exp/runtime/controllers
|
||||
alias: runtimecontrollers
|
||||
- pkg: sigs.k8s.io/cluster-api/exp/runtime/catalog
|
||||
alias: runtimecatalog
|
||||
- pkg: sigs.k8s.io/cluster-api/internal/runtime/client
|
||||
alias: runtimeclient
|
||||
- pkg: sigs.k8s.io/cluster-api/internal/runtime/registry
|
||||
alias: runtimeregistry
|
||||
- pkg: sigs.k8s.io/cluster-api/internal/webhooks/runtime
|
||||
alias: runtimewebhooks
|
||||
# CAPKK
|
||||
- pkg: github.com/kubesphere/kubekey/v3/api/v1beta1
|
||||
alias: infrav1
|
||||
- pkg: github.com/kubesphere/kubekey/v3/bootstrap/k3s/api/v1beta1
|
||||
alias: infrabootstrapv1
|
||||
- pkg: github.com/kubesphere/kubekey/v3/controlplane/k3s/api/v1beta1
|
||||
alias: infracontrolplanev1
|
||||
nolintlint:
|
||||
allow-unused: false
|
||||
allow-leading-space: false
|
||||
require-specific: true
|
||||
revive:
|
||||
rules:
|
||||
# The following rules are recommended https://github.com/mgechev/revive#recommended-configuration
|
||||
- name: blank-imports
|
||||
- name: context-as-argument
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
- name: exported
|
||||
#- name: if-return # TODO This is a recommended rule with many findings which may require it's own pr.
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: var-declaration
|
||||
- name: package-comments
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: time-naming
|
||||
- name: unexported-return
|
||||
- name: indent-error-flow
|
||||
- name: errorf
|
||||
- name: empty-block
|
||||
- name: superfluous-else
|
||||
#- name: unused-parameter # TODO This is a recommended rule with many findings which may require it's own pr.
|
||||
- name: unreachable-code
|
||||
- name: redefines-builtin-id
|
||||
#
|
||||
# Rules in addition to the recommended configuration above.
|
||||
#
|
||||
- name: bool-literal-in-expr
|
||||
- name: constant-logical-expr
|
||||
gosec:
|
||||
excludes:
|
||||
- G307 # Deferring unsafe method "Close" on type "\*os.File"
|
||||
- G108 # Profiling endpoint is automatically exposed on /debug/pprof
|
||||
gocritic:
|
||||
enabled-tags:
|
||||
- experimental
|
||||
disabled-checks:
|
||||
- appendAssign
|
||||
- dupImport # https://github.com/go-critic/go-critic/issues/845
|
||||
- evalOrder
|
||||
- ifElseChain
|
||||
- octalLiteral
|
||||
- regexpSimplify
|
||||
- sloppyReassign
|
||||
- truncateCmp
|
||||
- typeDefFirst
|
||||
- unnamedResult
|
||||
- unnecessaryDefer
|
||||
- whyNoLint
|
||||
- wrapperFunc
|
||||
- commentFormatting
|
||||
- filepathJoin
|
||||
- rangeValCopy
|
||||
- hugeParam
|
||||
issues:
|
||||
max-same-issues: 0
|
||||
max-issues-per-linter: 0
|
||||
# We are disabling default golangci exclusions because we want to help reviewers to focus on reviewing the most relevant
|
||||
# changes in PRs and avoid nitpicking.
|
||||
exclude-use-default: false
|
||||
exclude-rules:
|
||||
- linters:
|
||||
- revive
|
||||
text: "exported: exported method .*\\.(Reconcile|SetupWithManager|SetupWebhookWithManager) should have comment or be unexported"
|
||||
- linters:
|
||||
- errcheck
|
||||
text: Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked
|
||||
# Exclude revive's exported for certain packages and code, e.g. tests and fake.
|
||||
- linters:
|
||||
- revive
|
||||
text: exported (method|function|type|const) (.+) should have comment or be unexported
|
||||
source: (func|type).*Fake.*
|
||||
- linters:
|
||||
- revive
|
||||
text: exported (method|function|type|const) (.+) should have comment or be unexported
|
||||
path: fake_\.go
|
||||
- linters:
|
||||
- revive
|
||||
text: exported (method|function|type|const) (.+) should have comment or be unexported
|
||||
path: .*test/(providers|framework|e2e).*.go
|
||||
- linters:
|
||||
- errcheck
|
||||
text: Error return value is not checked
|
||||
path: _test\.go
|
||||
- linters:
|
||||
- errcheck
|
||||
text: Error return value of (.+) is not checked
|
||||
path: _test\.go
|
||||
- linters:
|
||||
- gosec
|
||||
text: "G108: Profiling endpoint is automatically exposed on /debug/pprof"
|
||||
- linters:
|
||||
- godot
|
||||
text: "Comment should end in a period"
|
||||
path: "(.*)/(v1beta1|v1beta2)/(.*)types.go"
|
||||
- linters:
|
||||
- errcheck
|
||||
text: Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked
|
||||
# With Go 1.16, the new embed directive can be used with an un-named import,
|
||||
# revive (previously, golint) only allows these to be imported in a main.go, which wouldn't work for us.
|
||||
# This directive allows the embed package to be imported with an underscore everywhere.
|
||||
- linters:
|
||||
- revive
|
||||
source: _ "embed"
|
||||
# This directive allows the variable in defaults.go files to have underscore
|
||||
- linters:
|
||||
- revive
|
||||
text: "var-naming: don't use underscores in Go names; func (.+) should be (.+)"
|
||||
path: .*/defaults.go
|
||||
# Disable unparam "always receives" which might not be really
|
||||
# useful when building libraries.
|
||||
- linters:
|
||||
- unparam
|
||||
text: always receives
|
||||
# Dot imports for gomega or ginkgo are allowed
|
||||
# within test files.
|
||||
- path: _test\.go
|
||||
text: should not use dot imports
|
||||
- path: (framework|e2e)/.*.go
|
||||
text: should not use dot imports
|
||||
- path: _test\.go
|
||||
text: cyclomatic complexity
|
||||
- linters:
|
||||
- unparam
|
||||
text: (.+) - (`t`|`g`) is unused
|
||||
- path: _test\.go
|
||||
text: cyclomatic complexity
|
||||
# Append should be able to assign to a different var/slice.
|
||||
- linters:
|
||||
- gocritic
|
||||
text: "appendAssign: append result not assigned to the same slice"
|
||||
# We don't care about defer in for loops in test files.
|
||||
- linters:
|
||||
- gocritic
|
||||
text: "deferInLoop: Possible resource leak, 'defer' is called in the 'for' loop"
|
||||
path: _test\.go
|
||||
|
||||
run:
|
||||
timeout: 10m
|
||||
go: "1.19"
|
||||
build-tags:
|
||||
- tools
|
||||
- e2e
|
||||
- containers_image_openpgp
|
||||
- exclude_graphdriver_devicemapper
|
||||
- exclude_graphdriver_btrfs
|
||||
skip-files:
|
||||
- "zz_generated.*\\.go$"
|
||||
- "vendored_openapi\\.go$"
|
||||
- "cmd"
|
||||
allow-parallel-runners: true
|
||||
122
CONTRIBUTORS.md
122
CONTRIBUTORS.md
|
|
@ -1,122 +0,0 @@
|
|||
### Sincere gratitude goes to the following people for their contributions to KubeKey
|
||||
|
||||
Contributions of any kind are welcome! Thanks goes to these wonderful contributors, they made our project grow fast.
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pixiake"><img src="https://avatars0.githubusercontent.com/u/22290449?v=4?s=100" width="100px;" alt="pixiake"/><br /><sub><b>pixiake</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=pixiake" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=pixiake" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Forest-L"><img src="https://avatars2.githubusercontent.com/u/50984129?v=4?s=100" width="100px;" alt="Forest"/><br /><sub><b>Forest</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Forest-L" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=Forest-L" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://kubesphere.io/"><img src="https://avatars2.githubusercontent.com/u/28859385?v=4?s=100" width="100px;" alt="rayzhou2017"/><br /><sub><b>rayzhou2017</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=rayzhou2017" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=rayzhou2017" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.chenshaowen.com/"><img src="https://avatars2.githubusercontent.com/u/43693241?v=4?s=100" width="100px;" alt="shaowenchen"/><br /><sub><b>shaowenchen</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=shaowenchen" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=shaowenchen" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://surenpi.com/"><img src="https://avatars1.githubusercontent.com/u/1450685?v=4?s=100" width="100px;" alt="Zhao Xiaojie"/><br /><sub><b>Zhao Xiaojie</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=LinuxSuRen" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=LinuxSuRen" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zackzhangkai"><img src="https://avatars1.githubusercontent.com/u/20178386?v=4?s=100" width="100px;" alt="Zack Zhang"/><br /><sub><b>Zack Zhang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zackzhangkai" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://akhilerm.com/"><img src="https://avatars1.githubusercontent.com/u/7610845?v=4?s=100" width="100px;" alt="Akhil Mohan"/><br /><sub><b>Akhil Mohan</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=akhilerm" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeynmanZhou"><img src="https://avatars3.githubusercontent.com/u/40452856?v=4?s=100" width="100px;" alt="pengfei"/><br /><sub><b>pengfei</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=FeynmanZhou" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/min-zh"><img src="https://avatars1.githubusercontent.com/u/35321102?v=4?s=100" width="100px;" alt="min zhang"/><br /><sub><b>min zhang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=min-zh" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=min-zh" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zgldh"><img src="https://avatars1.githubusercontent.com/u/312404?v=4?s=100" width="100px;" alt="zgldh"/><br /><sub><b>zgldh</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zgldh" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xrjk"><img src="https://avatars0.githubusercontent.com/u/16330256?v=4?s=100" width="100px;" alt="xrjk"/><br /><sub><b>xrjk</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=xrjk" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/stoneshi-yunify"><img src="https://avatars2.githubusercontent.com/u/70880165?v=4?s=100" width="100px;" alt="yonghongshi"/><br /><sub><b>yonghongshi</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=stoneshi-yunify" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shenhonglei"><img src="https://avatars2.githubusercontent.com/u/20896372?v=4?s=100" width="100px;" alt="Honglei"/><br /><sub><b>Honglei</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=shenhonglei" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liucy1983"><img src="https://avatars2.githubusercontent.com/u/2360302?v=4?s=100" width="100px;" alt="liucy1983"/><br /><sub><b>liucy1983</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=liucy1983" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lilien1010"><img src="https://avatars1.githubusercontent.com/u/3814966?v=4?s=100" width="100px;" alt="Lien"/><br /><sub><b>Lien</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lilien1010" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/klj890"><img src="https://avatars3.githubusercontent.com/u/19380605?v=4?s=100" width="100px;" alt="Tony Wang"/><br /><sub><b>Tony Wang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=klj890" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hlwanghl"><img src="https://avatars3.githubusercontent.com/u/4861515?v=4?s=100" width="100px;" alt="Hongliang Wang"/><br /><sub><b>Hongliang Wang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=hlwanghl" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://fafucoder.github.io/"><img src="https://avatars0.githubusercontent.com/u/16442491?v=4?s=100" width="100px;" alt="dawn"/><br /><sub><b>dawn</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=fafucoder" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/duanjiong"><img src="https://avatars1.githubusercontent.com/u/3678855?v=4?s=100" width="100px;" alt="Duan Jiong"/><br /><sub><b>Duan Jiong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=duanjiong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/calvinyv"><img src="https://avatars3.githubusercontent.com/u/28883416?v=4?s=100" width="100px;" alt="calvinyv"/><br /><sub><b>calvinyv</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=calvinyv" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/benjaminhuo"><img src="https://avatars2.githubusercontent.com/u/18525465?v=4?s=100" width="100px;" alt="Benjamin Huo"/><br /><sub><b>Benjamin Huo</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=benjaminhuo" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Sherlock113"><img src="https://avatars2.githubusercontent.com/u/65327072?v=4?s=100" width="100px;" alt="Sherlock113"/><br /><sub><b>Sherlock113</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Sherlock113" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fuchange"><img src="https://avatars1.githubusercontent.com/u/31716848?v=4?s=100" width="100px;" alt="fu_changjie"/><br /><sub><b>fu_changjie</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Fuchange" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yuswift"><img src="https://avatars1.githubusercontent.com/u/37265389?v=4?s=100" width="100px;" alt="yuswift"/><br /><sub><b>yuswift</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yuswift" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ruiyaoOps"><img src="https://avatars.githubusercontent.com/u/35256376?v=4?s=100" width="100px;" alt="ruiyaoOps"/><br /><sub><b>ruiyaoOps</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=ruiyaoOps" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.luxingmin.com"><img src="https://avatars.githubusercontent.com/u/1918195?v=4?s=100" width="100px;" alt="LXM"/><br /><sub><b>LXM</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lxm" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sbhnet"><img src="https://avatars.githubusercontent.com/u/2368131?v=4?s=100" width="100px;" alt="sbhnet"/><br /><sub><b>sbhnet</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=sbhnet" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/misteruly"><img src="https://avatars.githubusercontent.com/u/31399968?v=4?s=100" width="100px;" alt="misteruly"/><br /><sub><b>misteruly</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=misteruly" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://johnniang.me"><img src="https://avatars.githubusercontent.com/u/16865714?v=4?s=100" width="100px;" alt="John Niang"/><br /><sub><b>John Niang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=JohnNiang" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://alimy.me"><img src="https://avatars.githubusercontent.com/u/10525842?v=4?s=100" width="100px;" alt="Michael Li"/><br /><sub><b>Michael Li</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=alimy" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/duguhaotian"><img src="https://avatars.githubusercontent.com/u/3174621?v=4?s=100" width="100px;" alt="独孤昊天"/><br /><sub><b>独孤昊天</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=duguhaotian" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lshmouse"><img src="https://avatars.githubusercontent.com/u/118687?v=4?s=100" width="100px;" alt="Liu Shaohui"/><br /><sub><b>Liu Shaohui</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lshmouse" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/24sama"><img src="https://avatars.githubusercontent.com/u/43993589?v=4?s=100" width="100px;" alt="Leo Li"/><br /><sub><b>Leo Li</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=24sama" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RolandMa1986"><img src="https://avatars.githubusercontent.com/u/1720333?v=4?s=100" width="100px;" alt="Roland"/><br /><sub><b>Roland</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=RolandMa1986" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://ops.m114.org"><img src="https://avatars.githubusercontent.com/u/2347587?v=4?s=100" width="100px;" alt="Vinson Zou"/><br /><sub><b>Vinson Zou</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=vinsonzou" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tagGeeY"><img src="https://avatars.githubusercontent.com/u/35259969?v=4?s=100" width="100px;" alt="tag_gee_y"/><br /><sub><b>tag_gee_y</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=tagGeeY" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liulangwa"><img src="https://avatars.githubusercontent.com/u/25916792?v=4?s=100" width="100px;" alt="codebee"/><br /><sub><b>codebee</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=liulangwa" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TheApeMachine"><img src="https://avatars.githubusercontent.com/u/9572060?v=4?s=100" width="100px;" alt="Daniel Owen van Dommelen"/><br /><sub><b>Daniel Owen van Dommelen</b></sub></a><br /><a href="#ideas-TheApeMachine" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Naidile-P-N"><img src="https://avatars.githubusercontent.com/u/29476402?v=4?s=100" width="100px;" alt="Naidile P N"/><br /><sub><b>Naidile P N</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Naidile-P-N" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/haiker2011"><img src="https://avatars.githubusercontent.com/u/8073429?v=4?s=100" width="100px;" alt="Haiker Sun"/><br /><sub><b>Haiker Sun</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=haiker2011" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yj-cloud"><img src="https://avatars.githubusercontent.com/u/19648473?v=4?s=100" width="100px;" alt="Jing Yu"/><br /><sub><b>Jing Yu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yj-cloud" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chaunceyjiang"><img src="https://avatars.githubusercontent.com/u/17962021?v=4?s=100" width="100px;" alt="Chauncey"/><br /><sub><b>Chauncey</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=chaunceyjiang" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tanguofu"><img src="https://avatars.githubusercontent.com/u/87045830?v=4?s=100" width="100px;" alt="Tan Guofu"/><br /><sub><b>Tan Guofu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=tanguofu" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lvillis"><img src="https://avatars.githubusercontent.com/u/56720445?v=4?s=100" width="100px;" alt="lvillis"/><br /><sub><b>lvillis</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lvillis" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/vincenthe11"><img src="https://avatars.githubusercontent.com/u/8400716?v=4?s=100" width="100px;" alt="Vincent He"/><br /><sub><b>Vincent He</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=vincenthe11" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://laminar.fun/"><img src="https://avatars.githubusercontent.com/u/2360535?v=4?s=100" width="100px;" alt="laminar"/><br /><sub><b>laminar</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=tpiperatgod" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cumirror"><img src="https://avatars.githubusercontent.com/u/2455429?v=4?s=100" width="100px;" alt="tongjin"/><br /><sub><b>tongjin</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=cumirror" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://k8s.li"><img src="https://avatars.githubusercontent.com/u/42566386?v=4?s=100" width="100px;" alt="Reimu"/><br /><sub><b>Reimu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=muzi502" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt="Ikko Ashimine"/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=eltociear" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://yeya24.github.io/"><img src="https://avatars.githubusercontent.com/u/25150124?v=4?s=100" width="100px;" alt="Ben Ye"/><br /><sub><b>Ben Ye</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yeya24" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yinheli"><img src="https://avatars.githubusercontent.com/u/235094?v=4?s=100" width="100px;" alt="yinheli"/><br /><sub><b>yinheli</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yinheli" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hellocn9"><img src="https://avatars.githubusercontent.com/u/102210430?v=4?s=100" width="100px;" alt="hellocn9"/><br /><sub><b>hellocn9</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=hellocn9" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/brandan-schmitz"><img src="https://avatars.githubusercontent.com/u/6267549?v=4?s=100" width="100px;" alt="Brandan Schmitz"/><br /><sub><b>Brandan Schmitz</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=brandan-schmitz" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yjqg6666"><img src="https://avatars.githubusercontent.com/u/1879641?v=4?s=100" width="100px;" alt="yjqg6666"/><br /><sub><b>yjqg6666</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yjqg6666" title="Documentation">📖</a> <a href="https://github.com/kubesphere/kubekey/commits?author=yjqg6666" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zaunist"><img src="https://avatars.githubusercontent.com/u/38528079?v=4?s=100" width="100px;" alt="失眠是真滴难受"/><br /><sub><b>失眠是真滴难受</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zaunist" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mangoGoForward"><img src="https://avatars.githubusercontent.com/u/35127166?v=4?s=100" width="100px;" alt="mango"/><br /><sub><b>mango</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/pulls?q=is%3Apr+reviewed-by%3AmangoGoForward" title="Reviewed Pull Requests">👀</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wenwutang1"><img src="https://avatars.githubusercontent.com/u/45817987?v=4?s=100" width="100px;" alt="wenwutang"/><br /><sub><b>wenwutang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=wenwutang1" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://kuops.com"><img src="https://avatars.githubusercontent.com/u/18283256?v=4?s=100" width="100px;" alt="Shiny Hou"/><br /><sub><b>Shiny Hou</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=kuops" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhouqiu0103"><img src="https://avatars.githubusercontent.com/u/108912268?v=4?s=100" width="100px;" alt="zhouqiu0103"/><br /><sub><b>zhouqiu0103</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zhouqiu0103" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/77yu77"><img src="https://avatars.githubusercontent.com/u/73932296?v=4?s=100" width="100px;" alt="77yu77"/><br /><sub><b>77yu77</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=77yu77" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hzhhong"><img src="https://avatars.githubusercontent.com/u/83079531?v=4?s=100" width="100px;" alt="hzhhong"/><br /><sub><b>hzhhong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=hzhhong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/arugal"><img src="https://avatars.githubusercontent.com/u/26432832?v=4?s=100" width="100px;" alt="zhang-wei"/><br /><sub><b>zhang-wei</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=arugal" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/xds2000"><img src="https://avatars.githubusercontent.com/u/37678?v=4?s=100" width="100px;" alt="Deshi Xiao"/><br /><sub><b>Deshi Xiao</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=xiaods" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=xiaods" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://besscroft.com"><img src="https://avatars.githubusercontent.com/u/33775809?v=4?s=100" width="100px;" alt="besscroft"/><br /><sub><b>besscroft</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=besscroft" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhangzhiqiangcs"><img src="https://avatars.githubusercontent.com/u/8319897?v=4?s=100" width="100px;" alt="张志强"/><br /><sub><b>张志强</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zhangzhiqiangcs" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwabish"><img src="https://avatars.githubusercontent.com/u/7044019?v=4?s=100" width="100px;" alt="lwabish"/><br /><sub><b>lwabish</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lwabish" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=lwabish" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyz87"><img src="https://avatars.githubusercontent.com/u/36068894?v=4?s=100" width="100px;" alt="qyz87"/><br /><sub><b>qyz87</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=qyz87" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fangzhengjin"><img src="https://avatars.githubusercontent.com/u/12680972?v=4?s=100" width="100px;" alt="ZhengJin Fang"/><br /><sub><b>ZhengJin Fang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=fangzhengjin" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://lhr.wiki"><img src="https://avatars.githubusercontent.com/u/6327311?v=4?s=100" width="100px;" alt="Eric_Lian"/><br /><sub><b>Eric_Lian</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=ExerciseBook" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nicognaW"><img src="https://avatars.githubusercontent.com/u/66731869?v=4?s=100" width="100px;" alt="nicognaw"/><br /><sub><b>nicognaw</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=nicognaW" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/deqingLv"><img src="https://avatars.githubusercontent.com/u/6064297?v=4?s=100" width="100px;" alt="吕德庆"/><br /><sub><b>吕德庆</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=deqingLv" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littleplus"><img src="https://avatars.githubusercontent.com/u/11694750?v=4?s=100" width="100px;" alt="littleplus"/><br /><sub><b>littleplus</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=littleplus" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/%D0%BA%D0%BE%D0%BD%D1%81%D1%82%D0%B0%D0%BD%D1%82%D0%B8%D0%BD-%D0%B0%D0%BA%D0%B0%D0%BA%D0%B8%D0%B5%D0%B2-13130b1b4/"><img src="https://avatars.githubusercontent.com/u/82488489?v=4?s=100" width="100px;" alt="Konstantin"/><br /><sub><b>Konstantin</b></sub></a><br /><a href="#ideas-Nello-Angelo" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://kiragoo.github.io"><img src="https://avatars.githubusercontent.com/u/7400711?v=4?s=100" width="100px;" alt="kiragoo"/><br /><sub><b>kiragoo</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=kiragoo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jojotong"><img src="https://avatars.githubusercontent.com/u/100849526?v=4?s=100" width="100px;" alt="jojotong"/><br /><sub><b>jojotong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=jojotong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littleBlackHouse"><img src="https://avatars.githubusercontent.com/u/54946465?v=4?s=100" width="100px;" alt="littleBlackHouse"/><br /><sub><b>littleBlackHouse</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=littleBlackHouse" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=littleBlackHouse" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/testwill"><img src="https://avatars.githubusercontent.com/u/8717479?v=4?s=100" width="100px;" alt="guangwu"/><br /><sub><b>guangwu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=testwill" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=testwill" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wongearl"><img src="https://avatars.githubusercontent.com/u/36498442?v=4?s=100" width="100px;" alt="wongearl"/><br /><sub><b>wongearl</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=wongearl" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wenwenxiong"><img src="https://avatars.githubusercontent.com/u/10548812?v=4?s=100" width="100px;" alt="wenwenxiong"/><br /><sub><b>wenwenxiong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=wenwenxiong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://baimeow.cn/"><img src="https://avatars.githubusercontent.com/u/38121125?v=4?s=100" width="100px;" alt="柏喵Sakura"/><br /><sub><b>柏喵Sakura</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=BaiMeow" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://dashen.tech"><img src="https://avatars.githubusercontent.com/u/15921519?v=4?s=100" width="100px;" alt="cui fliter"/><br /><sub><b>cui fliter</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=cuishuang" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liuxu623"><img src="https://avatars.githubusercontent.com/u/9653438?v=4?s=100" width="100px;" alt="刘旭"/><br /><sub><b>刘旭</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=liuxu623" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
61
Dockerfile
61
Dockerfile
|
|
@ -1,61 +0,0 @@
|
|||
# Build architecture
|
||||
ARG ARCH
|
||||
|
||||
# Download dependencies
|
||||
FROM alpine:3.11 as base_os_context
|
||||
|
||||
|
||||
ENV OUTDIR=/out
|
||||
RUN mkdir -p ${OUTDIR}/usr/local/bin/
|
||||
|
||||
WORKDIR /tmp
|
||||
|
||||
RUN apk add --no-cache ca-certificates
|
||||
|
||||
# Build the manager binary
|
||||
FROM golang:1.19 as builder
|
||||
|
||||
# Run this with docker build --build_arg $(go env GOPROXY) to override the goproxy
|
||||
ARG goproxy=https://goproxy.cn,direct
|
||||
ENV GOPROXY=$goproxy
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
COPY go.mod go.mod
|
||||
COPY go.sum go.sum
|
||||
|
||||
# Cache deps before building and copying source so that we don't need to re-download as much
|
||||
# and so that source changes don't invalidate our downloaded layer
|
||||
RUN --mount=type=cache,target=/go/pkg/mod \
|
||||
go mod download
|
||||
|
||||
# Copy the go source
|
||||
COPY ./ ./
|
||||
|
||||
# Cache the go build into the the Go’s compiler cache folder so we take benefits of compiler caching across docker build calls
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
go build .
|
||||
|
||||
# Build
|
||||
ARG package=.
|
||||
ARG ARCH
|
||||
ARG LDFLAGS
|
||||
|
||||
# Do not force rebuild of up-to-date packages (do not use -a) and use the compiler cache folder
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} \
|
||||
go build -ldflags "${LDFLAGS}" \
|
||||
-o manager ${package}
|
||||
|
||||
FROM --platform=${ARCH} alpine:3.16
|
||||
|
||||
WORKDIR /
|
||||
|
||||
RUN mkdir -p /var/lib/kubekey/rootfs
|
||||
|
||||
COPY --from=base_os_context /out/ /
|
||||
COPY --from=builder /workspace/manager .
|
||||
|
||||
ENTRYPOINT ["/manager"]
|
||||
201
LICENSE
201
LICENSE
|
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2018-2020 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.
|
||||
601
Makefile
601
Makefile
|
|
@ -1,601 +0,0 @@
|
|||
# Ensure Make is run with bash shell as some syntax below is bash-specific
|
||||
SHELL:=/usr/bin/env bash
|
||||
|
||||
.DEFAULT_GOAL:=help
|
||||
|
||||
#
|
||||
# Go.
|
||||
#
|
||||
GO_VERSION ?= 1.19.2
|
||||
GO_CONTAINER_IMAGE ?= docker.io/library/golang:$(GO_VERSION)
|
||||
|
||||
# Use GOPROXY environment variable if set
|
||||
GOPROXY := $(shell go env GOPROXY)
|
||||
ifeq ($(GOPROXY),)
|
||||
GOPROXY := https://goproxy.cn,direct
|
||||
endif
|
||||
export GOPROXY
|
||||
|
||||
# Active module mode, as we use go modules to manage dependencies
|
||||
export GO111MODULE=on
|
||||
|
||||
# This option is for running docker manifest command
|
||||
export DOCKER_CLI_EXPERIMENTAL := enabled
|
||||
|
||||
#
|
||||
# Directories.
|
||||
#
|
||||
# Full directory of where the Makefile resides
|
||||
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||
EXP_DIR := exp
|
||||
BIN_DIR := bin
|
||||
TEST_DIR := test
|
||||
TOOLS_DIR := hack/tools
|
||||
TOOLS_BIN_DIR := $(abspath $(TOOLS_DIR)/$(BIN_DIR))
|
||||
E2E_FRAMEWORK_DIR := $(TEST_DIR)/framework
|
||||
GO_INSTALL := ./scripts/go_install.sh
|
||||
|
||||
export PATH := $(abspath $(TOOLS_BIN_DIR)):$(PATH)
|
||||
|
||||
#
|
||||
# Binaries.
|
||||
#
|
||||
# Note: Need to use abspath so we can invoke these from subdirectories
|
||||
KUSTOMIZE_VER := v4.5.2
|
||||
KUSTOMIZE_BIN := kustomize
|
||||
KUSTOMIZE := $(abspath $(TOOLS_BIN_DIR)/$(KUSTOMIZE_BIN)-$(KUSTOMIZE_VER))
|
||||
KUSTOMIZE_PKG := sigs.k8s.io/kustomize/kustomize/v4
|
||||
|
||||
SETUP_ENVTEST_VER := v0.0.0-20211110210527-619e6b92dab9
|
||||
SETUP_ENVTEST_BIN := setup-envtest
|
||||
SETUP_ENVTEST := $(abspath $(TOOLS_BIN_DIR)/$(SETUP_ENVTEST_BIN)-$(SETUP_ENVTEST_VER))
|
||||
SETUP_ENVTEST_PKG := sigs.k8s.io/controller-runtime/tools/setup-envtest
|
||||
|
||||
CONTROLLER_GEN_VER := v0.9.1
|
||||
CONTROLLER_GEN_BIN := controller-gen
|
||||
CONTROLLER_GEN := $(abspath $(TOOLS_BIN_DIR)/$(CONTROLLER_GEN_BIN)-$(CONTROLLER_GEN_VER))
|
||||
CONTROLLER_GEN_PKG := sigs.k8s.io/controller-tools/cmd/controller-gen
|
||||
|
||||
GOTESTSUM_VER := v1.6.4
|
||||
GOTESTSUM_BIN := gotestsum
|
||||
GOTESTSUM := $(abspath $(TOOLS_BIN_DIR)/$(GOTESTSUM_BIN)-$(GOTESTSUM_VER))
|
||||
GOTESTSUM_PKG := gotest.tools/gotestsum
|
||||
|
||||
HADOLINT_VER := v2.10.0
|
||||
HADOLINT_FAILURE_THRESHOLD = warning
|
||||
|
||||
GOLANGCI_LINT_BIN := golangci-lint
|
||||
GOLANGCI_LINT := $(abspath $(TOOLS_BIN_DIR)/$(GOLANGCI_LINT_BIN))
|
||||
|
||||
# Define Docker related variables. Releases should modify and double check these vars.
|
||||
REGISTRY ?= docker.io/kubespheredev
|
||||
PROD_REGISTRY ?= docker.io/kubesphere
|
||||
|
||||
# capkk
|
||||
CAPKK_IMAGE_NAME ?= capkk-controller
|
||||
CAPKK_CONTROLLER_IMG ?= $(REGISTRY)/$(CAPKK_IMAGE_NAME)
|
||||
|
||||
# bootstrap
|
||||
K3S_BOOTSTRAP_IMAGE_NAME ?= k3s-bootstrap-controller
|
||||
K3S_BOOTSTRAP_CONTROLLER_IMG ?= $(REGISTRY)/$(K3S_BOOTSTRAP_IMAGE_NAME)
|
||||
|
||||
# control plane
|
||||
K3S_CONTROL_PLANE_IMAGE_NAME ?= k3s-control-plane-controller
|
||||
K3S_CONTROL_PLANE_CONTROLLER_IMG ?= $(REGISTRY)/$(K3S_CONTROL_PLANE_IMAGE_NAME)
|
||||
|
||||
# It is set by Prow GIT_TAG, a git-based tag of the form vYYYYMMDD-hash, e.g., v20210120-v0.3.10-308-gc61521971
|
||||
|
||||
TAG ?= dev
|
||||
ARCH ?= $(shell go env GOARCH)
|
||||
ALL_ARCH = amd64 arm arm64 ppc64le s390x
|
||||
|
||||
# Allow overriding the imagePullPolicy
|
||||
PULL_POLICY ?= Always
|
||||
|
||||
# Hosts running SELinux need :z added to volume mounts
|
||||
SELINUX_ENABLED := $(shell cat /sys/fs/selinux/enforce 2> /dev/null || echo 0)
|
||||
|
||||
ifeq ($(SELINUX_ENABLED),1)
|
||||
DOCKER_VOL_OPTS?=:z
|
||||
endif
|
||||
|
||||
# Set build time variables including version details
|
||||
LDFLAGS := $(shell hack/version.sh)
|
||||
|
||||
# Set kk build tags
|
||||
BUILDTAGS = exclude_graphdriver_devicemapper exclude_graphdriver_btrfs containers_image_openpgp
|
||||
|
||||
.PHONY: all
|
||||
all: test managers
|
||||
|
||||
.PHONY: help
|
||||
help: ## Display this help.
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n\nTargets:\n"} /^[0-9A-Za-z_-]+:.*?##/ { printf " \033[36m%-45s\033[0m %s\n", $$1, $$2 } /^\$$\([0-9A-Za-z_-]+\):.*?##/ { gsub("_","-", $$1); printf " \033[36m%-45s\033[0m %s\n", tolower(substr($$1, 3, length($$1)-7)), $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
|
||||
## --------------------------------------
|
||||
## Generate / Manifests
|
||||
## --------------------------------------
|
||||
|
||||
##@ generate:
|
||||
|
||||
ALL_GENERATE_MODULES = capkk k3s-bootstrap k3s-control-plane
|
||||
|
||||
.PHONY: generate
|
||||
generate: ## Run all generate-manifests-*, generate-go-deepcopy-* targets
|
||||
$(MAKE) generate-modules generate-manifests generate-go-deepcopy
|
||||
|
||||
.PHONY: generate-manifests
|
||||
generate-manifests: ## Run all generate-manifest-* targets
|
||||
$(MAKE) $(addprefix generate-manifests-,$(ALL_GENERATE_MODULES))
|
||||
|
||||
.PHONY: generate-manifests-capkk
|
||||
generate-manifests-capkk: $(CONTROLLER_GEN) $(KUSTOMIZE) ## Generate manifests e.g. CRD, RBAC etc. for core
|
||||
$(MAKE) clean-generated-yaml SRC_DIRS="./config/crd/bases"
|
||||
$(CONTROLLER_GEN) \
|
||||
paths=./api/... \
|
||||
paths=./controllers/... \
|
||||
crd:crdVersions=v1 \
|
||||
rbac:roleName=manager-role \
|
||||
output:crd:dir=./config/crd/bases \
|
||||
output:webhook:dir=./config/webhook \
|
||||
webhook
|
||||
|
||||
.PHONY: generate-manifests-k3s-bootstrap
|
||||
generate-manifests-k3s-bootstrap: $(CONTROLLER_GEN) $(KUSTOMIZE) ## Generate manifests e.g. CRD, RBAC etc. for core
|
||||
$(MAKE) clean-generated-yaml SRC_DIRS="./bootstrap/k3s/config/crd/bases"
|
||||
$(CONTROLLER_GEN) \
|
||||
paths=./bootstrap/k3s/api/... \
|
||||
paths=./bootstrap/k3s/controllers/... \
|
||||
crd:crdVersions=v1 \
|
||||
rbac:roleName=manager-role \
|
||||
output:crd:dir=./bootstrap/k3s/config/crd/bases \
|
||||
output:rbac:dir=./bootstrap/k3s/config/rbac \
|
||||
output:webhook:dir=./bootstrap/k3s/config/webhook \
|
||||
webhook
|
||||
|
||||
.PHONY: generate-manifests-k3s-control-plane
|
||||
generate-manifests-k3s-control-plane: $(CONTROLLER_GEN) $(KUSTOMIZE) ## Generate manifests e.g. CRD, RBAC etc. for core
|
||||
$(MAKE) clean-generated-yaml SRC_DIRS="./controlplane/k3s/config/crd/bases"
|
||||
$(CONTROLLER_GEN) \
|
||||
paths=./controlplane/k3s/api/... \
|
||||
paths=./controlplane/k3s/controllers/... \
|
||||
crd:crdVersions=v1 \
|
||||
rbac:roleName=manager-role \
|
||||
output:crd:dir=./controlplane/k3s/config/crd/bases \
|
||||
output:rbac:dir=./controlplane/k3s/config/rbac \
|
||||
output:webhook:dir=./controlplane/k3s/config/webhook \
|
||||
webhook
|
||||
|
||||
.PHONY: generate-go-deepcopy
|
||||
generate-go-deepcopy: ## Run all generate-go-deepcopy-* targets
|
||||
$(MAKE) $(addprefix generate-go-deepcopy-,$(ALL_GENERATE_MODULES))
|
||||
|
||||
.PHONY: generate-go-deepcopy-capkk
|
||||
generate-go-deepcopy-capkk: $(CONTROLLER_GEN) ## Generate deepcopy go code for capkk
|
||||
$(MAKE) clean-generated-deepcopy SRC_DIRS="./api"
|
||||
$(CONTROLLER_GEN) \
|
||||
object:headerFile=./hack/boilerplate.go.txt \
|
||||
paths=./api/... \
|
||||
|
||||
.PHONY: generate-go-deepcopy-k3s-bootstrap
|
||||
generate-go-deepcopy-k3s-bootstrap: $(CONTROLLER_GEN) ## Generate deepcopy go code for k3s-bootstrap
|
||||
$(MAKE) clean-generated-deepcopy SRC_DIRS="./bootstrap/k3s/api"
|
||||
$(CONTROLLER_GEN) \
|
||||
object:headerFile=./hack/boilerplate.go.txt \
|
||||
paths=./bootstrap/k3s/api/... \
|
||||
|
||||
.PHONY: generate-go-deepcopy-k3s-control-plane
|
||||
generate-go-deepcopy-k3s-control-plane: $(CONTROLLER_GEN) ## Generate deepcopy go code for k3s-control-plane
|
||||
$(MAKE) clean-generated-deepcopy SRC_DIRS="./controlplane/k3s/api"
|
||||
$(CONTROLLER_GEN) \
|
||||
object:headerFile=./hack/boilerplate.go.txt \
|
||||
paths=./controlplane/k3s/api/... \
|
||||
|
||||
.PHONY: generate-modules
|
||||
generate-modules: ## Run go mod tidy to ensure modules are up to date
|
||||
go mod tidy
|
||||
|
||||
## --------------------------------------
|
||||
## Lint / Verify
|
||||
## --------------------------------------
|
||||
|
||||
##@ lint and verify:
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(GOLANGCI_LINT) ## Lint the codebase
|
||||
$(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_EXTRA_ARGS)
|
||||
cd $(TEST_DIR); $(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_EXTRA_ARGS)
|
||||
cd $(TOOLS_DIR); $(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_EXTRA_ARGS)
|
||||
./scripts/ci-lint-dockerfiles.sh $(HADOLINT_VER) $(HADOLINT_FAILURE_THRESHOLD)
|
||||
|
||||
.PHONY: lint-dockerfiles
|
||||
lint-dockerfiles:
|
||||
./scripts/ci-lint-dockerfiles.sh $(HADOLINT_VER) $(HADOLINT_FAILURE_THRESHOLD)
|
||||
|
||||
.PHONY: verify
|
||||
verify: $(addprefix verify-,$(ALL_VERIFY_CHECKS)) lint-dockerfiles ## Run all verify-* targets
|
||||
|
||||
.PHONY: verify-modules
|
||||
verify-modules: generate-modules ## Verify go modules are up to date
|
||||
@if !(git diff --quiet HEAD -- go.sum go.mod $(TOOLS_DIR)/go.mod $(TOOLS_DIR)/go.sum $(TEST_DIR)/go.mod $(TEST_DIR)/go.sum); then \
|
||||
git diff; \
|
||||
echo "go module files are out of date"; exit 1; \
|
||||
fi
|
||||
@if (find . -name 'go.mod' | xargs -n1 grep -q -i 'k8s.io/client-go.*+incompatible'); then \
|
||||
find . -name "go.mod" -exec grep -i 'k8s.io/client-go.*+incompatible' {} \; -print; \
|
||||
echo "go module contains an incompatible client-go version"; exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: verify-gen
|
||||
verify-gen: generate ## Verify go generated files are up to date
|
||||
@if !(git diff --quiet HEAD); then \
|
||||
git diff; \
|
||||
echo "generated files are out of date, run make generate"; exit 1; \
|
||||
fi
|
||||
|
||||
## --------------------------------------
|
||||
## Binaries
|
||||
## --------------------------------------
|
||||
|
||||
##@ build:
|
||||
|
||||
.PHONY: kk
|
||||
kk:
|
||||
CGO_ENABLED=0 go build -trimpath -tags "$(BUILDTAGS)" -ldflags "$(LDFLAGS)" -o $(BIN_DIR)/kk github.com/kubesphere/kubekey/v3/cmd/kk;
|
||||
|
||||
ALL_MANAGERS = capkk k3s-bootstrap k3s-control-plane
|
||||
|
||||
.PHONY: managers
|
||||
managers: $(addprefix manager-,$(ALL_MANAGERS)) ## Run all manager-* targets
|
||||
|
||||
.PHONY: manager-capkk
|
||||
manager-capkk: ## Build the capkk manager binary into the ./bin folder
|
||||
go build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN_DIR)/manager github.com/kubesphere/kubekey/v3
|
||||
|
||||
.PHONY: manager-k3s-bootstrap
|
||||
manager-k3s-bootstrap: ## Build the k3s bootstrap manager binary into the ./bin folder
|
||||
go build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN_DIR)/k3s-bootstrap-manager github.com/kubesphere/kubekey/v3/bootstrap/k3s
|
||||
|
||||
.PHONY: manager-k3s-control-plane
|
||||
manager-k3s-control-plane: ## Build the k3s control plane manager binary into the ./bin folder
|
||||
go build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN_DIR)/k3s-control-plane-manager github.com/kubesphere/kubekey/v3/controlplane/k3s
|
||||
|
||||
.PHONY: docker-pull-prerequisites
|
||||
docker-pull-prerequisites:
|
||||
docker pull docker.io/docker/dockerfile:1.4
|
||||
docker pull $(GO_CONTAINER_IMAGE)
|
||||
|
||||
.PHONY: docker-build-all
|
||||
docker-build-all: $(addprefix docker-build-,$(ALL_ARCH)) ## Build docker images for all architectures
|
||||
|
||||
docker-build-%:
|
||||
$(MAKE) ARCH=$* docker-build
|
||||
|
||||
ALL_DOCKER_BUILD = capkk k3s-bootstrap k3s-control-plane
|
||||
|
||||
.PHONY: docker-build
|
||||
docker-build: docker-pull-prerequisites ## Run docker-build-* targets for all providers
|
||||
$(MAKE) ARCH=$(ARCH) $(addprefix docker-build-,$(ALL_DOCKER_BUILD))
|
||||
|
||||
.PHONY: docker-build-capkk
|
||||
docker-build-capkk: ## Build the docker image for capkk
|
||||
DOCKER_BUILDKIT=1 docker build --build-arg builder_image=$(GO_CONTAINER_IMAGE) --build-arg goproxy=$(GOPROXY) --build-arg ARCH=$(ARCH) --build-arg ldflags="$(LDFLAGS)" . -t $(CAPKK_CONTROLLER_IMG)-$(ARCH):$(TAG)
|
||||
|
||||
.PHONY: docker-build-k3s-bootstrap
|
||||
docker-build-k3s-bootstrap: ## Build the docker image for k3s bootstrap controller manager
|
||||
DOCKER_BUILDKIT=1 docker build --build-arg builder_image=$(GO_CONTAINER_IMAGE) --build-arg goproxy=$(GOPROXY) --build-arg ARCH=$(ARCH) --build-arg package=./bootstrap/k3s --build-arg ldflags="$(LDFLAGS)" . -t $(K3S_BOOTSTRAP_CONTROLLER_IMG)-$(ARCH):$(TAG)
|
||||
|
||||
.PHONY: docker-build-k3s-control-plane
|
||||
docker-build-k3s-control-plane: ## Build the docker image for k3s control plane controller manager
|
||||
DOCKER_BUILDKIT=1 docker build --build-arg builder_image=$(GO_CONTAINER_IMAGE) --build-arg goproxy=$(GOPROXY) --build-arg ARCH=$(ARCH) --build-arg package=./controlplane/k3s --build-arg ldflags="$(LDFLAGS)" . -t $(K3S_CONTROL_PLANE_CONTROLLER_IMG)-$(ARCH):$(TAG)
|
||||
|
||||
.PHONY: docker-build-e2e
|
||||
docker-build-e2e: ## Build the docker image for capkk
|
||||
$(MAKE) docker-build REGISTRY=docker.io/kubespheredev PULL_POLICY=IfNotPresent TAG=e2e
|
||||
|
||||
## --------------------------------------
|
||||
## Deployment
|
||||
## --------------------------------------
|
||||
|
||||
##@ deployment
|
||||
|
||||
ifndef ignore-not-found
|
||||
ignore-not-found = false
|
||||
endif
|
||||
|
||||
.PHONY: install
|
||||
install: generate $(KUSTOMIZE) ## Install CRDs into the K8s cluster specified in ~/.kube/config.
|
||||
$(KUSTOMIZE) build config/crd | kubectl apply -f -
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall: generate $(KUSTOMIZE) ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
|
||||
$(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
|
||||
|
||||
.PHONY: deploy
|
||||
deploy: generate $(KUSTOMIZE) ## Deploy controller to the K8s cluster specified in ~/.kube/config.
|
||||
$(MAKE) set-manifest-image \
|
||||
MANIFEST_IMG=$(REGISTRY)/$(CAPKK_IMAGE_NAME)-$(ARCH) MANIFEST_TAG=$(TAG) \
|
||||
TARGET_RESOURCE="./config/default/manager_image_patch.yaml"
|
||||
cd config/manager
|
||||
$(KUSTOMIZE) build config/default | kubectl apply -f -
|
||||
|
||||
.PHONY: undeploy
|
||||
undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
|
||||
$(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
|
||||
|
||||
## --------------------------------------
|
||||
## Testing
|
||||
## --------------------------------------
|
||||
|
||||
##@ test:
|
||||
|
||||
ARTIFACTS ?= ${ROOT_DIR}/_artifacts
|
||||
|
||||
ifeq ($(shell go env GOOS),darwin) # Use the darwin/amd64 binary until an arm64 version is available
|
||||
KUBEBUILDER_ASSETS ?= $(shell $(SETUP_ENVTEST) use --use-env -p path --arch amd64 $(KUBEBUILDER_ENVTEST_KUBERNETES_VERSION))
|
||||
else
|
||||
KUBEBUILDER_ASSETS ?= $(shell $(SETUP_ENVTEST) use --use-env -p path $(KUBEBUILDER_ENVTEST_KUBERNETES_VERSION))
|
||||
endif
|
||||
|
||||
.PHONY: test
|
||||
test: $(SETUP_ENVTEST) ## Run unit and integration tests
|
||||
KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" go test ./... $(TEST_ARGS)
|
||||
|
||||
.PHONY: test-verbose
|
||||
test-verbose: ## Run unit and integration tests with verbose flag
|
||||
$(MAKE) test TEST_ARGS="$(TEST_ARGS) -v"
|
||||
|
||||
.PHONY: test-junit
|
||||
test-junit: $(SETUP_ENVTEST) $(GOTESTSUM) ## Run unit and integration tests and generate a junit report
|
||||
set +o errexit; (KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" go test -json ./... $(TEST_ARGS); echo $$? > $(ARTIFACTS)/junit.exitcode) | tee $(ARTIFACTS)/junit.stdout
|
||||
$(GOTESTSUM) --junitfile $(ARTIFACTS)/junit.xml --raw-command cat $(ARTIFACTS)/junit.stdout
|
||||
exit $$(cat $(ARTIFACTS)/junit.exitcode)
|
||||
|
||||
.PHONY: test-cover
|
||||
test-cover: ## Run unit and integration tests and generate a coverage report
|
||||
$(MAKE) test TEST_ARGS="$(TEST_ARGS) -coverprofile=out/coverage.out"
|
||||
go tool cover -func=out/coverage.out -o out/coverage.txt
|
||||
go tool cover -html=out/coverage.out -o out/coverage.html
|
||||
|
||||
.PHONY: test-e2e
|
||||
test-e2e: ## Run e2e tests
|
||||
$(MAKE) -C $(TEST_DIR)/e2e run
|
||||
|
||||
.PHONY: test-e2e-k3s
|
||||
test-e2e-k3s: ## Run e2e tests
|
||||
$(MAKE) -C $(TEST_DIR)/e2e run-k3s
|
||||
|
||||
## --------------------------------------
|
||||
## Release
|
||||
## --------------------------------------
|
||||
|
||||
##@ release:
|
||||
|
||||
## latest git tag for the commit, e.g., v0.3.10
|
||||
RELEASE_TAG ?= $(shell git describe --abbrev=0 2>/dev/null)
|
||||
ifneq (,$(findstring -,$(RELEASE_TAG)))
|
||||
PRE_RELEASE=true
|
||||
endif
|
||||
# the previous release tag, e.g., v0.3.9, excluding pre-release tags
|
||||
PREVIOUS_TAG ?= $(shell git tag -l | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+$$" | sort -V | grep -B1 $(RELEASE_TAG) | head -n 1 2>/dev/null)
|
||||
RELEASE_DIR := out
|
||||
|
||||
$(RELEASE_DIR):
|
||||
mkdir -p $(RELEASE_DIR)/
|
||||
|
||||
.PHONY: release
|
||||
release: clean-release ## Build and push container images using the latest git tag for the commit
|
||||
@if [ -z "${RELEASE_TAG}" ]; then echo "RELEASE_TAG is not set"; exit 1; fi
|
||||
@if ! [ -z "$$(git status --porcelain)" ]; then echo "Your local git repository contains uncommitted changes, use git clean before proceeding."; exit 1; fi
|
||||
git checkout "${RELEASE_TAG}"
|
||||
## Build binaries first.
|
||||
GIT_VERSION=$(RELEASE_TAG) $(MAKE) release-binaries
|
||||
# Set the manifest image to the production bucket.
|
||||
$(MAKE) manifest-modification REGISTRY=$(PROD_REGISTRY)
|
||||
## Build the manifests
|
||||
$(MAKE) release-manifests
|
||||
## Build the templates
|
||||
$(MAKE) release-templates
|
||||
## Clean the git artifacts modified in the release process
|
||||
$(MAKE) clean-release-git
|
||||
|
||||
release-binaries: ## Build the binaries to publish with a release
|
||||
RELEASE_BINARY=./cmd/kk GOOS=linux GOARCH=amd64 $(MAKE) release-binary
|
||||
RELEASE_BINARY=./cmd/kk GOOS=linux GOARCH=amd64 $(MAKE) release-archive
|
||||
RELEASE_BINARY=./cmd/kk GOOS=linux GOARCH=arm64 $(MAKE) release-binary
|
||||
RELEASE_BINARY=./cmd/kk GOOS=linux GOARCH=arm64 $(MAKE) release-archive
|
||||
RELEASE_BINARY=./cmd/kk GOOS=darwin GOARCH=amd64 $(MAKE) release-binary
|
||||
RELEASE_BINARY=./cmd/kk GOOS=darwin GOARCH=amd64 $(MAKE) release-archive
|
||||
RELEASE_BINARY=./cmd/kk GOOS=darwin GOARCH=arm64 $(MAKE) release-binary
|
||||
RELEASE_BINARY=./cmd/kk GOOS=darwin GOARCH=arm64 $(MAKE) release-archive
|
||||
|
||||
release-binary: $(RELEASE_DIR)
|
||||
docker run \
|
||||
--rm \
|
||||
-e CGO_ENABLED=0 \
|
||||
-e GOOS=$(GOOS) \
|
||||
-e GOARCH=$(GOARCH) \
|
||||
-e GOPROXY=$(GOPROXY) \
|
||||
-v "$$(pwd):/workspace$(DOCKER_VOL_OPTS)" \
|
||||
-w /workspace \
|
||||
golang:$(GO_VERSION) \
|
||||
go build -a -trimpath -tags "$(BUILDTAGS)" -ldflags "$(LDFLAGS) -extldflags '-static'" \
|
||||
-o $(RELEASE_DIR)/$(notdir $(RELEASE_BINARY)) $(RELEASE_BINARY)
|
||||
|
||||
release-archive: $(RELEASE_DIR)
|
||||
tar -czf $(RELEASE_DIR)/kubekey-$(RELEASE_TAG)-$(GOOS)-$(GOARCH).tar.gz -C $(RELEASE_DIR)/ $(notdir $(RELEASE_BINARY))
|
||||
rm -rf $(RELEASE_DIR)/$(notdir $(RELEASE_BINARY))
|
||||
|
||||
.PHONY: manifest-modification
|
||||
manifest-modification: # Set the manifest images to the staging/production bucket.
|
||||
$(MAKE) set-manifest-image \
|
||||
MANIFEST_IMG=$(REGISTRY)/$(CAPKK_IMAGE_NAME) MANIFEST_TAG=$(RELEASE_TAG) \
|
||||
TARGET_RESOURCE="./config/default/manager_image_patch.yaml"
|
||||
$(MAKE) set-manifest-image \
|
||||
MANIFEST_IMG=$(REGISTRY)/$(K3S_BOOTSTRAP_IMAGE_NAME) MANIFEST_TAG=$(RELEASE_TAG) \
|
||||
TARGET_RESOURCE="./bootstrap/k3s/config/default/manager_image_patch.yaml"
|
||||
$(MAKE) set-manifest-image \
|
||||
MANIFEST_IMG=$(REGISTRY)/$(K3S_CONTROL_PLANE_IMAGE_NAME) MANIFEST_TAG=$(RELEASE_TAG) \
|
||||
TARGET_RESOURCE="./controlplane/k3s/config/default/manager_image_patch.yaml"
|
||||
$(MAKE) set-manifest-pull-policy PULL_POLICY=IfNotPresent TARGET_RESOURCE="./config/default/manager_pull_policy.yaml"
|
||||
$(MAKE) set-manifest-pull-policy PULL_POLICY=IfNotPresent TARGET_RESOURCE="./bootstrap/k3s/config/default/manager_pull_policy.yaml"
|
||||
$(MAKE) set-manifest-pull-policy PULL_POLICY=IfNotPresent TARGET_RESOURCE="./controlplane/k3s/config/default/manager_pull_policy.yaml"
|
||||
|
||||
.PHONY: release-manifests
|
||||
release-manifests: $(RELEASE_DIR) $(KUSTOMIZE) ## Build the manifests to publish with a release
|
||||
# Build capkk-components.
|
||||
$(KUSTOMIZE) build config/default > $(RELEASE_DIR)/infrastructure-components.yaml
|
||||
# Build bootstrap-components.
|
||||
$(KUSTOMIZE) build bootstrap/k3s/config/default > $(RELEASE_DIR)/bootstrap-components.yaml
|
||||
# Build control-plane-components.
|
||||
$(KUSTOMIZE) build controlplane/k3s/config/default > $(RELEASE_DIR)/control-plane-components.yaml
|
||||
|
||||
# Add metadata to the release artifacts
|
||||
cp metadata.yaml $(RELEASE_DIR)/metadata.yaml
|
||||
|
||||
.PHONY: release-templates
|
||||
release-templates: $(RELEASE_DIR) ## Generate release templates
|
||||
cp templates/cluster-template*.yaml $(RELEASE_DIR)/
|
||||
|
||||
.PHONY: release-prod
|
||||
release-prod: ## Build and push container images to the prod
|
||||
REGISTRY=$(PROD_REGISTRY) TAG=$(RELEASE_TAG) $(MAKE) docker-build-all docker-push-all
|
||||
|
||||
## --------------------------------------
|
||||
## Docker
|
||||
## --------------------------------------
|
||||
|
||||
.PHONY: docker-push-all
|
||||
docker-push-all: $(addprefix docker-push-,$(ALL_ARCH)) ## Push the docker images to be included in the release for all architectures + related multiarch manifests
|
||||
$(MAKE) docker-push-manifest-capkk
|
||||
$(MAKE) docker-push-manifest-k3s-bootstrap
|
||||
$(MAKE) docker-push-manifest-k3s-control-plane
|
||||
|
||||
docker-push-%:
|
||||
$(MAKE) ARCH=$* docker-push
|
||||
|
||||
.PHONY: docker-push
|
||||
docker-push: ## Push the docker images
|
||||
docker push $(CAPKK_CONTROLLER_IMG)-$(ARCH):$(TAG)
|
||||
docker push $(K3S_BOOTSTRAP_CONTROLLER_IMG)-$(ARCH):$(TAG)
|
||||
docker push $(K3S_CONTROL_PLANE_CONTROLLER_IMG)-$(ARCH):$(TAG)
|
||||
|
||||
.PHONY: docker-push-manifest-capkk
|
||||
docker-push-manifest-capkk: ## Push the multiarch manifest for the capkk docker images
|
||||
## Minimum docker version 18.06.0 is required for creating and pushing manifest images.
|
||||
docker manifest create --amend $(CAPKK_CONTROLLER_IMG):$(TAG) $(shell echo $(ALL_ARCH) | sed -e "s~[^ ]*~$(CAPKK_CONTROLLER_IMG)\-&:$(TAG)~g")
|
||||
@for arch in $(ALL_ARCH); do docker manifest annotate --arch $${arch} ${CAPKK_CONTROLLER_IMG}:${TAG} ${CAPKK_CONTROLLER_IMG}-$${arch}:${TAG}; done
|
||||
docker manifest push --purge $(CAPKK_CONTROLLER_IMG):$(TAG)
|
||||
|
||||
.PHONY: docker-push-manifest-k3s-bootstrap
|
||||
docker-push-manifest-k3s-bootstrap: ## Push the multiarch manifest for the k3s bootstrap docker images
|
||||
## Minimum docker version 18.06.0 is required for creating and pushing manifest images.
|
||||
docker manifest create --amend $(K3S_BOOTSTRAP_CONTROLLER_IMG):$(TAG) $(shell echo $(ALL_ARCH) | sed -e "s~[^ ]*~$(K3S_BOOTSTRAP_CONTROLLER_IMG)\-&:$(TAG)~g")
|
||||
@for arch in $(ALL_ARCH); do docker manifest annotate --arch $${arch} ${K3S_BOOTSTRAP_CONTROLLER_IMG}:${TAG} ${K3S_BOOTSTRAP_CONTROLLER_IMG}-$${arch}:${TAG}; done
|
||||
docker manifest push --purge $(K3S_BOOTSTRAP_CONTROLLER_IMG):$(TAG)
|
||||
|
||||
.PHONY: docker-push-manifest-k3s-control-plane
|
||||
docker-push-manifest-k3s-control-plane: ## Push the multiarch manifest for the k3s control plane docker images
|
||||
## Minimum docker version 18.06.0 is required for creating and pushing manifest images.
|
||||
docker manifest create --amend $(K3S_CONTROL_PLANE_CONTROLLER_IMG):$(TAG) $(shell echo $(ALL_ARCH) | sed -e "s~[^ ]*~$(K3S_CONTROL_PLANE_CONTROLLER_IMG)\-&:$(TAG)~g")
|
||||
@for arch in $(ALL_ARCH); do docker manifest annotate --arch $${arch} ${K3S_CONTROL_PLANE_CONTROLLER_IMG}:${TAG} ${K3S_CONTROL_PLANE_CONTROLLER_IMG}-$${arch}:${TAG}; done
|
||||
docker manifest push --purge $(K3S_CONTROL_PLANE_CONTROLLER_IMG):$(TAG)
|
||||
|
||||
.PHONY: set-manifest-pull-policy
|
||||
set-manifest-pull-policy:
|
||||
$(info Updating kustomize pull policy file for manager resources)
|
||||
sed -i'' -e 's@imagePullPolicy: .*@imagePullPolicy: '"$(PULL_POLICY)"'@' $(TARGET_RESOURCE)
|
||||
|
||||
.PHONY: set-manifest-image
|
||||
set-manifest-image:
|
||||
$(info Updating kustomize image patch file for manager resource)
|
||||
sed -i'' -e 's@image: .*@image: '"${MANIFEST_IMG}:$(MANIFEST_TAG)"'@' $(TARGET_RESOURCE)
|
||||
|
||||
## --------------------------------------
|
||||
## Cleanup / Verification
|
||||
## --------------------------------------
|
||||
|
||||
##@ clean:
|
||||
|
||||
.PHONY: clean
|
||||
clean: ## Remove all generated files
|
||||
$(MAKE) clean-bin
|
||||
|
||||
.PHONY: clean-bin
|
||||
clean-bin: ## Remove all generated binaries
|
||||
rm -rf $(BIN_DIR)
|
||||
rm -rf $(TOOLS_BIN_DIR)
|
||||
|
||||
.PHONY: clean-release
|
||||
clean-release: ## Remove the release folder
|
||||
rm -rf $(RELEASE_DIR)
|
||||
|
||||
.PHONY: clean-release-git
|
||||
clean-release-git: ## Restores the git files usually modified during a release
|
||||
git restore ./*manager_image_patch.yaml ./*manager_pull_policy.yaml
|
||||
|
||||
.PHONY: clean-generated-yaml
|
||||
clean-generated-yaml: ## Remove files generated by conversion-gen from the mentioned dirs. Example SRC_DIRS="./api/v1beta1"
|
||||
(IFS=','; for i in $(SRC_DIRS); do find $$i -type f -name '*.yaml' -exec rm -f {} \;; done)
|
||||
|
||||
.PHONY: clean-generated-deepcopy
|
||||
clean-generated-deepcopy: ## Remove files generated by conversion-gen from the mentioned dirs. Example SRC_DIRS="./api/v1beta1"
|
||||
(IFS=','; for i in $(SRC_DIRS); do find $$i -type f -name 'zz_generated.deepcopy*' -exec rm -f {} \;; done)
|
||||
|
||||
## --------------------------------------
|
||||
## Hack / Tools
|
||||
## --------------------------------------
|
||||
|
||||
##@ hack/tools:
|
||||
|
||||
.PHONY: $(CONTROLLER_GEN_BIN)
|
||||
$(CONTROLLER_GEN_BIN): $(CONTROLLER_GEN) ## Build a local copy of controller-gen.
|
||||
|
||||
.PHONY: $(GOTESTSUM_BIN)
|
||||
$(GOTESTSUM_BIN): $(GOTESTSUM) ## Build a local copy of gotestsum.
|
||||
|
||||
.PHONY: $(KUSTOMIZE_BIN)
|
||||
$(KUSTOMIZE_BIN): $(KUSTOMIZE) ## Build a local copy of kustomize.
|
||||
|
||||
.PHONY: $(SETUP_ENVTEST_BIN)
|
||||
$(SETUP_ENVTEST_BIN): $(SETUP_ENVTEST) ## Build a local copy of setup-envtest.
|
||||
|
||||
.PHONY: $(GOLANGCI_LINT_BIN)
|
||||
$(GOLANGCI_LINT_BIN): $(GOLANGCI_LINT) ## Build a local copy of golangci-lint
|
||||
|
||||
$(CONTROLLER_GEN): # Build controller-gen from tools folder.
|
||||
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(CONTROLLER_GEN_PKG) $(CONTROLLER_GEN_BIN) $(CONTROLLER_GEN_VER)
|
||||
|
||||
$(GOTESTSUM): # Build gotestsum from tools folder.
|
||||
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GOTESTSUM_PKG) $(GOTESTSUM_BIN) $(GOTESTSUM_VER)
|
||||
|
||||
$(KUSTOMIZE): # Build kustomize from tools folder.
|
||||
CGO_ENABLED=0 GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(KUSTOMIZE_PKG) $(KUSTOMIZE_BIN) $(KUSTOMIZE_VER)
|
||||
|
||||
$(SETUP_ENVTEST): # Build setup-envtest from tools folder.
|
||||
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(SETUP_ENVTEST_PKG) $(SETUP_ENVTEST_BIN) $(SETUP_ENVTEST_VER)
|
||||
|
||||
$(GOLANGCI_LINT): .github/workflows/golangci-lint.yml # Download golangci-lint using hack script into tools folder.
|
||||
hack/ensure-golangci-lint.sh \
|
||||
-b $(TOOLS_BIN_DIR) \
|
||||
$(shell cat .github/workflows/golangci-lint.yml | grep [[:space:]]version | sed 's/.*version: //')
|
||||
|
||||
# build the artifact of repository iso
|
||||
ISO_ARCH ?= amd64
|
||||
ISO_OUTPUT_DIR ?= ./output
|
||||
ISO_BUILD_WORKDIR := hack/gen-repository-iso
|
||||
ISO_OS_NAMES := centos7 debian9 debian10 ubuntu1604 ubuntu1804 ubuntu2004 ubuntu2204
|
||||
ISO_BUILD_NAMES := $(addprefix build-iso-,$(ISO_OS_NAMES))
|
||||
build-iso-all: $(ISO_BUILD_NAMES)
|
||||
.PHONY: $(ISO_BUILD_NAMES)
|
||||
$(ISO_BUILD_NAMES):
|
||||
@export DOCKER_BUILDKIT=1
|
||||
docker build \
|
||||
--platform linux/$(ISO_ARCH) \
|
||||
--build-arg TARGETARCH=$(ISO_ARCH) \
|
||||
-o type=local,dest=$(ISO_OUTPUT_DIR) \
|
||||
-f $(ISO_BUILD_WORKDIR)/dockerfile.$(subst build-iso-,,$@) \
|
||||
$(ISO_BUILD_WORKDIR)
|
||||
|
||||
go-releaser-test:
|
||||
goreleaser release --rm-dist --skip-publish --snapshot
|
||||
20
OWNERS
20
OWNERS
|
|
@ -1,20 +0,0 @@
|
|||
approvers:
|
||||
- pixiake
|
||||
- 24sama
|
||||
- rayzhou2017
|
||||
- littleBlackHouse
|
||||
|
||||
reviewers:
|
||||
- pixiake
|
||||
- Forest-L
|
||||
- rayzhou2017
|
||||
- zryfish
|
||||
- shaowenchen
|
||||
- benjaminhuo
|
||||
- calvinyv
|
||||
- FeynmanZhou
|
||||
- huanggze
|
||||
- wansir
|
||||
- LinuxSuRen
|
||||
- 24sama
|
||||
- littleBlackHouse
|
||||
73
PROJECT
73
PROJECT
|
|
@ -1,73 +0,0 @@
|
|||
domain: cluster.x-k8s.io
|
||||
layout:
|
||||
- go.kubebuilder.io/v3
|
||||
plugins:
|
||||
manifests.sdk.operatorframework.io/v2: {}
|
||||
scorecard.sdk.operatorframework.io/v2: {}
|
||||
projectName: cluster-api-provider-kubekey
|
||||
repo: github.com/kubesphere/kubekey
|
||||
resources:
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: cluster.x-k8s.io
|
||||
group: infrastructure
|
||||
kind: KKCluster
|
||||
path: github.com/kubesphere/kubekey/api/v1beta1
|
||||
version: v1beta1
|
||||
webhooks:
|
||||
defaulting: true
|
||||
validation: true
|
||||
webhookVersion: v1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
domain: cluster.x-k8s.io
|
||||
group: infrastructure
|
||||
kind: KKClusterTemplate
|
||||
path: github.com/kubesphere/kubekey/api/v1beta1
|
||||
version: v1beta1
|
||||
webhooks:
|
||||
defaulting: true
|
||||
validation: true
|
||||
webhookVersion: v1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: cluster.x-k8s.io
|
||||
group: infrastructure
|
||||
kind: KKMachine
|
||||
path: github.com/kubesphere/kubekey/api/v1beta1
|
||||
version: v1beta1
|
||||
webhooks:
|
||||
defaulting: true
|
||||
validation: true
|
||||
webhookVersion: v1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
domain: cluster.x-k8s.io
|
||||
group: infrastructure
|
||||
kind: KKMachineTemplate
|
||||
path: github.com/kubesphere/kubekey/api/v1beta1
|
||||
version: v1beta1
|
||||
webhooks:
|
||||
defaulting: true
|
||||
validation: true
|
||||
webhookVersion: v1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: cluster.x-k8s.io
|
||||
group: infrastructure
|
||||
kind: KKInstance
|
||||
path: github.com/kubesphere/kubekey/api/v1beta1
|
||||
version: v1beta1
|
||||
webhooks:
|
||||
defaulting: true
|
||||
validation: true
|
||||
webhookVersion: v1
|
||||
version: "3"
|
||||
408
README.md
408
README.md
|
|
@ -1,408 +0,0 @@
|
|||
<div align=center><img src="docs/img/kubekey-logo.svg?raw=true"></div>
|
||||
|
||||
[](https://github.com/kubesphere/kubekey/actions?query=event%3Apush+branch%3Amaster+workflow%3ACI+)
|
||||
|
||||
> English | [中文](README_zh-CN.md)
|
||||
|
||||
### 👋 Welcome to KubeKey!
|
||||
|
||||
KubeKey is an open-source lightweight tool for deploying Kubernetes clusters. It provides a flexible, rapid, and convenient way to install Kubernetes/K3s only, both Kubernetes/K3s and KubeSphere, and related cloud-native add-ons. It is also an efficient tool to scale and upgrade your cluster.
|
||||
|
||||
In addition, KubeKey also supports customized Air-Gap package, which is convenient for users to quickly deploy clusters in offline environments.
|
||||
|
||||
> KubeKey has passed [CNCF kubernetes conformance verification](https://www.cncf.io/certification/software-conformance/).
|
||||
|
||||
Use KubeKey in the following three scenarios.
|
||||
|
||||
* Install Kubernetes/K3s only
|
||||
* Install Kubernetes/K3s and KubeSphere together in one command
|
||||
* Install Kubernetes/K3s first, then deploy KubeSphere on it using [ks-installer](https://github.com/kubesphere/ks-installer)
|
||||
|
||||
> **Important:** If you have existing Kubernetes clusters, please refer to [ks-installer (Install KubeSphere on existing Kubernetes cluster)](https://github.com/kubesphere/ks-installer).
|
||||
|
||||
## Supported Environment
|
||||
|
||||
### Linux Distributions
|
||||
|
||||
* **Ubuntu** *16.04, 18.04, 20.04, 22.04*
|
||||
* **Debian** *Bullseye, Buster, Stretch*
|
||||
* **CentOS/RHEL** *7*
|
||||
* **AlmaLinux** *9.0*
|
||||
* **SUSE Linux Enterprise Server** *15*
|
||||
|
||||
> Recommended Linux Kernel Version: `4.15 or later`
|
||||
> You can run the `uname -srm` command to check the Linux Kernel Version.
|
||||
|
||||
### <span id = "KubernetesVersions">Kubernetes Versions</span>
|
||||
|
||||
* **v1.19**:   *v1.19.15*
|
||||
* **v1.20**:   *v1.20.10*
|
||||
* **v1.21**:   *v1.21.14*
|
||||
* **v1.22**:   *v1.22.15*
|
||||
* **v1.23**:   *v1.23.10* (default)
|
||||
* **v1.24**:   *v1.24.7*
|
||||
* **v1.25**:   *v1.25.3*
|
||||
|
||||
> Looking for more supported versions: \
|
||||
> [Kubernetes Versions](./docs/kubernetes-versions.md) \
|
||||
> [K3s Versions](./docs/k3s-versions.md)
|
||||
|
||||
### Container Manager
|
||||
|
||||
* **Docker** / **containerd** / **CRI-O** / **iSula**
|
||||
|
||||
> `Kata Containers` can be set to automatically install and configure runtime class for it when the container manager is containerd or CRI-O.
|
||||
|
||||
### Network Plugins
|
||||
|
||||
* **Calico** / **Flannel** / **Cilium** / **Kube-OVN** / **Multus-CNI**
|
||||
|
||||
> Kubekey also supports users to set the network plugin to `none` if there is a requirement for custom network plugin.
|
||||
|
||||
## Requirements and Recommendations
|
||||
|
||||
* Minimum resource requirements (For Minimal Installation of KubeSphere only):
|
||||
* 2 vCPUs
|
||||
* 4 GB RAM
|
||||
* 20 GB Storage
|
||||
|
||||
> /var/lib/docker is mainly used to store the container data, and will gradually increase in size during use and operation. In the case of a production environment, it is recommended that /var/lib/docker mounts a drive separately.
|
||||
|
||||
* OS requirements:
|
||||
* `SSH` can access to all nodes.
|
||||
* Time synchronization for all nodes.
|
||||
* `sudo`/`curl`/`openssl` should be used in all nodes.
|
||||
* `docker` can be installed by yourself or by KubeKey.
|
||||
* `Red Hat` includes `SELinux` in its `Linux release`. It is recommended to close SELinux or [switch the mode of SELinux](./docs/turn-off-SELinux.md) to `Permissive`
|
||||
|
||||
> * It's recommended that Your OS is clean (without any other software installed), otherwise there may be conflicts.
|
||||
> * A container image mirror (accelerator) is recommended to be prepared if you have trouble downloading images from dockerhub.io. [Configure registry-mirrors for the Docker daemon](https://docs.docker.com/registry/recipes/mirror/#configure-the-docker-daemon).
|
||||
> * KubeKey will install [OpenEBS](https://openebs.io/) to provision LocalPV for development and testing environment by default, this is convenient for new users. For production, please use NFS / Ceph / GlusterFS or commercial products as persistent storage, and install the [relevant client](docs/storage-client.md) in all nodes.
|
||||
> * If you encounter `Permission denied` when copying, it is recommended to check [SELinux and turn off it](./docs/turn-off-SELinux.md) first
|
||||
|
||||
* Dependency requirements:
|
||||
|
||||
KubeKey can install Kubernetes and KubeSphere together. Some dependencies need to be installed before installing kubernetes after version 1.18. You can refer to the list below to check and install the relevant dependencies on your node in advance.
|
||||
|
||||
| | Kubernetes Version ≥ 1.18 |
|
||||
| ------------- | -------------------------- |
|
||||
| `socat` | Required |
|
||||
| `conntrack` | Required |
|
||||
| `ebtables` | Optional but recommended |
|
||||
| `ipset` | Optional but recommended |
|
||||
| `ipvsadm` | Optional but recommended |
|
||||
|
||||
* Networking and DNS requirements:
|
||||
* Make sure the DNS address in `/etc/resolv.conf` is available. Otherwise, it may cause some issues of DNS in cluster.
|
||||
* If your network configuration uses Firewall or Security Group,you must ensure infrastructure components can communicate with each other through specific ports. It's recommended that you turn off the firewall or follow the link configuriation: [NetworkAccess](docs/network-access.md).
|
||||
|
||||
## Usage
|
||||
|
||||
### Get the KubeKey Executable File
|
||||
|
||||
* The fastest way to get KubeKey is to use the script:
|
||||
|
||||
```
|
||||
curl -sfL https://get-kk.kubesphere.io | sh -
|
||||
```
|
||||
* Binary downloads of the KubeKey also can be found on the [Releases page](https://github.com/kubesphere/kubekey/releases).
|
||||
Unpack the binary and you are good to go!
|
||||
* Build Binary from Source Code
|
||||
|
||||
```shell
|
||||
git clone https://github.com/kubesphere/kubekey.git
|
||||
cd kubekey
|
||||
make kk
|
||||
```
|
||||
|
||||
### Create a Cluster
|
||||
|
||||
#### Quick Start
|
||||
|
||||
Quick Start is for `all-in-one` installation which is a good start to get familiar with Kubernetes and KubeSphere.
|
||||
|
||||
> Note: Since Kubernetes temporarily does not support uppercase NodeName, contains uppercase letters in the hostname will lead to subsequent installation error
|
||||
|
||||
##### Command
|
||||
|
||||
> If you have problem to access `https://storage.googleapis.com`, execute first `export KKZONE=cn`.
|
||||
|
||||
```shell
|
||||
./kk create cluster [--with-kubernetes version] [--with-kubesphere version]
|
||||
```
|
||||
|
||||
##### Examples
|
||||
|
||||
* Create a pure Kubernetes cluster with default version (Kubernetes v1.23.10).
|
||||
|
||||
```shell
|
||||
./kk create cluster
|
||||
```
|
||||
* Create a Kubernetes cluster with a specified version.
|
||||
|
||||
```shell
|
||||
./kk create cluster --with-kubernetes v1.24.1 --container-manager containerd
|
||||
```
|
||||
* Create a Kubernetes cluster with KubeSphere installed.
|
||||
|
||||
```shell
|
||||
./kk create cluster --with-kubesphere v3.2.1
|
||||
```
|
||||
|
||||
#### Advanced
|
||||
|
||||
You have more control to customize parameters or create a multi-node cluster using the advanced installation. Specifically, create a cluster by specifying a configuration file.
|
||||
|
||||
> If you have problem to access `https://storage.googleapis.com`, execute first `export KKZONE=cn`.
|
||||
|
||||
1. First, create an example configuration file
|
||||
|
||||
```shell
|
||||
./kk create config [--with-kubernetes version] [--with-kubesphere version] [(-f | --filename) path]
|
||||
```
|
||||
|
||||
**examples:**
|
||||
|
||||
* create an example config file with default configurations. You also can specify the file that could be a different filename, or in different folder.
|
||||
|
||||
```shell
|
||||
./kk create config [-f ~/myfolder/abc.yaml]
|
||||
```
|
||||
|
||||
* with KubeSphere
|
||||
|
||||
```shell
|
||||
./kk create config --with-kubesphere v3.2.1
|
||||
```
|
||||
2. Modify the file config-sample.yaml according to your environment
|
||||
|
||||
> Note: Since Kubernetes temporarily does not support uppercase NodeName, contains uppercase letters in workerNode`s name will lead to subsequent installation error
|
||||
>
|
||||
> A persistent storage is required in the cluster, when kubesphere will be installed. The local volume is used default. If you want to use other persistent storage, please refer to [addons](./docs/addons.md).
|
||||
|
||||
3. Create a cluster using the configuration file
|
||||
|
||||
```shell
|
||||
./kk create cluster -f config-sample.yaml
|
||||
```
|
||||
|
||||
### Enable Multi-cluster Management
|
||||
|
||||
By default, KubeKey will only install a **solo** cluster without Kubernetes federation. If you want to set up a multi-cluster control plane to centrally manage multiple clusters using KubeSphere, you need to set the `ClusterRole` in [config-example.yaml](docs/config-example.md). For multi-cluster user guide, please refer to [How to Enable the Multi-cluster Feature](https://github.com/kubesphere/community/tree/master/sig-multicluster/how-to-setup-multicluster-on-kubesphere).
|
||||
|
||||
### Enable Pluggable Components
|
||||
|
||||
KubeSphere has decoupled some core feature components since v2.1.0. These components are designed to be pluggable which means you can enable them either before or after installation. By default, KubeSphere will be started with a minimal installation if you do not enable them.
|
||||
|
||||
You can enable any of them according to your demands. It is highly recommended that you install these pluggable components to discover the full-stack features and capabilities provided by KubeSphere. Please ensure your machines have sufficient CPU and memory before enabling them. See [Enable Pluggable Components](https://github.com/kubesphere/ks-installer#enable-pluggable-components) for the details.
|
||||
|
||||
### Add Nodes
|
||||
|
||||
Add new node's information to the cluster config file, then apply the changes.
|
||||
|
||||
```shell
|
||||
./kk add nodes -f config-sample.yaml
|
||||
```
|
||||
|
||||
### Delete Nodes
|
||||
|
||||
You can delete the node by the following command,the nodeName that needs to be removed.
|
||||
|
||||
```shell
|
||||
./kk delete node <nodeName> -f config-sample.yaml
|
||||
```
|
||||
|
||||
### Delete Cluster
|
||||
|
||||
You can delete the cluster by the following command:
|
||||
|
||||
* If you started with the quick start (all-in-one):
|
||||
|
||||
```shell
|
||||
./kk delete cluster
|
||||
```
|
||||
|
||||
* If you started with the advanced (created with a configuration file):
|
||||
|
||||
```shell
|
||||
./kk delete cluster [-f config-sample.yaml]
|
||||
```
|
||||
|
||||
### Upgrade Cluster
|
||||
|
||||
#### Allinone
|
||||
|
||||
Upgrading cluster with a specified version.
|
||||
|
||||
```shell
|
||||
./kk upgrade [--with-kubernetes version] [--with-kubesphere version]
|
||||
```
|
||||
|
||||
* Support upgrading Kubernetes only.
|
||||
* Support upgrading KubeSphere only.
|
||||
* Support upgrading Kubernetes and KubeSphere.
|
||||
|
||||
#### Multi-nodes
|
||||
|
||||
Upgrading cluster with a specified configuration file.
|
||||
|
||||
```shell
|
||||
./kk upgrade [--with-kubernetes version] [--with-kubesphere version] [(-f | --filename) path]
|
||||
```
|
||||
|
||||
* If `--with-kubernetes` or `--with-kubesphere` is specified, the configuration file will be also updated.
|
||||
* Use `-f` to specify the configuration file which was generated for cluster creation.
|
||||
|
||||
> Note: Upgrading multi-nodes cluster need a specified configuration file. If the cluster was installed without kubekey or the configuration file for installation was not found, the configuration file needs to be created by yourself or following command.
|
||||
|
||||
Getting cluster info and generating kubekey's configuration file (optional).
|
||||
|
||||
```shell
|
||||
./kk create config [--from-cluster] [(-f | --filename) path] [--kubeconfig path]
|
||||
```
|
||||
|
||||
* `--from-cluster` means fetching cluster's information from an existing cluster.
|
||||
* `-f` refers to the path where the configuration file is generated.
|
||||
* `--kubeconfig` refers to the path where the kubeconfig.
|
||||
* After generating the configuration file, some parameters need to be filled in, such as the ssh information of the nodes.
|
||||
|
||||
## Documents
|
||||
|
||||
* [Features List](docs/features.md)
|
||||
* [Commands](docs/commands/kk.md)
|
||||
* [Configuration example](docs/config-example.md)
|
||||
* [Air-Gapped Installation](docs/manifest_and_artifact.md)
|
||||
* [Highly Available clusters](docs/ha-mode.md)
|
||||
* [Addons](docs/addons.md)
|
||||
* [Network access](docs/network-access.md)
|
||||
* [Storage clients](docs/storage-client.md)
|
||||
* [kubectl auto-completion](docs/kubectl-autocompletion.md)
|
||||
* [kubekey auto-completion](docs/kubekey-autocompletion.md)
|
||||
* [Roadmap](docs/roadmap.md)
|
||||
* [Check-Renew-Certificate](docs/check-renew-certificate.md)
|
||||
* [Developer-Guide](docs/developer-guide.md)
|
||||
|
||||
## Contributors ✨
|
||||
|
||||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pixiake"><img src="https://avatars0.githubusercontent.com/u/22290449?v=4?s=100" width="100px;" alt="pixiake"/><br /><sub><b>pixiake</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=pixiake" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=pixiake" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Forest-L"><img src="https://avatars2.githubusercontent.com/u/50984129?v=4?s=100" width="100px;" alt="Forest"/><br /><sub><b>Forest</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Forest-L" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=Forest-L" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://kubesphere.io/"><img src="https://avatars2.githubusercontent.com/u/28859385?v=4?s=100" width="100px;" alt="rayzhou2017"/><br /><sub><b>rayzhou2017</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=rayzhou2017" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=rayzhou2017" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.chenshaowen.com/"><img src="https://avatars2.githubusercontent.com/u/43693241?v=4?s=100" width="100px;" alt="shaowenchen"/><br /><sub><b>shaowenchen</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=shaowenchen" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=shaowenchen" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://surenpi.com/"><img src="https://avatars1.githubusercontent.com/u/1450685?v=4?s=100" width="100px;" alt="Zhao Xiaojie"/><br /><sub><b>Zhao Xiaojie</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=LinuxSuRen" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=LinuxSuRen" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zackzhangkai"><img src="https://avatars1.githubusercontent.com/u/20178386?v=4?s=100" width="100px;" alt="Zack Zhang"/><br /><sub><b>Zack Zhang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zackzhangkai" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://akhilerm.com/"><img src="https://avatars1.githubusercontent.com/u/7610845?v=4?s=100" width="100px;" alt="Akhil Mohan"/><br /><sub><b>Akhil Mohan</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=akhilerm" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeynmanZhou"><img src="https://avatars3.githubusercontent.com/u/40452856?v=4?s=100" width="100px;" alt="pengfei"/><br /><sub><b>pengfei</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=FeynmanZhou" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/min-zh"><img src="https://avatars1.githubusercontent.com/u/35321102?v=4?s=100" width="100px;" alt="min zhang"/><br /><sub><b>min zhang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=min-zh" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=min-zh" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zgldh"><img src="https://avatars1.githubusercontent.com/u/312404?v=4?s=100" width="100px;" alt="zgldh"/><br /><sub><b>zgldh</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zgldh" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xrjk"><img src="https://avatars0.githubusercontent.com/u/16330256?v=4?s=100" width="100px;" alt="xrjk"/><br /><sub><b>xrjk</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=xrjk" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/stoneshi-yunify"><img src="https://avatars2.githubusercontent.com/u/70880165?v=4?s=100" width="100px;" alt="yonghongshi"/><br /><sub><b>yonghongshi</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=stoneshi-yunify" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shenhonglei"><img src="https://avatars2.githubusercontent.com/u/20896372?v=4?s=100" width="100px;" alt="Honglei"/><br /><sub><b>Honglei</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=shenhonglei" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liucy1983"><img src="https://avatars2.githubusercontent.com/u/2360302?v=4?s=100" width="100px;" alt="liucy1983"/><br /><sub><b>liucy1983</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=liucy1983" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lilien1010"><img src="https://avatars1.githubusercontent.com/u/3814966?v=4?s=100" width="100px;" alt="Lien"/><br /><sub><b>Lien</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lilien1010" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/klj890"><img src="https://avatars3.githubusercontent.com/u/19380605?v=4?s=100" width="100px;" alt="Tony Wang"/><br /><sub><b>Tony Wang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=klj890" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hlwanghl"><img src="https://avatars3.githubusercontent.com/u/4861515?v=4?s=100" width="100px;" alt="Hongliang Wang"/><br /><sub><b>Hongliang Wang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=hlwanghl" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://fafucoder.github.io/"><img src="https://avatars0.githubusercontent.com/u/16442491?v=4?s=100" width="100px;" alt="dawn"/><br /><sub><b>dawn</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=fafucoder" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/duanjiong"><img src="https://avatars1.githubusercontent.com/u/3678855?v=4?s=100" width="100px;" alt="Duan Jiong"/><br /><sub><b>Duan Jiong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=duanjiong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/calvinyv"><img src="https://avatars3.githubusercontent.com/u/28883416?v=4?s=100" width="100px;" alt="calvinyv"/><br /><sub><b>calvinyv</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=calvinyv" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/benjaminhuo"><img src="https://avatars2.githubusercontent.com/u/18525465?v=4?s=100" width="100px;" alt="Benjamin Huo"/><br /><sub><b>Benjamin Huo</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=benjaminhuo" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Sherlock113"><img src="https://avatars2.githubusercontent.com/u/65327072?v=4?s=100" width="100px;" alt="Sherlock113"/><br /><sub><b>Sherlock113</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Sherlock113" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fuchange"><img src="https://avatars1.githubusercontent.com/u/31716848?v=4?s=100" width="100px;" alt="fu_changjie"/><br /><sub><b>fu_changjie</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Fuchange" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yuswift"><img src="https://avatars1.githubusercontent.com/u/37265389?v=4?s=100" width="100px;" alt="yuswift"/><br /><sub><b>yuswift</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yuswift" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ruiyaoOps"><img src="https://avatars.githubusercontent.com/u/35256376?v=4?s=100" width="100px;" alt="ruiyaoOps"/><br /><sub><b>ruiyaoOps</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=ruiyaoOps" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.luxingmin.com"><img src="https://avatars.githubusercontent.com/u/1918195?v=4?s=100" width="100px;" alt="LXM"/><br /><sub><b>LXM</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lxm" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sbhnet"><img src="https://avatars.githubusercontent.com/u/2368131?v=4?s=100" width="100px;" alt="sbhnet"/><br /><sub><b>sbhnet</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=sbhnet" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/misteruly"><img src="https://avatars.githubusercontent.com/u/31399968?v=4?s=100" width="100px;" alt="misteruly"/><br /><sub><b>misteruly</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=misteruly" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://johnniang.me"><img src="https://avatars.githubusercontent.com/u/16865714?v=4?s=100" width="100px;" alt="John Niang"/><br /><sub><b>John Niang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=JohnNiang" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://alimy.me"><img src="https://avatars.githubusercontent.com/u/10525842?v=4?s=100" width="100px;" alt="Michael Li"/><br /><sub><b>Michael Li</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=alimy" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/duguhaotian"><img src="https://avatars.githubusercontent.com/u/3174621?v=4?s=100" width="100px;" alt="独孤昊天"/><br /><sub><b>独孤昊天</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=duguhaotian" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lshmouse"><img src="https://avatars.githubusercontent.com/u/118687?v=4?s=100" width="100px;" alt="Liu Shaohui"/><br /><sub><b>Liu Shaohui</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lshmouse" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/24sama"><img src="https://avatars.githubusercontent.com/u/43993589?v=4?s=100" width="100px;" alt="Leo Li"/><br /><sub><b>Leo Li</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=24sama" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RolandMa1986"><img src="https://avatars.githubusercontent.com/u/1720333?v=4?s=100" width="100px;" alt="Roland"/><br /><sub><b>Roland</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=RolandMa1986" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://ops.m114.org"><img src="https://avatars.githubusercontent.com/u/2347587?v=4?s=100" width="100px;" alt="Vinson Zou"/><br /><sub><b>Vinson Zou</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=vinsonzou" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tagGeeY"><img src="https://avatars.githubusercontent.com/u/35259969?v=4?s=100" width="100px;" alt="tag_gee_y"/><br /><sub><b>tag_gee_y</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=tagGeeY" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liulangwa"><img src="https://avatars.githubusercontent.com/u/25916792?v=4?s=100" width="100px;" alt="codebee"/><br /><sub><b>codebee</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=liulangwa" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TheApeMachine"><img src="https://avatars.githubusercontent.com/u/9572060?v=4?s=100" width="100px;" alt="Daniel Owen van Dommelen"/><br /><sub><b>Daniel Owen van Dommelen</b></sub></a><br /><a href="#ideas-TheApeMachine" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Naidile-P-N"><img src="https://avatars.githubusercontent.com/u/29476402?v=4?s=100" width="100px;" alt="Naidile P N"/><br /><sub><b>Naidile P N</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Naidile-P-N" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/haiker2011"><img src="https://avatars.githubusercontent.com/u/8073429?v=4?s=100" width="100px;" alt="Haiker Sun"/><br /><sub><b>Haiker Sun</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=haiker2011" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yj-cloud"><img src="https://avatars.githubusercontent.com/u/19648473?v=4?s=100" width="100px;" alt="Jing Yu"/><br /><sub><b>Jing Yu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yj-cloud" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chaunceyjiang"><img src="https://avatars.githubusercontent.com/u/17962021?v=4?s=100" width="100px;" alt="Chauncey"/><br /><sub><b>Chauncey</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=chaunceyjiang" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tanguofu"><img src="https://avatars.githubusercontent.com/u/87045830?v=4?s=100" width="100px;" alt="Tan Guofu"/><br /><sub><b>Tan Guofu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=tanguofu" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lvillis"><img src="https://avatars.githubusercontent.com/u/56720445?v=4?s=100" width="100px;" alt="lvillis"/><br /><sub><b>lvillis</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lvillis" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/vincenthe11"><img src="https://avatars.githubusercontent.com/u/8400716?v=4?s=100" width="100px;" alt="Vincent He"/><br /><sub><b>Vincent He</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=vincenthe11" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://laminar.fun/"><img src="https://avatars.githubusercontent.com/u/2360535?v=4?s=100" width="100px;" alt="laminar"/><br /><sub><b>laminar</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=tpiperatgod" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cumirror"><img src="https://avatars.githubusercontent.com/u/2455429?v=4?s=100" width="100px;" alt="tongjin"/><br /><sub><b>tongjin</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=cumirror" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://k8s.li"><img src="https://avatars.githubusercontent.com/u/42566386?v=4?s=100" width="100px;" alt="Reimu"/><br /><sub><b>Reimu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=muzi502" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt="Ikko Ashimine"/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=eltociear" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://yeya24.github.io/"><img src="https://avatars.githubusercontent.com/u/25150124?v=4?s=100" width="100px;" alt="Ben Ye"/><br /><sub><b>Ben Ye</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yeya24" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yinheli"><img src="https://avatars.githubusercontent.com/u/235094?v=4?s=100" width="100px;" alt="yinheli"/><br /><sub><b>yinheli</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yinheli" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hellocn9"><img src="https://avatars.githubusercontent.com/u/102210430?v=4?s=100" width="100px;" alt="hellocn9"/><br /><sub><b>hellocn9</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=hellocn9" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/brandan-schmitz"><img src="https://avatars.githubusercontent.com/u/6267549?v=4?s=100" width="100px;" alt="Brandan Schmitz"/><br /><sub><b>Brandan Schmitz</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=brandan-schmitz" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yjqg6666"><img src="https://avatars.githubusercontent.com/u/1879641?v=4?s=100" width="100px;" alt="yjqg6666"/><br /><sub><b>yjqg6666</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yjqg6666" title="Documentation">📖</a> <a href="https://github.com/kubesphere/kubekey/commits?author=yjqg6666" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zaunist"><img src="https://avatars.githubusercontent.com/u/38528079?v=4?s=100" width="100px;" alt="失眠是真滴难受"/><br /><sub><b>失眠是真滴难受</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zaunist" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mangoGoForward"><img src="https://avatars.githubusercontent.com/u/35127166?v=4?s=100" width="100px;" alt="mango"/><br /><sub><b>mango</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/pulls?q=is%3Apr+reviewed-by%3AmangoGoForward" title="Reviewed Pull Requests">👀</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wenwutang1"><img src="https://avatars.githubusercontent.com/u/45817987?v=4?s=100" width="100px;" alt="wenwutang"/><br /><sub><b>wenwutang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=wenwutang1" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://kuops.com"><img src="https://avatars.githubusercontent.com/u/18283256?v=4?s=100" width="100px;" alt="Shiny Hou"/><br /><sub><b>Shiny Hou</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=kuops" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhouqiu0103"><img src="https://avatars.githubusercontent.com/u/108912268?v=4?s=100" width="100px;" alt="zhouqiu0103"/><br /><sub><b>zhouqiu0103</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zhouqiu0103" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/77yu77"><img src="https://avatars.githubusercontent.com/u/73932296?v=4?s=100" width="100px;" alt="77yu77"/><br /><sub><b>77yu77</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=77yu77" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hzhhong"><img src="https://avatars.githubusercontent.com/u/83079531?v=4?s=100" width="100px;" alt="hzhhong"/><br /><sub><b>hzhhong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=hzhhong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/arugal"><img src="https://avatars.githubusercontent.com/u/26432832?v=4?s=100" width="100px;" alt="zhang-wei"/><br /><sub><b>zhang-wei</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=arugal" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/xds2000"><img src="https://avatars.githubusercontent.com/u/37678?v=4?s=100" width="100px;" alt="Deshi Xiao"/><br /><sub><b>Deshi Xiao</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=xiaods" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=xiaods" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://besscroft.com"><img src="https://avatars.githubusercontent.com/u/33775809?v=4?s=100" width="100px;" alt="besscroft"/><br /><sub><b>besscroft</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=besscroft" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhangzhiqiangcs"><img src="https://avatars.githubusercontent.com/u/8319897?v=4?s=100" width="100px;" alt="张志强"/><br /><sub><b>张志强</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zhangzhiqiangcs" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwabish"><img src="https://avatars.githubusercontent.com/u/7044019?v=4?s=100" width="100px;" alt="lwabish"/><br /><sub><b>lwabish</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lwabish" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=lwabish" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyz87"><img src="https://avatars.githubusercontent.com/u/36068894?v=4?s=100" width="100px;" alt="qyz87"/><br /><sub><b>qyz87</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=qyz87" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fangzhengjin"><img src="https://avatars.githubusercontent.com/u/12680972?v=4?s=100" width="100px;" alt="ZhengJin Fang"/><br /><sub><b>ZhengJin Fang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=fangzhengjin" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://lhr.wiki"><img src="https://avatars.githubusercontent.com/u/6327311?v=4?s=100" width="100px;" alt="Eric_Lian"/><br /><sub><b>Eric_Lian</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=ExerciseBook" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nicognaW"><img src="https://avatars.githubusercontent.com/u/66731869?v=4?s=100" width="100px;" alt="nicognaw"/><br /><sub><b>nicognaw</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=nicognaW" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/deqingLv"><img src="https://avatars.githubusercontent.com/u/6064297?v=4?s=100" width="100px;" alt="吕德庆"/><br /><sub><b>吕德庆</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=deqingLv" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littleplus"><img src="https://avatars.githubusercontent.com/u/11694750?v=4?s=100" width="100px;" alt="littleplus"/><br /><sub><b>littleplus</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=littleplus" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/%D0%BA%D0%BE%D0%BD%D1%81%D1%82%D0%B0%D0%BD%D1%82%D0%B8%D0%BD-%D0%B0%D0%BA%D0%B0%D0%BA%D0%B8%D0%B5%D0%B2-13130b1b4/"><img src="https://avatars.githubusercontent.com/u/82488489?v=4?s=100" width="100px;" alt="Konstantin"/><br /><sub><b>Konstantin</b></sub></a><br /><a href="#ideas-Nello-Angelo" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://kiragoo.github.io"><img src="https://avatars.githubusercontent.com/u/7400711?v=4?s=100" width="100px;" alt="kiragoo"/><br /><sub><b>kiragoo</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=kiragoo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jojotong"><img src="https://avatars.githubusercontent.com/u/100849526?v=4?s=100" width="100px;" alt="jojotong"/><br /><sub><b>jojotong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=jojotong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littleBlackHouse"><img src="https://avatars.githubusercontent.com/u/54946465?v=4?s=100" width="100px;" alt="littleBlackHouse"/><br /><sub><b>littleBlackHouse</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=littleBlackHouse" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=littleBlackHouse" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/testwill"><img src="https://avatars.githubusercontent.com/u/8717479?v=4?s=100" width="100px;" alt="guangwu"/><br /><sub><b>guangwu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=testwill" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=testwill" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wongearl"><img src="https://avatars.githubusercontent.com/u/36498442?v=4?s=100" width="100px;" alt="wongearl"/><br /><sub><b>wongearl</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=wongearl" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wenwenxiong"><img src="https://avatars.githubusercontent.com/u/10548812?v=4?s=100" width="100px;" alt="wenwenxiong"/><br /><sub><b>wenwenxiong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=wenwenxiong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://baimeow.cn/"><img src="https://avatars.githubusercontent.com/u/38121125?v=4?s=100" width="100px;" alt="柏喵Sakura"/><br /><sub><b>柏喵Sakura</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=BaiMeow" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://dashen.tech"><img src="https://avatars.githubusercontent.com/u/15921519?v=4?s=100" width="100px;" alt="cui fliter"/><br /><sub><b>cui fliter</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=cuishuang" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liuxu623"><img src="https://avatars.githubusercontent.com/u/9653438?v=4?s=100" width="100px;" alt="刘旭"/><br /><sub><b>刘旭</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=liuxu623" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||
423
README_zh-CN.md
423
README_zh-CN.md
|
|
@ -1,423 +0,0 @@
|
|||
# KubeKey
|
||||
|
||||
[](https://github.com/kubesphere/kubekey/actions?query=event%3Apush+branch%3Amaster+workflow%3ACI+)
|
||||
|
||||
> [English](README.md) | 中文
|
||||
|
||||
KubeKey是一个开源的轻量级工具,用于部署Kubernetes集群。它提供了一种灵活、快速、方便的方式来安装Kubernetes/K3s、Kubernetes/K3s和KubeSphere,以及相关的云原生附加组件。它也是扩展和升级集群的有效工具。
|
||||
|
||||
此外,KubeKey还支持定制离线包(artifact),方便用户在离线环境下快速部署集群。
|
||||
|
||||
> KubeKey 通过了 [CNCF kubernetes 一致性认证](https://www.cncf.io/certification/software-conformance/)。
|
||||
|
||||
有三种情况可以使用 KubeKey。
|
||||
|
||||
* 仅安装 Kubernetes
|
||||
* 用一个命令中安装 Kubernetes 和 KubeSphere
|
||||
* 首先安装 Kubernetes,然后使用 [ks-installer](https://github.com/kubesphere/ks-installer) 在其上部署 KubeSphere
|
||||
|
||||
> 重要提示:Kubekey 将会帮您安装 Kubernetes,若已有 Kubernetes 集群请参考 [在 Kubernetes 之上安装 KubeSphere](https://github.com/kubesphere/ks-installer/)。
|
||||
|
||||
## 优势
|
||||
|
||||
* 基于 Ansible 的安装程序具有大量软件依赖性,例如 Python。KubeKey 是使用 Go 语言开发的,可以消除在各种环境中出现的问题,从而提高安装成功率。
|
||||
* KubeKey 使用 Kubeadm 在节点上尽可能多地并行安装 K8s 集群,以降低安装复杂性并提高效率。与较早的安装程序相比,它将大大节省安装时间。
|
||||
* KubeKey 支持将集群从 all-in-one 扩展到多节点集群甚至 HA 集群。
|
||||
* KubeKey 旨在将集群当作一个对象操作,即 CaaO。
|
||||
|
||||
## 支持的环境
|
||||
|
||||
### Linux 发行版
|
||||
|
||||
* **Ubuntu** *16.04, 18.04, 20.04, 22.04*
|
||||
* **Debian** *Bullseye, Buster, Stretch*
|
||||
* **CentOS/RHEL** *7*
|
||||
* **AlmaLinux** *9.0*
|
||||
* **SUSE Linux Enterprise Server** *15*
|
||||
|
||||
> 建议使用 Linux Kernel 版本: `4.15 or later`
|
||||
> 可以通过命令 `uname -srm` 查看 Linux Kernel 版本。
|
||||
|
||||
### <span id = "KubernetesVersions">Kubernetes 版本</span>
|
||||
|
||||
* **v1.19**:   *v1.19.15*
|
||||
* **v1.20**:   *v1.20.10*
|
||||
* **v1.21**:   *v1.21.14*
|
||||
* **v1.22**:   *v1.22.15*
|
||||
* **v1.23**:   *v1.23.10* (default)
|
||||
* **v1.24**:   *v1.24.7*
|
||||
* **v1.25**:   *v1.25.3*
|
||||
|
||||
> 查看更多支持的版本: \
|
||||
> [Kubernetes 版本](./docs/kubernetes-versions.md) \
|
||||
> [K3s 版本](./docs/k3s-versions.md)
|
||||
|
||||
## 要求和建议
|
||||
|
||||
* 最低资源要求(仅对于最小安装 KubeSphere):
|
||||
* 2 核虚拟 CPU
|
||||
* 4 GB 内存
|
||||
* 20 GB 储存空间
|
||||
|
||||
> /var/lib/docker 主要用于存储容器数据,在使用和操作过程中会逐渐增大。对于生产环境,建议 /var/lib/docker 单独挂盘。
|
||||
|
||||
* 操作系统要求:
|
||||
* `SSH` 可以访问所有节点。
|
||||
* 所有节点的时间同步。
|
||||
* `sudo`/`curl`/`openssl` 应在所有节点使用。
|
||||
* `docker` 可以自己安装,也可以通过 KubeKey 安装。
|
||||
* `Red Hat` 在其 `Linux` 发行版本中包括了 `SELinux`,建议[关闭SELinux](./docs/turn-off-SELinux_zh-CN.md)或者将[SELinux的模式切换](./docs/turn-off-SELinux_zh-CN.md)为Permissive[宽容]工作模式
|
||||
|
||||
> * 建议您的操作系统环境足够干净 (不安装任何其他软件),否则可能会发生冲突。
|
||||
> * 如果在从 dockerhub.io 下载镜像时遇到问题,建议准备一个容器镜像仓库 (加速器)。[为 Docker 守护程序配置镜像加速](https://docs.docker.com/registry/recipes/mirror/#configure-the-docker-daemon)。
|
||||
> * 默认情况下,KubeKey 将安装 [OpenEBS](https://openebs.io/) 来为开发和测试环境配置 LocalPV,这对新用户来说非常方便。对于生产,请使用 NFS/Ceph/GlusterFS 或商业化存储作为持久化存储,并在所有节点中安装[相关的客户端](./docs/storage-client.md) 。
|
||||
> * 如果遇到拷贝时报权限问题Permission denied,建议优先考虑查看[SELinux的原因](./docs/turn-off-SELinux_zh-CN.md)。
|
||||
|
||||
* 依赖要求:
|
||||
|
||||
KubeKey 可以同时安装 Kubernetes 和 KubeSphere。在版本1.18之后,安装kubernetes前需要安装一些依赖。你可以参考下面的列表,提前在你的节点上检查并安装相关依赖。
|
||||
|
||||
| | Kubernetes 版本 ≥ 1.18 |
|
||||
| ------------- | ----------------------- |
|
||||
| `socat` | 必须安装 |
|
||||
| `conntrack` | 必须安装 |
|
||||
| `ebtables` | 可选,但推荐安装 |
|
||||
| `ipset` | 可选,但推荐安装 |
|
||||
| `ipvsadm` | 可选,但推荐安装 |
|
||||
|
||||
* 网络和 DNS 要求:
|
||||
* 确保 `/etc/resolv.conf` 中的 DNS 地址可用。否则,可能会导致集群中出现某些 DNS 问题。
|
||||
* 如果您的网络配置使用防火墙或安全组,则必须确保基础结构组件可以通过特定端口相互通信。建议您关闭防火墙或遵循链接配置:[网络访问](docs/network-access.md)。
|
||||
|
||||
## 用法
|
||||
|
||||
### 获取安装程序可执行文件
|
||||
|
||||
* 使用脚本获取 KubeKey
|
||||
> 如果无法访问 https://github.com, 请先执行 export KKZONE=cn.
|
||||
```
|
||||
curl -sfL https://get-kk.kubesphere.io | sh -
|
||||
```
|
||||
|
||||
* 下载KubeKey可执行文件 [Releases page](https://github.com/kubesphere/kubekey/releases)
|
||||
|
||||
下载解压后可直接使用。
|
||||
|
||||
* 从源代码生成二进制文件
|
||||
|
||||
```shell
|
||||
git clone https://github.com/kubesphere/kubekey.git
|
||||
cd kubekey
|
||||
make kk
|
||||
```
|
||||
|
||||
### 创建集群
|
||||
|
||||
#### 快速开始
|
||||
|
||||
快速入门使用 `all-in-one` 安装,这是熟悉 KubeSphere 的良好开始。
|
||||
|
||||
> 注意: 由于 Kubernetes 暂不支持大写 NodeName, hostname 中包含大写字母将导致后续安装过程无法正常结束
|
||||
|
||||
##### 命令
|
||||
|
||||
> 如果无法访问 `https://storage.googleapis.com`, 请先执行 `export KKZONE=cn`.
|
||||
|
||||
```shell
|
||||
./kk create cluster [--with-kubernetes version] [--with-kubesphere version]
|
||||
```
|
||||
|
||||
##### 例子
|
||||
|
||||
* 使用默认版本创建一个纯 Kubernetes 集群
|
||||
|
||||
```shell
|
||||
./kk create cluster
|
||||
```
|
||||
* 创建指定一个([支持的版本](#KubernetesVersions))的 Kubernetes 集群
|
||||
|
||||
```shell
|
||||
./kk create cluster --with-kubernetes v1.19.8
|
||||
```
|
||||
* 创建一个部署了 KubeSphere 的 Kubernetes 集群 (例如 `--with-kubesphere v3.1.0`)
|
||||
|
||||
```shell
|
||||
./kk create cluster --with-kubesphere [version]
|
||||
```
|
||||
* 创建一个指定的 container runtime 的 Kubernetes 集群(docker, crio, containerd and isula)
|
||||
|
||||
```shell
|
||||
./kk create cluster --container-manager containerd
|
||||
```
|
||||
|
||||
#### 高级用法
|
||||
|
||||
您可以使用高级安装来控制自定义参数或创建多节点集群。具体来说,通过指定配置文件来创建集群。
|
||||
|
||||
> 如果无法访问 `https://storage.googleapis.com`, 请先执行 `export KKZONE=cn`.
|
||||
|
||||
1. 首先,创建一个示例配置文件
|
||||
|
||||
```shell
|
||||
./kk create config [--with-kubernetes version] [--with-kubesphere version] [(-f | --filename) path]
|
||||
```
|
||||
|
||||
**例子:**
|
||||
|
||||
* 使用默认配置创建一个示例配置文件。您也可以指定文件名称或文件所在的文件夹。
|
||||
|
||||
```shell
|
||||
./kk create config [-f ~/myfolder/config-sample.yaml]
|
||||
```
|
||||
* 同时安装 KubeSphere
|
||||
|
||||
```shell
|
||||
./kk create config --with-kubesphere
|
||||
```
|
||||
2. 根据您的环境修改配置文件 config-sample.yaml
|
||||
|
||||
> 注意: 由于 Kubernetes 暂不支持大写 NodeName, worker 节点名中包含大写字母将导致后续安装过程无法正常结束
|
||||
>
|
||||
> 当指定安装KubeSphere时,要求集群中有可用的持久化存储。默认使用localVolume,如果需要使用其他持久化存储,请参阅 [addons](./docs/addons.md) 配置。
|
||||
|
||||
3. 使用配置文件创建集群。
|
||||
|
||||
```shell
|
||||
./kk create cluster -f ~/myfolder/config-sample.yaml
|
||||
```
|
||||
|
||||
### 启用多集群管理
|
||||
|
||||
默认情况下,Kubekey 将仅安装一个 Solo 模式的单集群,即未开启 Kubernetes 多集群联邦。如果您希望将 KubeSphere 作为一个支持多集群集中管理的中央面板,您需要在 [config-example.yaml](docs/config-example.md) 中设置 `ClusterRole`。关于多集群的使用文档,请参考 [如何启用多集群](https://github.com/kubesphere/community/blob/master/sig-multicluster/how-to-setup-multicluster-on-kubesphere/README_zh.md)。
|
||||
|
||||
### 开启可插拔功能组件
|
||||
|
||||
KubeSphere 从 2.1.0 版本开始对 Installer 的各功能组件进行了解耦,快速安装将默认仅开启最小化安装(Minimal Installation),Installer 支持在安装前或安装后自定义可插拔的功能组件的安装。使最小化安装更快速轻量且资源占用更少,也方便不同用户按需选择安装不同的功能组件。
|
||||
|
||||
KubeSphere 有多个可插拔功能组件,功能组件的介绍可参考 [配置示例](docs/config-example.md)。您可以根据需求,选择开启安装 KubeSphere 的可插拔功能组件。我们非常建议您开启这些功能组件来体验 KubeSphere 完整的功能以及端到端的解决方案。请在安装前确保您的机器有足够的 CPU 与内存资源。开启可插拔功能组件可参考 [开启可选功能组件](https://github.com/kubesphere/ks-installer/blob/master/README_zh.md#%E5%AE%89%E8%A3%85%E5%8A%9F%E8%83%BD%E7%BB%84%E4%BB%B6)。
|
||||
|
||||
### 添加节点
|
||||
|
||||
将新节点的信息添加到集群配置文件,然后应用更改。
|
||||
|
||||
```shell
|
||||
./kk add nodes -f config-sample.yaml
|
||||
```
|
||||
|
||||
### 删除节点
|
||||
|
||||
通过以下命令删除节点,nodename指需要删除的节点名。
|
||||
|
||||
```shell
|
||||
./kk delete node <nodeName> -f config-sample.yaml
|
||||
```
|
||||
|
||||
### 删除集群
|
||||
|
||||
您可以通过以下命令删除集群:
|
||||
|
||||
* 如果您以快速入门(all-in-one)开始:
|
||||
|
||||
```shell
|
||||
./kk delete cluster
|
||||
```
|
||||
|
||||
* 如果从高级安装开始(使用配置文件创建的集群):
|
||||
|
||||
```shell
|
||||
./kk delete cluster [-f config-sample.yaml]
|
||||
```
|
||||
|
||||
### 集群升级
|
||||
|
||||
#### 单节点集群
|
||||
|
||||
升级集群到指定版本。
|
||||
|
||||
```shell
|
||||
./kk upgrade [--with-kubernetes version] [--with-kubesphere version]
|
||||
```
|
||||
|
||||
* `--with-kubernetes` 指定kubernetes目标版本。
|
||||
* `--with-kubesphere` 指定kubesphere目标版本。
|
||||
|
||||
#### 多节点集群
|
||||
|
||||
通过指定配置文件对集群进行升级。
|
||||
|
||||
```shell
|
||||
./kk upgrade [--with-kubernetes version] [--with-kubesphere version] [(-f | --filename) path]
|
||||
```
|
||||
|
||||
* `--with-kubernetes` 指定kubernetes目标版本。
|
||||
* `--with-kubesphere` 指定kubesphere目标版本。
|
||||
* `-f` 指定集群安装时创建的配置文件。
|
||||
|
||||
> 注意: 升级多节点集群需要指定配置文件. 如果集群非kubekey创建,或者创建集群时生成的配置文件丢失,需要重新生成配置文件,或使用以下方法生成。
|
||||
|
||||
Getting cluster info and generating kubekey's configuration file (optional).
|
||||
|
||||
```shell
|
||||
./kk create config [--from-cluster] [(-f | --filename) path] [--kubeconfig path]
|
||||
```
|
||||
|
||||
* `--from-cluster` 根据已存在集群信息生成配置文件.
|
||||
* `-f` 指定生成配置文件路径.
|
||||
* `--kubeconfig` 指定集群kubeconfig文件.
|
||||
* 由于无法全面获取集群配置,生成配置文件后,请根据集群实际信息补全配置文件。
|
||||
|
||||
### 启用 kubectl 自动补全
|
||||
|
||||
KubeKey 不会启用 kubectl 自动补全功能。请参阅下面的指南并将其打开:
|
||||
|
||||
**先决条件**:确保已安装 `bash-autocompletion` 并可以正常工作。
|
||||
|
||||
```shell
|
||||
# 安装 bash-completion
|
||||
apt-get install bash-completion
|
||||
|
||||
# 将 completion 脚本添加到你的 ~/.bashrc 文件
|
||||
echo 'source <(kubectl completion bash)' >>~/.bashrc
|
||||
|
||||
# 将 completion 脚本添加到 /etc/bash_completion.d 目录
|
||||
kubectl completion bash >/etc/bash_completion.d/kubectl
|
||||
```
|
||||
|
||||
更详细的参考可以在[这里](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion)找到。
|
||||
|
||||
## 相关文档
|
||||
|
||||
* [特性列表](docs/features.md)
|
||||
* [命令手册](docs/commands/kk.md)
|
||||
* [配置示例](docs/config-example.md)
|
||||
* [离线安装](docs/zh/manifest_and_artifact.md)
|
||||
* [高可用集群](docs/ha-mode.md)
|
||||
* [自定义插件安装](docs/addons.md)
|
||||
* [网络访问](docs/network-access.md)
|
||||
* [存储客户端](docs/storage-client.md)
|
||||
* [路线图](docs/roadmap.md)
|
||||
* [查看或更新证书](docs/check-renew-certificate.md)
|
||||
* [开发指南](docs/developer-guide.md)
|
||||
|
||||
## 贡献者 ✨
|
||||
|
||||
欢迎任何形式的贡献! 感谢这些优秀的贡献者,是他们让我们的项目快速成长。
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pixiake"><img src="https://avatars0.githubusercontent.com/u/22290449?v=4?s=100" width="100px;" alt="pixiake"/><br /><sub><b>pixiake</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=pixiake" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=pixiake" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Forest-L"><img src="https://avatars2.githubusercontent.com/u/50984129?v=4?s=100" width="100px;" alt="Forest"/><br /><sub><b>Forest</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Forest-L" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=Forest-L" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://kubesphere.io/"><img src="https://avatars2.githubusercontent.com/u/28859385?v=4?s=100" width="100px;" alt="rayzhou2017"/><br /><sub><b>rayzhou2017</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=rayzhou2017" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=rayzhou2017" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.chenshaowen.com/"><img src="https://avatars2.githubusercontent.com/u/43693241?v=4?s=100" width="100px;" alt="shaowenchen"/><br /><sub><b>shaowenchen</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=shaowenchen" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=shaowenchen" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://surenpi.com/"><img src="https://avatars1.githubusercontent.com/u/1450685?v=4?s=100" width="100px;" alt="Zhao Xiaojie"/><br /><sub><b>Zhao Xiaojie</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=LinuxSuRen" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=LinuxSuRen" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zackzhangkai"><img src="https://avatars1.githubusercontent.com/u/20178386?v=4?s=100" width="100px;" alt="Zack Zhang"/><br /><sub><b>Zack Zhang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zackzhangkai" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://akhilerm.com/"><img src="https://avatars1.githubusercontent.com/u/7610845?v=4?s=100" width="100px;" alt="Akhil Mohan"/><br /><sub><b>Akhil Mohan</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=akhilerm" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeynmanZhou"><img src="https://avatars3.githubusercontent.com/u/40452856?v=4?s=100" width="100px;" alt="pengfei"/><br /><sub><b>pengfei</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=FeynmanZhou" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/min-zh"><img src="https://avatars1.githubusercontent.com/u/35321102?v=4?s=100" width="100px;" alt="min zhang"/><br /><sub><b>min zhang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=min-zh" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=min-zh" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zgldh"><img src="https://avatars1.githubusercontent.com/u/312404?v=4?s=100" width="100px;" alt="zgldh"/><br /><sub><b>zgldh</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zgldh" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xrjk"><img src="https://avatars0.githubusercontent.com/u/16330256?v=4?s=100" width="100px;" alt="xrjk"/><br /><sub><b>xrjk</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=xrjk" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/stoneshi-yunify"><img src="https://avatars2.githubusercontent.com/u/70880165?v=4?s=100" width="100px;" alt="yonghongshi"/><br /><sub><b>yonghongshi</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=stoneshi-yunify" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shenhonglei"><img src="https://avatars2.githubusercontent.com/u/20896372?v=4?s=100" width="100px;" alt="Honglei"/><br /><sub><b>Honglei</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=shenhonglei" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liucy1983"><img src="https://avatars2.githubusercontent.com/u/2360302?v=4?s=100" width="100px;" alt="liucy1983"/><br /><sub><b>liucy1983</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=liucy1983" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lilien1010"><img src="https://avatars1.githubusercontent.com/u/3814966?v=4?s=100" width="100px;" alt="Lien"/><br /><sub><b>Lien</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lilien1010" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/klj890"><img src="https://avatars3.githubusercontent.com/u/19380605?v=4?s=100" width="100px;" alt="Tony Wang"/><br /><sub><b>Tony Wang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=klj890" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hlwanghl"><img src="https://avatars3.githubusercontent.com/u/4861515?v=4?s=100" width="100px;" alt="Hongliang Wang"/><br /><sub><b>Hongliang Wang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=hlwanghl" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://fafucoder.github.io/"><img src="https://avatars0.githubusercontent.com/u/16442491?v=4?s=100" width="100px;" alt="dawn"/><br /><sub><b>dawn</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=fafucoder" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/duanjiong"><img src="https://avatars1.githubusercontent.com/u/3678855?v=4?s=100" width="100px;" alt="Duan Jiong"/><br /><sub><b>Duan Jiong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=duanjiong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/calvinyv"><img src="https://avatars3.githubusercontent.com/u/28883416?v=4?s=100" width="100px;" alt="calvinyv"/><br /><sub><b>calvinyv</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=calvinyv" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/benjaminhuo"><img src="https://avatars2.githubusercontent.com/u/18525465?v=4?s=100" width="100px;" alt="Benjamin Huo"/><br /><sub><b>Benjamin Huo</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=benjaminhuo" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Sherlock113"><img src="https://avatars2.githubusercontent.com/u/65327072?v=4?s=100" width="100px;" alt="Sherlock113"/><br /><sub><b>Sherlock113</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Sherlock113" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fuchange"><img src="https://avatars1.githubusercontent.com/u/31716848?v=4?s=100" width="100px;" alt="fu_changjie"/><br /><sub><b>fu_changjie</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Fuchange" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yuswift"><img src="https://avatars1.githubusercontent.com/u/37265389?v=4?s=100" width="100px;" alt="yuswift"/><br /><sub><b>yuswift</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yuswift" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ruiyaoOps"><img src="https://avatars.githubusercontent.com/u/35256376?v=4?s=100" width="100px;" alt="ruiyaoOps"/><br /><sub><b>ruiyaoOps</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=ruiyaoOps" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.luxingmin.com"><img src="https://avatars.githubusercontent.com/u/1918195?v=4?s=100" width="100px;" alt="LXM"/><br /><sub><b>LXM</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lxm" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sbhnet"><img src="https://avatars.githubusercontent.com/u/2368131?v=4?s=100" width="100px;" alt="sbhnet"/><br /><sub><b>sbhnet</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=sbhnet" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/misteruly"><img src="https://avatars.githubusercontent.com/u/31399968?v=4?s=100" width="100px;" alt="misteruly"/><br /><sub><b>misteruly</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=misteruly" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://johnniang.me"><img src="https://avatars.githubusercontent.com/u/16865714?v=4?s=100" width="100px;" alt="John Niang"/><br /><sub><b>John Niang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=JohnNiang" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://alimy.me"><img src="https://avatars.githubusercontent.com/u/10525842?v=4?s=100" width="100px;" alt="Michael Li"/><br /><sub><b>Michael Li</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=alimy" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/duguhaotian"><img src="https://avatars.githubusercontent.com/u/3174621?v=4?s=100" width="100px;" alt="独孤昊天"/><br /><sub><b>独孤昊天</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=duguhaotian" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lshmouse"><img src="https://avatars.githubusercontent.com/u/118687?v=4?s=100" width="100px;" alt="Liu Shaohui"/><br /><sub><b>Liu Shaohui</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lshmouse" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/24sama"><img src="https://avatars.githubusercontent.com/u/43993589?v=4?s=100" width="100px;" alt="Leo Li"/><br /><sub><b>Leo Li</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=24sama" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RolandMa1986"><img src="https://avatars.githubusercontent.com/u/1720333?v=4?s=100" width="100px;" alt="Roland"/><br /><sub><b>Roland</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=RolandMa1986" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://ops.m114.org"><img src="https://avatars.githubusercontent.com/u/2347587?v=4?s=100" width="100px;" alt="Vinson Zou"/><br /><sub><b>Vinson Zou</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=vinsonzou" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tagGeeY"><img src="https://avatars.githubusercontent.com/u/35259969?v=4?s=100" width="100px;" alt="tag_gee_y"/><br /><sub><b>tag_gee_y</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=tagGeeY" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liulangwa"><img src="https://avatars.githubusercontent.com/u/25916792?v=4?s=100" width="100px;" alt="codebee"/><br /><sub><b>codebee</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=liulangwa" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TheApeMachine"><img src="https://avatars.githubusercontent.com/u/9572060?v=4?s=100" width="100px;" alt="Daniel Owen van Dommelen"/><br /><sub><b>Daniel Owen van Dommelen</b></sub></a><br /><a href="#ideas-TheApeMachine" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Naidile-P-N"><img src="https://avatars.githubusercontent.com/u/29476402?v=4?s=100" width="100px;" alt="Naidile P N"/><br /><sub><b>Naidile P N</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=Naidile-P-N" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/haiker2011"><img src="https://avatars.githubusercontent.com/u/8073429?v=4?s=100" width="100px;" alt="Haiker Sun"/><br /><sub><b>Haiker Sun</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=haiker2011" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yj-cloud"><img src="https://avatars.githubusercontent.com/u/19648473?v=4?s=100" width="100px;" alt="Jing Yu"/><br /><sub><b>Jing Yu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yj-cloud" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chaunceyjiang"><img src="https://avatars.githubusercontent.com/u/17962021?v=4?s=100" width="100px;" alt="Chauncey"/><br /><sub><b>Chauncey</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=chaunceyjiang" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tanguofu"><img src="https://avatars.githubusercontent.com/u/87045830?v=4?s=100" width="100px;" alt="Tan Guofu"/><br /><sub><b>Tan Guofu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=tanguofu" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lvillis"><img src="https://avatars.githubusercontent.com/u/56720445?v=4?s=100" width="100px;" alt="lvillis"/><br /><sub><b>lvillis</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lvillis" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/vincenthe11"><img src="https://avatars.githubusercontent.com/u/8400716?v=4?s=100" width="100px;" alt="Vincent He"/><br /><sub><b>Vincent He</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=vincenthe11" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://laminar.fun/"><img src="https://avatars.githubusercontent.com/u/2360535?v=4?s=100" width="100px;" alt="laminar"/><br /><sub><b>laminar</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=tpiperatgod" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cumirror"><img src="https://avatars.githubusercontent.com/u/2455429?v=4?s=100" width="100px;" alt="tongjin"/><br /><sub><b>tongjin</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=cumirror" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://k8s.li"><img src="https://avatars.githubusercontent.com/u/42566386?v=4?s=100" width="100px;" alt="Reimu"/><br /><sub><b>Reimu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=muzi502" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt="Ikko Ashimine"/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=eltociear" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://yeya24.github.io/"><img src="https://avatars.githubusercontent.com/u/25150124?v=4?s=100" width="100px;" alt="Ben Ye"/><br /><sub><b>Ben Ye</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yeya24" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yinheli"><img src="https://avatars.githubusercontent.com/u/235094?v=4?s=100" width="100px;" alt="yinheli"/><br /><sub><b>yinheli</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yinheli" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hellocn9"><img src="https://avatars.githubusercontent.com/u/102210430?v=4?s=100" width="100px;" alt="hellocn9"/><br /><sub><b>hellocn9</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=hellocn9" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/brandan-schmitz"><img src="https://avatars.githubusercontent.com/u/6267549?v=4?s=100" width="100px;" alt="Brandan Schmitz"/><br /><sub><b>Brandan Schmitz</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=brandan-schmitz" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yjqg6666"><img src="https://avatars.githubusercontent.com/u/1879641?v=4?s=100" width="100px;" alt="yjqg6666"/><br /><sub><b>yjqg6666</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=yjqg6666" title="Documentation">📖</a> <a href="https://github.com/kubesphere/kubekey/commits?author=yjqg6666" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zaunist"><img src="https://avatars.githubusercontent.com/u/38528079?v=4?s=100" width="100px;" alt="失眠是真滴难受"/><br /><sub><b>失眠是真滴难受</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zaunist" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mangoGoForward"><img src="https://avatars.githubusercontent.com/u/35127166?v=4?s=100" width="100px;" alt="mango"/><br /><sub><b>mango</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/pulls?q=is%3Apr+reviewed-by%3AmangoGoForward" title="Reviewed Pull Requests">👀</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wenwutang1"><img src="https://avatars.githubusercontent.com/u/45817987?v=4?s=100" width="100px;" alt="wenwutang"/><br /><sub><b>wenwutang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=wenwutang1" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://kuops.com"><img src="https://avatars.githubusercontent.com/u/18283256?v=4?s=100" width="100px;" alt="Shiny Hou"/><br /><sub><b>Shiny Hou</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=kuops" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhouqiu0103"><img src="https://avatars.githubusercontent.com/u/108912268?v=4?s=100" width="100px;" alt="zhouqiu0103"/><br /><sub><b>zhouqiu0103</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zhouqiu0103" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/77yu77"><img src="https://avatars.githubusercontent.com/u/73932296?v=4?s=100" width="100px;" alt="77yu77"/><br /><sub><b>77yu77</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=77yu77" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hzhhong"><img src="https://avatars.githubusercontent.com/u/83079531?v=4?s=100" width="100px;" alt="hzhhong"/><br /><sub><b>hzhhong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=hzhhong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/arugal"><img src="https://avatars.githubusercontent.com/u/26432832?v=4?s=100" width="100px;" alt="zhang-wei"/><br /><sub><b>zhang-wei</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=arugal" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/xds2000"><img src="https://avatars.githubusercontent.com/u/37678?v=4?s=100" width="100px;" alt="Deshi Xiao"/><br /><sub><b>Deshi Xiao</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=xiaods" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=xiaods" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://besscroft.com"><img src="https://avatars.githubusercontent.com/u/33775809?v=4?s=100" width="100px;" alt="besscroft"/><br /><sub><b>besscroft</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=besscroft" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhangzhiqiangcs"><img src="https://avatars.githubusercontent.com/u/8319897?v=4?s=100" width="100px;" alt="张志强"/><br /><sub><b>张志强</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=zhangzhiqiangcs" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwabish"><img src="https://avatars.githubusercontent.com/u/7044019?v=4?s=100" width="100px;" alt="lwabish"/><br /><sub><b>lwabish</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=lwabish" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=lwabish" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyz87"><img src="https://avatars.githubusercontent.com/u/36068894?v=4?s=100" width="100px;" alt="qyz87"/><br /><sub><b>qyz87</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=qyz87" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fangzhengjin"><img src="https://avatars.githubusercontent.com/u/12680972?v=4?s=100" width="100px;" alt="ZhengJin Fang"/><br /><sub><b>ZhengJin Fang</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=fangzhengjin" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://lhr.wiki"><img src="https://avatars.githubusercontent.com/u/6327311?v=4?s=100" width="100px;" alt="Eric_Lian"/><br /><sub><b>Eric_Lian</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=ExerciseBook" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nicognaW"><img src="https://avatars.githubusercontent.com/u/66731869?v=4?s=100" width="100px;" alt="nicognaw"/><br /><sub><b>nicognaw</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=nicognaW" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/deqingLv"><img src="https://avatars.githubusercontent.com/u/6064297?v=4?s=100" width="100px;" alt="吕德庆"/><br /><sub><b>吕德庆</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=deqingLv" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littleplus"><img src="https://avatars.githubusercontent.com/u/11694750?v=4?s=100" width="100px;" alt="littleplus"/><br /><sub><b>littleplus</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=littleplus" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/%D0%BA%D0%BE%D0%BD%D1%81%D1%82%D0%B0%D0%BD%D1%82%D0%B8%D0%BD-%D0%B0%D0%BA%D0%B0%D0%BA%D0%B8%D0%B5%D0%B2-13130b1b4/"><img src="https://avatars.githubusercontent.com/u/82488489?v=4?s=100" width="100px;" alt="Konstantin"/><br /><sub><b>Konstantin</b></sub></a><br /><a href="#ideas-Nello-Angelo" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://kiragoo.github.io"><img src="https://avatars.githubusercontent.com/u/7400711?v=4?s=100" width="100px;" alt="kiragoo"/><br /><sub><b>kiragoo</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=kiragoo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jojotong"><img src="https://avatars.githubusercontent.com/u/100849526?v=4?s=100" width="100px;" alt="jojotong"/><br /><sub><b>jojotong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=jojotong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littleBlackHouse"><img src="https://avatars.githubusercontent.com/u/54946465?v=4?s=100" width="100px;" alt="littleBlackHouse"/><br /><sub><b>littleBlackHouse</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=littleBlackHouse" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=littleBlackHouse" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/testwill"><img src="https://avatars.githubusercontent.com/u/8717479?v=4?s=100" width="100px;" alt="guangwu"/><br /><sub><b>guangwu</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=testwill" title="Code">💻</a> <a href="https://github.com/kubesphere/kubekey/commits?author=testwill" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wongearl"><img src="https://avatars.githubusercontent.com/u/36498442?v=4?s=100" width="100px;" alt="wongearl"/><br /><sub><b>wongearl</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=wongearl" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wenwenxiong"><img src="https://avatars.githubusercontent.com/u/10548812?v=4?s=100" width="100px;" alt="wenwenxiong"/><br /><sub><b>wenwenxiong</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=wenwenxiong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://baimeow.cn/"><img src="https://avatars.githubusercontent.com/u/38121125?v=4?s=100" width="100px;" alt="柏喵Sakura"/><br /><sub><b>柏喵Sakura</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=BaiMeow" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://dashen.tech"><img src="https://avatars.githubusercontent.com/u/15921519?v=4?s=100" width="100px;" alt="cui fliter"/><br /><sub><b>cui fliter</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=cuishuang" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liuxu623"><img src="https://avatars.githubusercontent.com/u/9653438?v=4?s=100" width="100px;" alt="刘旭"/><br /><sub><b>刘旭</b></sub></a><br /><a href="https://github.com/kubesphere/kubekey/commits?author=liuxu623" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Auth contains the SSH authentication configuration for machines.
|
||||
type Auth struct {
|
||||
// User is the username for SSH authentication.
|
||||
// +optional
|
||||
User string `yaml:"user,omitempty" json:"user,omitempty"`
|
||||
|
||||
// Password is the password for SSH authentication.
|
||||
// +optional
|
||||
Password string `yaml:"password,omitempty" json:"password,omitempty"`
|
||||
|
||||
// Port is the port for SSH authentication.
|
||||
// +optional
|
||||
Port *int `yaml:"port,omitempty" json:"port,omitempty"`
|
||||
|
||||
// PrivateKey is the value of the private key for SSH authentication.
|
||||
// +optional
|
||||
PrivateKey string `yaml:"privateKey,omitempty" json:"privateKey,omitempty"`
|
||||
|
||||
// PrivateKeyFile is the path to the private key for SSH authentication.
|
||||
// +optional
|
||||
PrivateKeyPath string `yaml:"privateKeyPath,omitempty" json:"privateKeyPath,omitempty"`
|
||||
|
||||
// Secret is the secret of the PrivateKey or Password for SSH authentication.It should in the same namespace as capkk.
|
||||
// When Password is empty, replace it with data.password.
|
||||
// When PrivateKey is empty, replace it with data.privateKey
|
||||
// +optional
|
||||
Secret string `yaml:"secret,omitempty" json:"secret,omitempty"`
|
||||
|
||||
// Timeout is the timeout for establish an SSH connection.
|
||||
// +optional
|
||||
Timeout *time.Duration `yaml:"timeout,omitempty" json:"timeout,omitempty"`
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
const (
|
||||
// KKClusterLabelName is the label set on KKMachines and KKInstances linked to a kkCluster.
|
||||
KKClusterLabelName = "kkcluster.infrastructure.cluster.x-k8s.io/cluster-name"
|
||||
)
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
// Component is optional configuration for modifying the FTP server.
|
||||
type Component struct {
|
||||
// ZONE is the zone of the KKCluster where can get the binaries.
|
||||
// If you have problem to access https://storage.googleapis.com, you can set "zone: cn".
|
||||
// +optional
|
||||
ZONE string `json:"zone,omitempty"`
|
||||
|
||||
// Host is the host to download the binaries.
|
||||
// +optional
|
||||
Host string `json:"host,omitempty"`
|
||||
|
||||
// Overrides is a list of components download information that need to be overridden.
|
||||
// +optional
|
||||
Overrides []Override `json:"overrides,omitempty"`
|
||||
}
|
||||
|
||||
// Override is a component download information that need to be overridden.
|
||||
type Override struct {
|
||||
// ID is the component id name. e.g. kubeadm, kubelet, containerd, etc.
|
||||
ID string `json:"id,omitempty"`
|
||||
|
||||
// Arch is the component arch. e.g. amd64, arm64, etc.
|
||||
Arch string `json:"arch,omitempty"`
|
||||
|
||||
// Version is the component version. e.g. v1.21.1, v1.22.0, etc.
|
||||
Version string `json:"version,omitempty"`
|
||||
|
||||
// URL is the download url of the binaries.
|
||||
URL string `json:"url,omitempty"`
|
||||
|
||||
// Path defines the URL path, which is the string of information that comes after the top level domain name.
|
||||
Path string `json:"path,omitempty"`
|
||||
|
||||
// Checksum is the SHA256 checksum of the binary.
|
||||
// +optional
|
||||
Checksum Checksum `json:"checksum,omitempty"`
|
||||
}
|
||||
|
||||
// Checksum is the SHA256 checksum of the binary.
|
||||
type Checksum struct {
|
||||
// Value is the checksum string value.
|
||||
// +optional
|
||||
Value string `json:"value,omitempty"`
|
||||
|
||||
// Path defines the URL path, which is the path of the checksum file.
|
||||
// +optional
|
||||
Path string `json:"path,omitempty"`
|
||||
}
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
)
|
||||
|
||||
// KKCluster condition
|
||||
const (
|
||||
// PrincipalPreparedCondition reports whether the principal is prepared.
|
||||
PrincipalPreparedCondition clusterv1.ConditionType = "PrincipalPrepared"
|
||||
)
|
||||
|
||||
const (
|
||||
// HostReadyCondition reports whether the host is ready to be used.
|
||||
HostReadyCondition clusterv1.ConditionType = "HostReadyCondition"
|
||||
)
|
||||
|
||||
const (
|
||||
// ExternalLoadBalancerReadyCondition reports on whether a control plane load balancer was successfully reconciled.
|
||||
ExternalLoadBalancerReadyCondition clusterv1.ConditionType = "ExternalLoadBalancerReady"
|
||||
|
||||
// WaitForDNSNameResolveReason used while waiting for DNS name to resolve.
|
||||
WaitForDNSNameResolveReason = "WaitForDNSNameResolve"
|
||||
)
|
||||
|
||||
const (
|
||||
// CallKKInstanceInPlaceUpgradeCondition reports whether set up the InPlaceUpgradeVersionAnnotation annotation on all the KKInstance conditions.
|
||||
CallKKInstanceInPlaceUpgradeCondition clusterv1.ConditionType = "CallKKInstanceInPlaceUpgrade"
|
||||
|
||||
// KKInstanceObjectNotUpdatedReason used when the KKInstance is not updated.
|
||||
KKInstanceObjectNotUpdatedReason = "KKInstanceObjectNotUpdated"
|
||||
|
||||
// AllKKInstancesUpgradeCompletedCondition reports whether all the KKInstances are upgraded.
|
||||
AllKKInstancesUpgradeCompletedCondition clusterv1.ConditionType = "AllKKInstancesUpgradeCompleted"
|
||||
|
||||
// WaitingForKKInstancesUpgradeReason used when the KKCluster is waiting for all KKInstance to be upgrading completed.
|
||||
WaitingForKKInstancesUpgradeReason = "WaitingForKKInstancesUpgrade"
|
||||
)
|
||||
|
||||
// KKMachine condition
|
||||
const (
|
||||
// InstanceReadyCondition reports on current status of the SSH instance. Ready indicates the instance is in a Running state.
|
||||
InstanceReadyCondition clusterv1.ConditionType = "InstanceReady"
|
||||
|
||||
// InstanceNotFoundReason used when the instance couldn't be retrieved.
|
||||
InstanceNotFoundReason = "InstanceNotFound"
|
||||
// InstanceCleanedReason instance is in a Cleared state.
|
||||
InstanceCleanedReason = "InstanceCleaned"
|
||||
// InstanceNotReadyReason used when the instance is in a pending state.
|
||||
InstanceNotReadyReason = "InstanceNotReady"
|
||||
// InstanceInPlaceUpgradingReason used when the instance is in a InstanceStateInPlaceUpgrading state.
|
||||
InstanceInPlaceUpgradingReason = "InstanceInPlaceUpgrading"
|
||||
// InstanceBootstrapStartedReason set when the provisioning of an instance started.
|
||||
InstanceBootstrapStartedReason = "InstanceBootstrapStarted"
|
||||
// InstanceBootstrapFailedReason used for failures during instance provisioning.
|
||||
InstanceBootstrapFailedReason = "InstanceBootstrapFailed"
|
||||
// WaitingForClusterInfrastructureReason used when machine is waiting for cluster infrastructure to be ready before proceeding.
|
||||
WaitingForClusterInfrastructureReason = "WaitingForClusterInfrastructure"
|
||||
// WaitingForBootstrapDataReason used when machine is waiting for bootstrap data to be ready before proceeding.
|
||||
WaitingForBootstrapDataReason = "WaitingForBootstrapData"
|
||||
)
|
||||
|
||||
// KKInstance condition
|
||||
const (
|
||||
// KKInstanceBootstrappedCondition reports on current status of the instance. Ready indicates the instance is in a init Bootstrapped state.
|
||||
KKInstanceBootstrappedCondition clusterv1.ConditionType = "InstanceBootstrapped"
|
||||
// KKInstanceInitOSFailedReason used when the instance couldn't initialize os environment.
|
||||
KKInstanceInitOSFailedReason = "InitOSFailed"
|
||||
)
|
||||
|
||||
const (
|
||||
// KKInstanceRepositoryReadyCondition reports on whether successful to use repository to install packages.
|
||||
KKInstanceRepositoryReadyCondition clusterv1.ConditionType = "InstanceRepositoryReady"
|
||||
// KKInstanceRepositoryFailedReason used when the instance couldn't use repository to install packages.
|
||||
KKInstanceRepositoryFailedReason = "InstanceRepositoryFailed"
|
||||
)
|
||||
|
||||
const (
|
||||
// KKInstanceBinariesReadyCondition reports on whether successful to download binaries.
|
||||
KKInstanceBinariesReadyCondition clusterv1.ConditionType = "InstanceBinariesReady"
|
||||
// KKInstanceGetBinaryFailedReason used when the instance couldn't download binaries (or check existed binaries).
|
||||
KKInstanceGetBinaryFailedReason = "GetBinaryFailed"
|
||||
)
|
||||
|
||||
const (
|
||||
// KKInstanceCRIReadyCondition reports on whether successful to download and install CRI.
|
||||
KKInstanceCRIReadyCondition clusterv1.ConditionType = "InstanceCRIReady"
|
||||
// KKInstanceInstallCRIFailedReason used when the instance couldn't download and install CRI.
|
||||
KKInstanceInstallCRIFailedReason = "InstallCRIFailed"
|
||||
)
|
||||
|
||||
const (
|
||||
// KKInstanceProvisionedCondition reports on whether the instance is provisioned by cloud-init.
|
||||
KKInstanceProvisionedCondition clusterv1.ConditionType = "InstanceProvisioned"
|
||||
// KKInstanceRunCloudConfigFailedReason used when the instance couldn't be provisioned.
|
||||
KKInstanceRunCloudConfigFailedReason = "RunCloudConfigFailed"
|
||||
)
|
||||
|
||||
const (
|
||||
// KKInstanceDeletingBootstrapCondition reports on whether the instance is deleting bootstrap data.
|
||||
KKInstanceDeletingBootstrapCondition clusterv1.ConditionType = "InstanceDeletingBootstrapped"
|
||||
// KKInstanceClearEnvironmentFailedReason used when the instance couldn't be deleting bootstrap data.
|
||||
KKInstanceClearEnvironmentFailedReason = "ClearEnvironmentFailed"
|
||||
|
||||
// CleaningReason (Severity=Info) documents a machine node being cleaned.
|
||||
CleaningReason = "Cleaning"
|
||||
)
|
||||
|
||||
const (
|
||||
// KKInstanceInPlaceUpgradedCondition reports on whether the instance is in place upgrade succeed.
|
||||
KKInstanceInPlaceUpgradedCondition clusterv1.ConditionType = "KKInstanceInPlaceUpgraded"
|
||||
)
|
||||
|
||||
const (
|
||||
// KKInstanceInPlaceUpgradeBinariesCondition reports on whether the instance is in place upgrade download binaries succeed.
|
||||
KKInstanceInPlaceUpgradeBinariesCondition clusterv1.ConditionType = "KKInstanceInPlaceUpgradeBinaries"
|
||||
// KKInstanceInPlaceGetBinaryFailedReason used when the instance couldn't download binaries (or check existed binaries).
|
||||
KKInstanceInPlaceGetBinaryFailedReason = "KKInstanceInPlaceUpgradeGetBinaryFailed"
|
||||
)
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
// Default values.
|
||||
const (
|
||||
DockerType = "docker"
|
||||
DefaultDockerVersion = "20.10.8"
|
||||
DefaultCRIDockerdVersion = "0.2.6"
|
||||
DefaultDockerCRISocket = "unix:///run/cri-dockerd.sock"
|
||||
|
||||
ContainerdType = "containerd"
|
||||
DefaultContainerdVersion = "1.6.4"
|
||||
DefaultContainerdCRISocket = "unix:///var/run/containerd/containerd.sock"
|
||||
|
||||
DefaultCrictlVersion = "v1.24.0"
|
||||
)
|
||||
|
||||
// ContainerManager defines the desired state of ContainerManager
|
||||
type ContainerManager struct {
|
||||
// CRISocket is used to connect an existing CRIClient.
|
||||
// +optional
|
||||
CRISocket string `json:"criSocket,omitempty"`
|
||||
|
||||
// Type defines the type of ContainerManager.
|
||||
// "docker", "containerd"
|
||||
Type string `json:"type,omitempty"`
|
||||
|
||||
// Version defines the version of ContainerManager.
|
||||
Version string `json:"version,omitempty"`
|
||||
|
||||
// CRICTLVersion defines the version of CRICTL.
|
||||
CRICTLVersion string `json:"crictlVersion,omitempty"`
|
||||
|
||||
// CRIDockerdVersion defines the version of cri-dockerd, available only when Type is docker.
|
||||
// https://github.com/Mirantis/cri-dockerd
|
||||
// +optional
|
||||
CRIDockerdVersion string `json:"criDockerdVersion,omitempty"`
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1 contains the v1beta1 API implementation.
|
||||
package v1beta1
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1 contains API Schema definitions for the infrastructure v1beta1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=infrastructure.cluster.x-k8s.io
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "infrastructure.cluster.x-k8s.io", Version: "v1beta1"}
|
||||
|
||||
// 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
|
||||
)
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
"sigs.k8s.io/cluster-api/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// ClusterFinalizer allows ReconcileKKCluster to clean up KK resources associated with KKCluster before
|
||||
// removing it from the apiserver.
|
||||
ClusterFinalizer = "kkcluster.infrastructure.cluster.x-k8s.io"
|
||||
|
||||
// KUBERNETES the Kubernetes distributions
|
||||
KUBERNETES = "kubernetes"
|
||||
// K3S the K3S distributions
|
||||
K3S = "k3s"
|
||||
|
||||
// InPlaceUpgradeVersionAnnotation is the annotation that stores the version of the cluster used for in-place upgrade.
|
||||
InPlaceUpgradeVersionAnnotation = "kkcluster.infrastructure.cluster.x-k8s.io/in-place-upgrade-version"
|
||||
)
|
||||
|
||||
// KKClusterSpec defines the desired state of KKCluster
|
||||
type KKClusterSpec struct {
|
||||
// Distribution represents the Kubernetes distribution type of the cluster.
|
||||
Distribution string `json:"distribution,omitempty"`
|
||||
|
||||
// Nodes represents the information about the nodes available to the cluster
|
||||
Nodes Nodes `json:"nodes"`
|
||||
|
||||
// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
|
||||
// +optional
|
||||
ControlPlaneEndpoint clusterv1.APIEndpoint `json:"controlPlaneEndpoint"`
|
||||
|
||||
// ControlPlaneLoadBalancer is optional configuration for customizing control plane behavior.
|
||||
ControlPlaneLoadBalancer *KKLoadBalancerSpec `json:"controlPlaneLoadBalancer,omitempty"`
|
||||
|
||||
// Component is optional configuration for modifying the FTP server
|
||||
// that gets the necessary components for the cluster.
|
||||
// +optional
|
||||
Component *Component `json:"component,omitempty"`
|
||||
|
||||
// Registry represents the cluster image registry used to pull the images.
|
||||
// +optional
|
||||
Registry Registry `json:"registry,omitempty"`
|
||||
}
|
||||
|
||||
// Nodes represents the information about the nodes available to the cluster
|
||||
type Nodes struct {
|
||||
// Auth is the SSH authentication information of all instance. It is a global auth configuration.
|
||||
// +optional
|
||||
Auth Auth `json:"auth"`
|
||||
|
||||
// Instances defines all instance contained in kkcluster.
|
||||
Instances []InstanceInfo `json:"instances"`
|
||||
}
|
||||
|
||||
// InstanceInfo defines the information about the instance.
|
||||
type InstanceInfo struct {
|
||||
// Name is the host name of the machine.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// Address is the IP address of the machine.
|
||||
Address string `json:"address,omitempty"`
|
||||
|
||||
// InternalAddress is the internal IP address of the machine.
|
||||
InternalAddress string `json:"internalAddress,omitempty"`
|
||||
|
||||
// Roles is the role of the machine.
|
||||
// +optional
|
||||
Roles []Role `json:"roles,omitempty"`
|
||||
|
||||
// Arch is the architecture of the machine. e.g. "amd64", "arm64".
|
||||
// +optional
|
||||
Arch string `json:"arch,omitempty"`
|
||||
|
||||
// Auth is the SSH authentication information of this machine. It will override the global auth configuration.
|
||||
// +optional
|
||||
Auth Auth `json:"auth,omitempty"`
|
||||
}
|
||||
|
||||
// KKLoadBalancerSpec defines the desired state of an KK load balancer.
|
||||
type KKLoadBalancerSpec struct {
|
||||
// The hostname on which the API server is serving.
|
||||
Host string `json:"host,omitempty"`
|
||||
}
|
||||
|
||||
// KKClusterStatus defines the observed state of KKCluster
|
||||
type KKClusterStatus struct {
|
||||
// +kubebuilder:default=false
|
||||
Ready bool `json:"ready"`
|
||||
// FailureReason will be set in the event that there is a terminal problem
|
||||
// reconciling the Machine and will contain a succinct value suitable
|
||||
// for machine interpretation.
|
||||
//
|
||||
// This field should not be set for transitive errors that a controller
|
||||
// faces that are expected to be fixed automatically over
|
||||
// time (like service outages), but instead indicate that something is
|
||||
// fundamentally wrong with the Machine's spec or the configuration of
|
||||
// the controller, and that manual intervention is required. Examples
|
||||
// of terminal errors would be invalid combinations of settings in the
|
||||
// spec, values that are unsupported by the controller, or the
|
||||
// responsible controller itself being critically misconfigured.
|
||||
//
|
||||
// Any transient errors that occur during the reconciliation of Machines
|
||||
// can be added as events to the Machine object and/or logged in the
|
||||
// controller's output.
|
||||
// +optional
|
||||
FailureReason *errors.MachineStatusError `json:"failureReason,omitempty"`
|
||||
|
||||
// FailureMessage will be set in the event that there is a terminal problem
|
||||
// reconciling the Machine and will contain a more verbose string suitable
|
||||
// for logging and human consumption.
|
||||
//
|
||||
// This field should not be set for transitive errors that a controller
|
||||
// faces that are expected to be fixed automatically over
|
||||
// time (like service outages), but instead indicate that something is
|
||||
// fundamentally wrong with the Machine's spec or the configuration of
|
||||
// the controller, and that manual intervention is required. Examples
|
||||
// of terminal errors would be invalid combinations of settings in the
|
||||
// spec, values that are unsupported by the controller, or the
|
||||
// responsible controller itself being critically misconfigured.
|
||||
//
|
||||
// Any transient errors that occur during the reconciliation of Machines
|
||||
// can be added as events to the Machine object and/or logged in the
|
||||
// controller's output.
|
||||
// +optional
|
||||
FailureMessage *string `json:"failureMessage,omitempty"`
|
||||
|
||||
// Conditions defines current service state of the KKMachine.
|
||||
// +optional
|
||||
Conditions clusterv1.Conditions `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=kkclusters,scope=Namespaced,categories=cluster-api,shortName=kkc
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels.cluster\\.x-k8s\\.io/cluster-name",description="Cluster to which this KKClusters belongs"
|
||||
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Cluster infrastructure is ready for SSH instances"
|
||||
// +kubebuilder:printcolumn:name="Endpoint",type="string",JSONPath=".spec.controlPlaneEndpoint",description="API Endpoint",priority=1
|
||||
// +k8s:defaulter-gen=true
|
||||
|
||||
// KKCluster is the Schema for the kkclusters API
|
||||
type KKCluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec KKClusterSpec `json:"spec,omitempty"`
|
||||
Status KKClusterStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// KKClusterList contains a list of KKCluster
|
||||
type KKClusterList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []KKCluster `json:"items"`
|
||||
}
|
||||
|
||||
// GetConditions returns the observations of the operational state of the KKCluster resource.
|
||||
func (k *KKCluster) GetConditions() clusterv1.Conditions {
|
||||
return k.Status.Conditions
|
||||
}
|
||||
|
||||
// SetConditions sets the underlying service state of the KKCluster to the predescribed clusterv1.Conditions.
|
||||
func (k *KKCluster) SetConditions(conditions clusterv1.Conditions) {
|
||||
k.Status.Conditions = conditions
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&KKCluster{}, &KKClusterList{})
|
||||
}
|
||||
|
|
@ -1,247 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
mapset "github.com/deckarep/golang-set"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/pkg/errors"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
"sigs.k8s.io/cluster-api/util/version"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultSSHUser = "root"
|
||||
defaultSSHPort = 22
|
||||
defaultSSHEstablishTimeout = 30 * time.Second
|
||||
)
|
||||
|
||||
// log is for logging in this package.
|
||||
var kkclusterlog = logf.Log.WithName("kkcluster-resource")
|
||||
|
||||
func (k *KKCluster) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(k).
|
||||
Complete()
|
||||
}
|
||||
|
||||
//+kubebuilder:webhook:path=/mutate-infrastructure-cluster-x-k8s-io-v1beta1-kkcluster,mutating=true,failurePolicy=fail,sideEffects=None,groups=infrastructure.cluster.x-k8s.io,resources=kkclusters,verbs=create;update,versions=v1beta1,name=default.kkcluster.infrastructure.cluster.x-k8s.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Defaulter = &KKCluster{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type
|
||||
func (k *KKCluster) Default() {
|
||||
kkclusterlog.Info("default", "name", k.Name)
|
||||
|
||||
defaultDistribution(&k.Spec)
|
||||
defaultAuth(&k.Spec.Nodes.Auth)
|
||||
defaultInstance(&k.Spec)
|
||||
defaultInPlaceUpgradeAnnotation(k.GetAnnotations())
|
||||
}
|
||||
|
||||
func defaultDistribution(spec *KKClusterSpec) {
|
||||
if spec.Distribution == "" {
|
||||
spec.Distribution = "kubernetes"
|
||||
}
|
||||
if spec.Distribution == "k8s" {
|
||||
spec.Distribution = "kubernetes"
|
||||
}
|
||||
}
|
||||
|
||||
func defaultAuth(auth *Auth) {
|
||||
if auth.User == "" {
|
||||
auth.User = defaultSSHUser
|
||||
}
|
||||
if auth.Port == nil {
|
||||
p := defaultSSHPort
|
||||
auth.Port = &p
|
||||
}
|
||||
if auth.Timeout == nil {
|
||||
t := defaultSSHEstablishTimeout
|
||||
auth.Timeout = &t
|
||||
}
|
||||
}
|
||||
|
||||
func defaultInstance(spec *KKClusterSpec) {
|
||||
for i := range spec.Nodes.Instances {
|
||||
instance := &spec.Nodes.Instances[i]
|
||||
if instance.Name == "" {
|
||||
instance.Name = names.SimpleNameGenerator.GenerateName("kk-instance-")
|
||||
}
|
||||
if instance.InternalAddress == "" {
|
||||
instance.InternalAddress = instance.Address
|
||||
}
|
||||
if instance.Arch == "" {
|
||||
instance.Arch = "amd64"
|
||||
}
|
||||
if len(instance.Roles) == 0 {
|
||||
instance.Roles = []Role{ControlPlane, Worker}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func defaultInPlaceUpgradeAnnotation(annotation map[string]string) {
|
||||
upgradeVersion, ok := annotation[InPlaceUpgradeVersionAnnotation]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(upgradeVersion, "v") {
|
||||
annotation[InPlaceUpgradeVersionAnnotation] = "v" + upgradeVersion
|
||||
}
|
||||
}
|
||||
|
||||
//+kubebuilder:webhook:path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-kkcluster,mutating=false,failurePolicy=fail,sideEffects=None,groups=infrastructure.cluster.x-k8s.io,resources=kkclusters,verbs=create;update,versions=v1beta1,name=validation.kkcluster.infrastructure.cluster.x-k8s.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Validator = &KKCluster{}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKCluster) ValidateCreate() error {
|
||||
kkclusterlog.Info("validate create", "name", k.Name)
|
||||
|
||||
var allErrs field.ErrorList
|
||||
allErrs = append(allErrs, validateDistribution(k.Spec)...)
|
||||
allErrs = append(allErrs, validateClusterNodes(k.Spec.Nodes)...)
|
||||
allErrs = append(allErrs, validateLoadBalancer(k.Spec.ControlPlaneLoadBalancer)...)
|
||||
|
||||
return aggregateObjErrors(k.GroupVersionKind().GroupKind(), k.Name, allErrs)
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKCluster) ValidateUpdate(old runtime.Object) error {
|
||||
kkclusterlog.Info("validate update", "name", k.Name)
|
||||
|
||||
var allErrs field.ErrorList
|
||||
oldC, ok := old.(*KKCluster)
|
||||
if !ok {
|
||||
return apierrors.NewBadRequest(fmt.Sprintf("expected an KKCluster but got a %T", old))
|
||||
}
|
||||
|
||||
newLoadBalancer := &KKLoadBalancerSpec{}
|
||||
|
||||
if k.Spec.ControlPlaneLoadBalancer != nil {
|
||||
newLoadBalancer = k.Spec.ControlPlaneLoadBalancer.DeepCopy()
|
||||
}
|
||||
|
||||
if oldC.Spec.ControlPlaneLoadBalancer != nil {
|
||||
// If old scheme was not nil, the new scheme should be the same.
|
||||
existingLoadBalancer := oldC.Spec.ControlPlaneLoadBalancer.DeepCopy()
|
||||
if !cmp.Equal(newLoadBalancer, existingLoadBalancer) {
|
||||
allErrs = append(allErrs,
|
||||
field.Invalid(field.NewPath("spec", "controlPlaneLoadBalancer"),
|
||||
k.Spec.ControlPlaneLoadBalancer, "field is immutable"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, validateClusterNodes(k.Spec.Nodes)...)
|
||||
allErrs = append(allErrs, validateInPlaceUpgrade(k.GetAnnotations())...)
|
||||
return aggregateObjErrors(k.GroupVersionKind().GroupKind(), k.Name, allErrs)
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKCluster) ValidateDelete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDistribution(spec KKClusterSpec) []*field.Error {
|
||||
var errs field.ErrorList
|
||||
path := field.NewPath("spec", "distribution")
|
||||
switch spec.Distribution {
|
||||
case K3S:
|
||||
return errs
|
||||
case KUBERNETES:
|
||||
return errs
|
||||
default:
|
||||
errs = append(errs, field.NotSupported(path, spec.Distribution, []string{K3S, KUBERNETES}))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func validateLoadBalancer(loadBalancer *KKLoadBalancerSpec) []*field.Error {
|
||||
var errs field.ErrorList
|
||||
path := field.NewPath("spec", "controlPlaneLoadBalancer")
|
||||
if loadBalancer.Host == "" {
|
||||
errs = append(errs, field.Required(path.Child("host"), "can't be empty"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func validateClusterNodes(nodes Nodes) []*field.Error {
|
||||
var errs field.ErrorList
|
||||
|
||||
if nodes.Auth.Password == "" && nodes.Auth.PrivateKey == "" && nodes.Auth.PrivateKeyPath == "" && nodes.Auth.Secret == "" {
|
||||
errs = append(errs, field.Required(field.NewPath("spec", "nodes", "auth"), "password and privateKey can't both be empty"))
|
||||
}
|
||||
|
||||
nameSet := mapset.NewThreadUnsafeSet()
|
||||
addrSet := mapset.NewThreadUnsafeSet()
|
||||
internalAddrSet := mapset.NewThreadUnsafeSet()
|
||||
for i := range nodes.Instances {
|
||||
instance := nodes.Instances[i]
|
||||
path := field.NewPath("spec", "nodes", fmt.Sprintf("instances[%d]", i))
|
||||
if strings.ToLower(instance.Name) != instance.Name {
|
||||
errs = append(errs,
|
||||
field.Forbidden(path.Child("name"), "instance name must be the lower case"))
|
||||
}
|
||||
if !nameSet.Add(instance.Name) {
|
||||
errs = append(errs, field.Duplicate(path.Child("name"), instance.Name))
|
||||
}
|
||||
|
||||
if net.ParseIP(instance.Address) == nil {
|
||||
errs = append(errs, field.Invalid(path.Child("address"), instance.Address, "instance address is invalid"))
|
||||
}
|
||||
if !addrSet.Add(instance.Address) {
|
||||
errs = append(errs, field.Duplicate(path.Child("address"), instance.Address))
|
||||
}
|
||||
|
||||
if net.ParseIP(instance.InternalAddress) == nil {
|
||||
errs = append(errs, field.Invalid(path.Child("internalAddress"), instance.InternalAddress, "instance internalAddress is invalid"))
|
||||
}
|
||||
if !internalAddrSet.Add(instance.InternalAddress) {
|
||||
errs = append(errs, field.Duplicate(path.Child("internalAddress"), instance.InternalAddress))
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func validateInPlaceUpgrade(newAnnotation map[string]string) []*field.Error {
|
||||
var allErrs field.ErrorList
|
||||
|
||||
if v, ok := newAnnotation[InPlaceUpgradeVersionAnnotation]; ok {
|
||||
_, err := version.ParseMajorMinorPatch(v)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs,
|
||||
field.InternalError(
|
||||
field.NewPath("metadata", "annotations"),
|
||||
errors.Wrapf(err, "failed to parse in-place upgrade version: %s", v)),
|
||||
)
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
)
|
||||
|
||||
// KKClusterTemplateSpec defines the desired state of KKClusterTemplate
|
||||
type KKClusterTemplateSpec struct {
|
||||
Template KKClusterTemplateResource `json:"template"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=kkclustertemplates,scope=Namespaced,categories=cluster-api,shortName=kkct
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of KKClusterTemplate"
|
||||
// +k8s:defaulter-gen=true
|
||||
|
||||
// KKClusterTemplate is the Schema for the kkclustertemplates API
|
||||
type KKClusterTemplate struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec KKClusterTemplateSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// KKClusterTemplateList contains a list of KKClusterTemplate
|
||||
type KKClusterTemplateList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []KKClusterTemplate `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&KKClusterTemplate{}, &KKClusterTemplateList{})
|
||||
}
|
||||
|
||||
// KKClusterTemplateResource Standard object's metadata
|
||||
type KKClusterTemplateResource struct {
|
||||
// Standard object's metadata.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||
// +optional
|
||||
ObjectMeta clusterv1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec KKClusterSpec `json:"spec"`
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
// log is for logging in this package.
|
||||
var kkclustertemplatelog = logf.Log.WithName("kkclustertemplate-resource")
|
||||
|
||||
// SetupWebhookWithManager sets up and registers the webhook with the manager.
|
||||
func (r *KKClusterTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(r).
|
||||
Complete()
|
||||
}
|
||||
|
||||
//+kubebuilder:webhook:path=/mutate-infrastructure-cluster-x-k8s-io-v1beta1-kkclustertemplate,mutating=true,failurePolicy=fail,sideEffects=None,groups=infrastructure.cluster.x-k8s.io,resources=kkclustertemplates,verbs=create;update,versions=v1beta1,name=default.kkclustertemplate.infrastructure.cluster.x-k8s.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Defaulter = &KKClusterTemplate{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type
|
||||
func (r *KKClusterTemplate) Default() {
|
||||
kkclustertemplatelog.Info("default", "name", r.Name)
|
||||
|
||||
defaultDistribution(&r.Spec.Template.Spec)
|
||||
defaultAuth(&r.Spec.Template.Spec.Nodes.Auth)
|
||||
defaultInstance(&r.Spec.Template.Spec)
|
||||
}
|
||||
|
||||
//+kubebuilder:webhook:path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-kkclustertemplate,mutating=false,failurePolicy=fail,sideEffects=None,groups=infrastructure.cluster.x-k8s.io,resources=kkclustertemplates,verbs=create;update,versions=v1beta1,name=validation.kkclustertemplate.infrastructure.cluster.x-k8s.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Validator = &KKClusterTemplate{}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (r *KKClusterTemplate) ValidateCreate() error {
|
||||
kkclustertemplatelog.Info("validate create", "name", r.Name)
|
||||
|
||||
var allErrs field.ErrorList
|
||||
allErrs = append(allErrs, validateDistribution(r.Spec.Template.Spec)...)
|
||||
allErrs = append(allErrs, validateClusterNodes(r.Spec.Template.Spec.Nodes)...)
|
||||
allErrs = append(allErrs, validateLoadBalancer(r.Spec.Template.Spec.ControlPlaneLoadBalancer)...)
|
||||
|
||||
return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs)
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (r *KKClusterTemplate) ValidateUpdate(old runtime.Object) error {
|
||||
kkclustertemplatelog.Info("validate update", "name", r.Name)
|
||||
|
||||
oldC := old.(*KKClusterTemplate)
|
||||
if !cmp.Equal(r.Spec, oldC.Spec) {
|
||||
return apierrors.NewBadRequest("KKClusterTemplate.Spec is immutable")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
|
||||
func (r *KKClusterTemplate) ValidateDelete() error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,206 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
"sigs.k8s.io/cluster-api/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// InstanceFinalizer allows ReconcileKKInstance to clean up KubeKey resources associated with KKInstance before
|
||||
// removing it from the apiserver.
|
||||
InstanceFinalizer = "kkinstance.infrastructure.cluster.x-k8s.io"
|
||||
)
|
||||
|
||||
// InstanceState describes the state of an KK instance.
|
||||
type InstanceState string
|
||||
|
||||
var (
|
||||
// InstanceStatePending is the string representing an instance in a pending state.
|
||||
InstanceStatePending = InstanceState("pending")
|
||||
|
||||
// InstanceStateBootstrapping is the string representing an instance in a bootstrapping state.
|
||||
InstanceStateBootstrapping = InstanceState("bootstrapping")
|
||||
|
||||
// InstanceStateBootstrapped = InstanceState("bootstrapped")
|
||||
|
||||
// InstanceStateRunning is the string representing an instance in a running state.
|
||||
InstanceStateRunning = InstanceState("running")
|
||||
|
||||
// InstanceStateInPlaceUpgrading is the string representing an instance in an in-place-upgrading state.
|
||||
InstanceStateInPlaceUpgrading = InstanceState("InPlaceUpgrading")
|
||||
|
||||
// InstanceStateCleaning is the string representing an instance in a cleaning state.
|
||||
InstanceStateCleaning = InstanceState("cleaning")
|
||||
|
||||
// InstanceStateCleaned is the string representing an instance in a cleared state.
|
||||
InstanceStateCleaned = InstanceState("cleaned")
|
||||
|
||||
// InstanceRunningStates defines the set of states in which an SSH instance is
|
||||
// running or going to be running soon.
|
||||
InstanceRunningStates = sets.NewString(
|
||||
string(InstanceStatePending),
|
||||
string(InstanceStateRunning),
|
||||
)
|
||||
|
||||
// InstanceKnownStates represents all known KKInstance states.
|
||||
InstanceKnownStates = InstanceRunningStates.Union(
|
||||
sets.NewString(
|
||||
string(InstanceStateBootstrapping),
|
||||
string(InstanceStateCleaning),
|
||||
string(InstanceStateCleaned),
|
||||
string(InstanceStateInPlaceUpgrading),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
// KKInstanceSpec defines the desired state of KKInstance
|
||||
type KKInstanceSpec struct {
|
||||
// Name is the host name of the machine.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// Address is the IP address of the machine.
|
||||
Address string `json:"address,omitempty"`
|
||||
|
||||
// InternalAddress is the internal IP address of the machine.
|
||||
InternalAddress string `json:"internalAddress,omitempty"`
|
||||
|
||||
// Roles is the role of the machine.
|
||||
// +optional
|
||||
Roles []Role `json:"roles,omitempty"`
|
||||
|
||||
// Arch is the architecture of the machine. e.g. "amd64", "arm64".
|
||||
// +optional
|
||||
Arch string `json:"arch,omitempty"`
|
||||
|
||||
// Auth is the SSH authentication information of this machine. It will override the global auth configuration.
|
||||
// +optional
|
||||
Auth Auth `json:"auth,omitempty"`
|
||||
|
||||
// ContainerManager is the container manager config of this machine.
|
||||
// +optional
|
||||
ContainerManager ContainerManager `json:"containerManager,omitempty"`
|
||||
|
||||
// Repository is the repository config of this machine.
|
||||
// +optional
|
||||
Repository *Repository `json:"repository,omitempty"`
|
||||
}
|
||||
|
||||
// KKInstanceStatus defines the observed state of KKInstance
|
||||
type KKInstanceStatus struct {
|
||||
// The current state of the instance.
|
||||
State InstanceState `json:"instanceState,omitempty"`
|
||||
|
||||
// NodeRef will point to the corresponding Node if it exists.
|
||||
// +optional
|
||||
NodeRef *corev1.ObjectReference `json:"nodeRef,omitempty"`
|
||||
|
||||
// NodeInfo is a set of ids/uuids to uniquely identify the node.
|
||||
// More info: https://kubernetes.io/docs/concepts/nodes/node/#info
|
||||
// +optional
|
||||
NodeInfo *corev1.NodeSystemInfo `json:"nodeInfo,omitempty"`
|
||||
|
||||
// FailureReason will be set in the event that there is a terminal problem
|
||||
// reconciling the Machine and will contain a succinct value suitable
|
||||
// for machine interpretation.
|
||||
//
|
||||
// This field should not be set for transitive errors that a controller
|
||||
// faces that are expected to be fixed automatically over
|
||||
// time (like service outages), but instead indicate that something is
|
||||
// fundamentally wrong with the Machine's spec or the configuration of
|
||||
// the controller, and that manual intervention is required. Examples
|
||||
// of terminal errors would be invalid combinations of settings in the
|
||||
// spec, values that are unsupported by the controller, or the
|
||||
// responsible controller itself being critically misconfigured.
|
||||
//
|
||||
// Any transient errors that occur during the reconciliation of Machines
|
||||
// can be added as events to the Machine object and/or logged in the
|
||||
// controller's output.
|
||||
// +optional
|
||||
FailureReason *errors.MachineStatusError `json:"failureReason,omitempty"`
|
||||
|
||||
// FailureMessage will be set in the event that there is a terminal problem
|
||||
// reconciling the Machine and will contain a more verbose string suitable
|
||||
// for logging and human consumption.
|
||||
//
|
||||
// This field should not be set for transitive errors that a controller
|
||||
// faces that are expected to be fixed automatically over
|
||||
// time (like service outages), but instead indicate that something is
|
||||
// fundamentally wrong with the Machine's spec or the configuration of
|
||||
// the controller, and that manual intervention is required. Examples
|
||||
// of terminal errors would be invalid combinations of settings in the
|
||||
// spec, values that are unsupported by the controller, or the
|
||||
// responsible controller itself being critically misconfigured.
|
||||
//
|
||||
// Any transient errors that occur during the reconciliation of Machines
|
||||
// can be added as events to the Machine object and/or logged in the
|
||||
// controller's output.
|
||||
// +optional
|
||||
FailureMessage *string `json:"failureMessage,omitempty"`
|
||||
|
||||
// Conditions defines current service state of the KKMachine.
|
||||
// +optional
|
||||
Conditions clusterv1.Conditions `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:path=kkinstances,scope=Namespaced,categories=cluster-api,shortName=kki
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:printcolumn:name="Hostname",type="string",JSONPath=".spec.name",description="kubekey instance hostname"
|
||||
// +kubebuilder:printcolumn:name="Address",type="string",JSONPath=".spec.address",description="kubekey instance address"
|
||||
// +kubebuilder:printcolumn:name="State",type="string",JSONPath=".status.instanceState",description="KKInstance state"
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of KKInstance"
|
||||
// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".status.nodeInfo.kubeletVersion",description="Kubernetes version associated with this KKInstance"
|
||||
// +k8s:defaulter-gen=true
|
||||
|
||||
// KKInstance is the Schema for the kkinstances API
|
||||
type KKInstance struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec KKInstanceSpec `json:"spec,omitempty"`
|
||||
Status KKInstanceStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GetConditions returns the observations of the operational state of the KKMachine resource.
|
||||
func (k *KKInstance) GetConditions() clusterv1.Conditions {
|
||||
return k.Status.Conditions
|
||||
}
|
||||
|
||||
// SetConditions sets the underlying service state of the KKInstance to the predescribed clusterv1.Conditions.
|
||||
func (k *KKInstance) SetConditions(conditions clusterv1.Conditions) {
|
||||
k.Status.Conditions = conditions
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// KKInstanceList contains a list of KKInstance
|
||||
type KKInstanceList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []KKInstance `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&KKInstance{}, &KKInstanceList{})
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"sigs.k8s.io/cluster-api/util/version"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
// log is for logging in this package.
|
||||
var kkinstancelog = logf.Log.WithName("kkinstance-resource")
|
||||
|
||||
func (k *KKInstance) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(k).
|
||||
Complete()
|
||||
}
|
||||
|
||||
//+kubebuilder:webhook:path=/mutate-infrastructure-cluster-x-k8s-io-v1beta1-kkinstance,mutating=true,failurePolicy=fail,sideEffects=None,groups=infrastructure.cluster.x-k8s.io,resources=kkinstances,verbs=create;update,versions=v1beta1,name=default.kkinstance.infrastructure.cluster.x-k8s.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Defaulter = &KKInstance{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type
|
||||
func (k *KKInstance) Default() {
|
||||
kkinstancelog.Info("default", "name", k.Name)
|
||||
}
|
||||
|
||||
//+kubebuilder:webhook:path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-kkinstance,mutating=false,failurePolicy=fail,sideEffects=None,groups=infrastructure.cluster.x-k8s.io,resources=kkinstances,verbs=create;update,versions=v1beta1,name=validation.kkinstance.infrastructure.cluster.x-k8s.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Validator = &KKInstance{}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKInstance) ValidateCreate() error {
|
||||
kkinstancelog.Info("validate create", "name", k.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKInstance) ValidateUpdate(old runtime.Object) error {
|
||||
kkinstancelog.Info("validate update", "name", k.Name)
|
||||
|
||||
var allErrs field.ErrorList
|
||||
if v, ok := k.GetAnnotations()[InPlaceUpgradeVersionAnnotation]; ok {
|
||||
if k.Status.NodeInfo == nil {
|
||||
allErrs = append(allErrs,
|
||||
field.Invalid(
|
||||
field.NewPath("status", "nodeInfo"),
|
||||
k.Status.NodeInfo,
|
||||
"nodeInfo is required for in-place upgrade"))
|
||||
}
|
||||
newSemverVersion, err := version.ParseMajorMinorPatch(v)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs,
|
||||
field.InternalError(
|
||||
field.NewPath("metadata", "annotations"),
|
||||
errors.Wrapf(err, "failed to parse in-place upgrade version: %s", v)),
|
||||
)
|
||||
}
|
||||
oldSemverVersion, err := version.ParseMajorMinorPatch(k.Status.NodeInfo.KubeletVersion)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs,
|
||||
field.InternalError(
|
||||
field.NewPath("status", "nodeInfo", "kubeletVersion"),
|
||||
errors.Wrapf(err, "failed to parse old version: %s", k.Status.NodeInfo.KubeletVersion)),
|
||||
)
|
||||
}
|
||||
|
||||
if newSemverVersion.Equals(oldSemverVersion) {
|
||||
allErrs = append(allErrs,
|
||||
field.Invalid(
|
||||
field.NewPath("metadata", "annotations"),
|
||||
v,
|
||||
"new version must be different from old version"),
|
||||
)
|
||||
}
|
||||
|
||||
if !(newSemverVersion.GT(oldSemverVersion) &&
|
||||
newSemverVersion.Major == oldSemverVersion.Major &&
|
||||
(newSemverVersion.Minor == oldSemverVersion.Minor+1 || newSemverVersion.Minor == oldSemverVersion.Minor)) {
|
||||
allErrs = append(allErrs,
|
||||
field.Invalid(field.NewPath("metadata", "annotations"),
|
||||
v, "Skipping MINOR versions when upgrading is unsupported."))
|
||||
}
|
||||
}
|
||||
|
||||
return aggregateObjErrors(k.GroupVersionKind().GroupKind(), k.Name, allErrs)
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKInstance) ValidateDelete() error {
|
||||
kkinstancelog.Info("validate delete", "name", k.Name)
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
"sigs.k8s.io/cluster-api/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// MachineFinalizer allows ReconcileKKMachine to clean up KubeKey resources associated with KKMachine before
|
||||
// removing it from the apiserver.
|
||||
MachineFinalizer = "kkmachine.infrastructure.cluster.x-k8s.io"
|
||||
)
|
||||
|
||||
// KKMachineSpec defines the desired state of KKMachine
|
||||
type KKMachineSpec struct {
|
||||
// ProviderID is the unique identifier as specified by the kubekey provider.
|
||||
ProviderID *string `json:"providerID,omitempty"`
|
||||
|
||||
// InstanceID is the name of the KKInstance.
|
||||
InstanceID *string `json:"instanceID,omitempty"`
|
||||
|
||||
// Roles is the role of the machine.
|
||||
// +optional
|
||||
Roles []Role `json:"roles"`
|
||||
|
||||
// ContainerManager is the container manager config of this machine.
|
||||
// +optional
|
||||
ContainerManager ContainerManager `json:"containerManager"`
|
||||
|
||||
// Repository is the repository config of this machine.
|
||||
// +optional
|
||||
Repository *Repository `json:"repository,omitempty"`
|
||||
}
|
||||
|
||||
// KKMachineStatus defines the observed state of KKMachine
|
||||
type KKMachineStatus struct {
|
||||
// Ready is true when the provider resource is ready.
|
||||
// +optional
|
||||
Ready bool `json:"ready"`
|
||||
|
||||
// Addresses contains the KK instance associated addresses.
|
||||
Addresses []clusterv1.MachineAddress `json:"addresses,omitempty"`
|
||||
|
||||
// InstanceState is the state of the KK instance for this machine.
|
||||
// +optional
|
||||
InstanceState *InstanceState `json:"instanceState,omitempty"`
|
||||
|
||||
// FailureReason will be set in the event that there is a terminal problem
|
||||
// reconciling the Machine and will contain a succinct value suitable
|
||||
// for machine interpretation.
|
||||
//
|
||||
// This field should not be set for transitive errors that a controller
|
||||
// faces that are expected to be fixed automatically over
|
||||
// time (like service outages), but instead indicate that something is
|
||||
// fundamentally wrong with the Machine's spec or the configuration of
|
||||
// the controller, and that manual intervention is required. Examples
|
||||
// of terminal errors would be invalid combinations of settings in the
|
||||
// spec, values that are unsupported by the controller, or the
|
||||
// responsible controller itself being critically misconfigured.
|
||||
//
|
||||
// Any transient errors that occur during the reconciliation of Machines
|
||||
// can be added as events to the Machine object and/or logged in the
|
||||
// controller's output.
|
||||
// +optional
|
||||
FailureReason *errors.MachineStatusError `json:"failureReason,omitempty"`
|
||||
|
||||
// FailureMessage will be set in the event that there is a terminal problem
|
||||
// reconciling the Machine and will contain a more verbose string suitable
|
||||
// for logging and human consumption.
|
||||
//
|
||||
// This field should not be set for transitive errors that a controller
|
||||
// faces that are expected to be fixed automatically over
|
||||
// time (like service outages), but instead indicate that something is
|
||||
// fundamentally wrong with the Machine's spec or the configuration of
|
||||
// the controller, and that manual intervention is required. Examples
|
||||
// of terminal errors would be invalid combinations of settings in the
|
||||
// spec, values that are unsupported by the controller, or the
|
||||
// responsible controller itself being critically misconfigured.
|
||||
//
|
||||
// Any transient errors that occur during the reconciliation of Machines
|
||||
// can be added as events to the Machine object and/or logged in the
|
||||
// controller's output.
|
||||
// +optional
|
||||
FailureMessage *string `json:"failureMessage,omitempty"`
|
||||
|
||||
// Conditions defines current service state of the KKMachine.
|
||||
// +optional
|
||||
Conditions clusterv1.Conditions `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=kkmachines,scope=Namespaced,categories=cluster-api,shortName=kkm
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels.cluster\\.x-k8s\\.io/cluster-name",description="Cluster to which this KKMachine belongs"
|
||||
// +kubebuilder:printcolumn:name="Instance",type="string",JSONPath=".spec.instanceID",description="KKInstance name"
|
||||
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Machine ready status"
|
||||
// +kubebuilder:printcolumn:name="Machine",type="string",JSONPath=".metadata.ownerReferences[?(@.kind==\"Machine\")].name",description="Machine object which owns with this KKMachine"
|
||||
// +k8s:defaulter-gen=true
|
||||
|
||||
// KKMachine is the Schema for the kkmachines API
|
||||
type KKMachine struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec KKMachineSpec `json:"spec,omitempty"`
|
||||
Status KKMachineStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GetConditions returns the observations of the operational state of the KKMachine resource.
|
||||
func (k *KKMachine) GetConditions() clusterv1.Conditions {
|
||||
return k.Status.Conditions
|
||||
}
|
||||
|
||||
// SetConditions sets the underlying service state of the KKMachine to the predescribed clusterv1.Conditions.
|
||||
func (k *KKMachine) SetConditions(conditions clusterv1.Conditions) {
|
||||
k.Status.Conditions = conditions
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// KKMachineList contains a list of KKMachine
|
||||
type KKMachineList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []KKMachine `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&KKMachine{}, &KKMachineList{})
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
// log is for logging in this package.
|
||||
var kkmachinelog = logf.Log.WithName("kkmachine-resource")
|
||||
|
||||
func (k *KKMachine) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(k).
|
||||
Complete()
|
||||
}
|
||||
|
||||
//+kubebuilder:webhook:path=/mutate-infrastructure-cluster-x-k8s-io-v1beta1-kkmachine,mutating=true,failurePolicy=fail,sideEffects=None,groups=infrastructure.cluster.x-k8s.io,resources=kkmachines,verbs=create;update,versions=v1beta1,name=default.kkmachine.infrastructure.cluster.x-k8s.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Defaulter = &KKMachine{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type
|
||||
func (k *KKMachine) Default() {
|
||||
kkmachinelog.Info("default", "name", k.Name)
|
||||
|
||||
defaultContainerManager(&k.Spec)
|
||||
}
|
||||
|
||||
func defaultContainerManager(spec *KKMachineSpec) {
|
||||
// Direct connection to the user-provided CRI socket
|
||||
if spec.ContainerManager.CRISocket != "" {
|
||||
return
|
||||
}
|
||||
|
||||
if spec.ContainerManager.Type == "" {
|
||||
spec.ContainerManager.Type = ContainerdType
|
||||
}
|
||||
|
||||
switch spec.ContainerManager.Type {
|
||||
case ContainerdType:
|
||||
if spec.ContainerManager.Version == "" {
|
||||
spec.ContainerManager.Version = DefaultContainerdVersion
|
||||
}
|
||||
spec.ContainerManager.CRISocket = DefaultContainerdCRISocket
|
||||
case DockerType:
|
||||
if spec.ContainerManager.Version == "" {
|
||||
spec.ContainerManager.Version = DefaultDockerVersion
|
||||
}
|
||||
if spec.ContainerManager.CRIDockerdVersion == "" {
|
||||
spec.ContainerManager.CRIDockerdVersion = DefaultCRIDockerdVersion
|
||||
}
|
||||
spec.ContainerManager.CRISocket = DefaultDockerCRISocket
|
||||
}
|
||||
|
||||
if spec.ContainerManager.CRICTLVersion == "" {
|
||||
spec.ContainerManager.CRICTLVersion = DefaultCrictlVersion
|
||||
}
|
||||
|
||||
spec.ContainerManager.Version = strings.TrimPrefix(spec.ContainerManager.Version, "v")
|
||||
|
||||
if !strings.HasPrefix(spec.ContainerManager.CRICTLVersion, "v") {
|
||||
spec.ContainerManager.CRICTLVersion = "v" + spec.ContainerManager.CRICTLVersion
|
||||
}
|
||||
}
|
||||
|
||||
//+kubebuilder:webhook:path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-kkmachine,mutating=false,failurePolicy=fail,sideEffects=None,groups=infrastructure.cluster.x-k8s.io,resources=kkmachines,verbs=create;update,versions=v1beta1,name=validation.kkmachine.infrastructure.cluster.x-k8s.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Validator = &KKMachine{}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKMachine) ValidateCreate() error {
|
||||
kkmachinelog.Info("validate create", "name", k.Name)
|
||||
|
||||
var allErrs field.ErrorList
|
||||
allErrs = append(allErrs, validateRepository(k.Spec.Repository)...)
|
||||
return aggregateObjErrors(k.GroupVersionKind().GroupKind(), k.Name, allErrs)
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKMachine) ValidateUpdate(old runtime.Object) error {
|
||||
kkmachinelog.Info("validate update", "name", k.Name)
|
||||
var allErrs field.ErrorList
|
||||
allErrs = append(allErrs, validateRepository(k.Spec.Repository)...)
|
||||
return aggregateObjErrors(k.GroupVersionKind().GroupKind(), k.Name, allErrs)
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKMachine) ValidateDelete() error {
|
||||
kkmachinelog.Info("validate delete", "name", k.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateRepository(repo *Repository) field.ErrorList { //nolint:unparam
|
||||
var allErrs field.ErrorList
|
||||
if repo == nil {
|
||||
return allErrs
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utildefaulting "sigs.k8s.io/cluster-api/util/defaulting"
|
||||
)
|
||||
|
||||
func TestKKMachine_Default(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
kkm := &KKMachine{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "foobar",
|
||||
},
|
||||
}
|
||||
|
||||
t.Run("for KKMachine", utildefaulting.DefaultValidateTest(kkm))
|
||||
kkm.Default()
|
||||
|
||||
g.Expect(kkm.Spec.ContainerManager.Type).To(Equal(ContainerdType))
|
||||
g.Expect(kkm.Spec.ContainerManager.Version).To(Equal(DefaultContainerdVersion))
|
||||
g.Expect(kkm.Spec.ContainerManager.CRICTLVersion).To(Equal(DefaultCrictlVersion))
|
||||
|
||||
kkm2 := &KKMachine{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "foobar",
|
||||
},
|
||||
Spec: KKMachineSpec{
|
||||
ContainerManager: ContainerManager{
|
||||
Type: ContainerdType,
|
||||
Version: "v1.6.4",
|
||||
CRICTLVersion: "1.24.0",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
t.Run("for KKMachine2", utildefaulting.DefaultValidateTest(kkm2))
|
||||
kkm2.Default()
|
||||
|
||||
g.Expect(kkm2.Spec.ContainerManager.Type).To(Equal(ContainerdType))
|
||||
g.Expect(kkm2.Spec.ContainerManager.Version).To(Equal("1.6.4"))
|
||||
g.Expect(kkm2.Spec.ContainerManager.CRICTLVersion).To(Equal("v1.24.0"))
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
)
|
||||
|
||||
// KKMachineTemplateStatus defines a status for an KKMachineTemplate.
|
||||
type KKMachineTemplateStatus struct {
|
||||
// Capacity defines the resource capacity for this machine.
|
||||
// This value is used for autoscaling from zero operations as defined in:
|
||||
// https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210310-opt-in-autoscaling-from-zero.md
|
||||
// +optional
|
||||
Capacity corev1.ResourceList `json:"capacity,omitempty"`
|
||||
}
|
||||
|
||||
// KKMachineTemplateSpec defines the desired state of KKMachineTemplate
|
||||
type KKMachineTemplateSpec struct {
|
||||
Template KKMachineTemplateResource `json:"template"`
|
||||
}
|
||||
|
||||
// KKMachineTemplateResource describes the data needed to create am KKMachine from a template.
|
||||
type KKMachineTemplateResource struct {
|
||||
// Standard object's metadata.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||
// +optional
|
||||
ObjectMeta clusterv1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec is the specification of the desired behavior of the machine.
|
||||
Spec KKMachineSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=kkmachinetemplates,scope=Namespaced,categories=cluster-api,shortName=kkmt
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of KKMachineTemplate"
|
||||
// +k8s:defaulter-gen=true
|
||||
|
||||
// KKMachineTemplate is the Schema for the kkmachinetemplates API
|
||||
type KKMachineTemplate struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec KKMachineTemplateSpec `json:"spec,omitempty"`
|
||||
Status KKMachineTemplateStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// KKMachineTemplateList contains a list of KKMachineTemplate
|
||||
type KKMachineTemplateList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []KKMachineTemplate `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&KKMachineTemplate{}, &KKMachineTemplateList{})
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
// log is for logging in this package.
|
||||
var kkmachinetemplatelog = logf.Log.WithName("kkmachinetemplate-resource")
|
||||
|
||||
func (k *KKMachineTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(k).
|
||||
Complete()
|
||||
}
|
||||
|
||||
//+kubebuilder:webhook:path=/mutate-infrastructure-cluster-x-k8s-io-v1beta1-kkmachinetemplate,mutating=true,failurePolicy=fail,sideEffects=None,groups=infrastructure.cluster.x-k8s.io,resources=kkmachinetemplates,verbs=create;update,versions=v1beta1,name=default.kkmachinetemplate.infrastructure.cluster.x-k8s.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Defaulter = &KKMachineTemplate{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type
|
||||
func (k *KKMachineTemplate) Default() {
|
||||
kkmachinetemplatelog.Info("default", "name", k.Name)
|
||||
|
||||
defaultContainerManager(&k.Spec.Template.Spec)
|
||||
}
|
||||
|
||||
//+kubebuilder:webhook:path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-kkmachinetemplate,mutating=false,failurePolicy=fail,sideEffects=None,groups=infrastructure.cluster.x-k8s.io,resources=kkmachinetemplates,verbs=create;update,versions=v1beta1,name=validation.kkmachinetemplate.infrastructure.cluster.x-k8s.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Validator = &KKMachineTemplate{}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKMachineTemplate) ValidateCreate() error {
|
||||
kkmachinetemplatelog.Info("validate create", "name", k.Name)
|
||||
|
||||
spec := k.Spec.Template.Spec
|
||||
var allErrs field.ErrorList
|
||||
allErrs = append(allErrs, validateRepository(spec.Repository)...)
|
||||
return aggregateObjErrors(k.GroupVersionKind().GroupKind(), k.Name, allErrs)
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKMachineTemplate) ValidateUpdate(old runtime.Object) error {
|
||||
kkmachinetemplatelog.Info("validate update", "name", k.Name)
|
||||
|
||||
spec := k.Spec.Template.Spec
|
||||
var allErrs field.ErrorList
|
||||
allErrs = append(allErrs, validateRepository(spec.Repository)...)
|
||||
return aggregateObjErrors(k.GroupVersionKind().GroupKind(), k.Name, allErrs)
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
|
||||
func (k *KKMachineTemplate) ValidateDelete() error {
|
||||
kkmachinetemplatelog.Info("validate delete", "name", k.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Registry is the configuration for a cluster registry
|
||||
type Registry struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// PrivateRegistry defines the private registry address of ContainerManager.
|
||||
PrivateRegistry string `json:"privateRegistry"`
|
||||
|
||||
// InsecureRegistries defines the insecure registries of ContainerManager.
|
||||
InsecureRegistries []string `json:"insecureRegistries,omitempty"`
|
||||
|
||||
// RegistryMirrors defines the registry mirrors of this PrivateRegistry.
|
||||
RegistryMirrors []string `json:"registryMirrors,omitempty"`
|
||||
|
||||
// NamespaceOverride defines the namespace override of this PrivateRegistry.
|
||||
NamespaceOverride string `json:"namespaceOverride"`
|
||||
|
||||
// Auth defines the auth of this PrivateRegistry.
|
||||
Auth RegistryAuth `json:"auth"`
|
||||
}
|
||||
|
||||
// RegistryAuth defines the auth of a registry
|
||||
type RegistryAuth struct {
|
||||
// Username defines the username of this PrivateRegistry.
|
||||
Username string `json:"username"`
|
||||
|
||||
// Password defines the password of this PrivateRegistry.
|
||||
Password string `json:"password"`
|
||||
|
||||
// InsecureSkipVerify allow contacting this PrivateRegistry over HTTPS with failed TLS verification.
|
||||
InsecureSkipVerify bool `json:"insecureSkipVerify"`
|
||||
|
||||
// PlainHTTP allow contacting this PrivateRegistry over HTTP.
|
||||
PlainHTTP bool `json:"plainHTTP"`
|
||||
|
||||
// CertsPath defines the path of the certs files of this PrivateRegistry.
|
||||
CertsPath string `json:"certsPath"`
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
// ISO type
|
||||
const (
|
||||
NONE = "none"
|
||||
AUTO = "auto"
|
||||
)
|
||||
|
||||
// Repository defines the repository of the instance.
|
||||
type Repository struct {
|
||||
// ISO specifies the ISO file name. There are 3 options:
|
||||
// "": empty string means will not install the packages.
|
||||
// "none": no ISO file will be used. And capkk will use the default repository to install the required packages.
|
||||
// "auto": capkk will detect the ISO file automatically. Only support Ubuntu/Debian/CentOS.
|
||||
// "xxx-20.04-debs-amd64.iso": use the specified name to get the ISO file name.
|
||||
// +optional
|
||||
ISO string `json:"iso,omitempty"`
|
||||
|
||||
// Update will update the repository packages list and cache if it is true.
|
||||
// +optional
|
||||
Update bool `json:"update,omitempty"`
|
||||
|
||||
// Packages is a list of packages to be installed.
|
||||
// +optional
|
||||
Packages []string `json:"packages,omitempty"`
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
// Role represents a role of a node.
|
||||
type Role string
|
||||
|
||||
// Internal roles.
|
||||
const (
|
||||
ControlPlane Role = "control-plane"
|
||||
Master Role = "master"
|
||||
Worker Role = "worker"
|
||||
)
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func aggregateObjErrors(gk schema.GroupKind, name string, allErrs field.ErrorList) error {
|
||||
if len(allErrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return apierrors.NewInvalid(
|
||||
gk,
|
||||
name,
|
||||
allErrs,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,839 +0,0 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
apiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
"sigs.k8s.io/cluster-api/errors"
|
||||
timex "time"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Auth) DeepCopyInto(out *Auth) {
|
||||
*out = *in
|
||||
if in.Port != nil {
|
||||
in, out := &in.Port, &out.Port
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(timex.Duration)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auth.
|
||||
func (in *Auth) DeepCopy() *Auth {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Auth)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Checksum) DeepCopyInto(out *Checksum) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Checksum.
|
||||
func (in *Checksum) DeepCopy() *Checksum {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Checksum)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Component) DeepCopyInto(out *Component) {
|
||||
*out = *in
|
||||
if in.Overrides != nil {
|
||||
in, out := &in.Overrides, &out.Overrides
|
||||
*out = make([]Override, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Component.
|
||||
func (in *Component) DeepCopy() *Component {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Component)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ContainerManager) DeepCopyInto(out *ContainerManager) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerManager.
|
||||
func (in *ContainerManager) DeepCopy() *ContainerManager {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ContainerManager)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InstanceInfo) DeepCopyInto(out *InstanceInfo) {
|
||||
*out = *in
|
||||
if in.Roles != nil {
|
||||
in, out := &in.Roles, &out.Roles
|
||||
*out = make([]Role, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.Auth.DeepCopyInto(&out.Auth)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceInfo.
|
||||
func (in *InstanceInfo) DeepCopy() *InstanceInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InstanceInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKCluster) DeepCopyInto(out *KKCluster) {
|
||||
*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 KKCluster.
|
||||
func (in *KKCluster) DeepCopy() *KKCluster {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKCluster)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KKCluster) 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 *KKClusterList) DeepCopyInto(out *KKClusterList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]KKCluster, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKClusterList.
|
||||
func (in *KKClusterList) DeepCopy() *KKClusterList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKClusterList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KKClusterList) 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 *KKClusterSpec) DeepCopyInto(out *KKClusterSpec) {
|
||||
*out = *in
|
||||
in.Nodes.DeepCopyInto(&out.Nodes)
|
||||
out.ControlPlaneEndpoint = in.ControlPlaneEndpoint
|
||||
if in.ControlPlaneLoadBalancer != nil {
|
||||
in, out := &in.ControlPlaneLoadBalancer, &out.ControlPlaneLoadBalancer
|
||||
*out = new(KKLoadBalancerSpec)
|
||||
**out = **in
|
||||
}
|
||||
if in.Component != nil {
|
||||
in, out := &in.Component, &out.Component
|
||||
*out = new(Component)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.Registry.DeepCopyInto(&out.Registry)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKClusterSpec.
|
||||
func (in *KKClusterSpec) DeepCopy() *KKClusterSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKClusterSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKClusterStatus) DeepCopyInto(out *KKClusterStatus) {
|
||||
*out = *in
|
||||
if in.FailureReason != nil {
|
||||
in, out := &in.FailureReason, &out.FailureReason
|
||||
*out = new(errors.MachineStatusError)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureMessage != nil {
|
||||
in, out := &in.FailureMessage, &out.FailureMessage
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make(apiv1beta1.Conditions, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKClusterStatus.
|
||||
func (in *KKClusterStatus) DeepCopy() *KKClusterStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKClusterStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKClusterTemplate) DeepCopyInto(out *KKClusterTemplate) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKClusterTemplate.
|
||||
func (in *KKClusterTemplate) DeepCopy() *KKClusterTemplate {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKClusterTemplate)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KKClusterTemplate) 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 *KKClusterTemplateList) DeepCopyInto(out *KKClusterTemplateList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]KKClusterTemplate, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKClusterTemplateList.
|
||||
func (in *KKClusterTemplateList) DeepCopy() *KKClusterTemplateList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKClusterTemplateList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KKClusterTemplateList) 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 *KKClusterTemplateResource) DeepCopyInto(out *KKClusterTemplateResource) {
|
||||
*out = *in
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKClusterTemplateResource.
|
||||
func (in *KKClusterTemplateResource) DeepCopy() *KKClusterTemplateResource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKClusterTemplateResource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKClusterTemplateSpec) DeepCopyInto(out *KKClusterTemplateSpec) {
|
||||
*out = *in
|
||||
in.Template.DeepCopyInto(&out.Template)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKClusterTemplateSpec.
|
||||
func (in *KKClusterTemplateSpec) DeepCopy() *KKClusterTemplateSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKClusterTemplateSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKInstance) DeepCopyInto(out *KKInstance) {
|
||||
*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 KKInstance.
|
||||
func (in *KKInstance) DeepCopy() *KKInstance {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKInstance)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KKInstance) 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 *KKInstanceList) DeepCopyInto(out *KKInstanceList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]KKInstance, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKInstanceList.
|
||||
func (in *KKInstanceList) DeepCopy() *KKInstanceList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKInstanceList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KKInstanceList) 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 *KKInstanceSpec) DeepCopyInto(out *KKInstanceSpec) {
|
||||
*out = *in
|
||||
if in.Roles != nil {
|
||||
in, out := &in.Roles, &out.Roles
|
||||
*out = make([]Role, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.Auth.DeepCopyInto(&out.Auth)
|
||||
out.ContainerManager = in.ContainerManager
|
||||
if in.Repository != nil {
|
||||
in, out := &in.Repository, &out.Repository
|
||||
*out = new(Repository)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKInstanceSpec.
|
||||
func (in *KKInstanceSpec) DeepCopy() *KKInstanceSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKInstanceSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKInstanceStatus) DeepCopyInto(out *KKInstanceStatus) {
|
||||
*out = *in
|
||||
if in.NodeRef != nil {
|
||||
in, out := &in.NodeRef, &out.NodeRef
|
||||
*out = new(v1.ObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.NodeInfo != nil {
|
||||
in, out := &in.NodeInfo, &out.NodeInfo
|
||||
*out = new(v1.NodeSystemInfo)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureReason != nil {
|
||||
in, out := &in.FailureReason, &out.FailureReason
|
||||
*out = new(errors.MachineStatusError)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureMessage != nil {
|
||||
in, out := &in.FailureMessage, &out.FailureMessage
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make(apiv1beta1.Conditions, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKInstanceStatus.
|
||||
func (in *KKInstanceStatus) DeepCopy() *KKInstanceStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKInstanceStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKLoadBalancerSpec) DeepCopyInto(out *KKLoadBalancerSpec) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKLoadBalancerSpec.
|
||||
func (in *KKLoadBalancerSpec) DeepCopy() *KKLoadBalancerSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKLoadBalancerSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKMachine) DeepCopyInto(out *KKMachine) {
|
||||
*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 KKMachine.
|
||||
func (in *KKMachine) DeepCopy() *KKMachine {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKMachine)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KKMachine) 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 *KKMachineList) DeepCopyInto(out *KKMachineList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]KKMachine, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKMachineList.
|
||||
func (in *KKMachineList) DeepCopy() *KKMachineList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKMachineList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KKMachineList) 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 *KKMachineSpec) DeepCopyInto(out *KKMachineSpec) {
|
||||
*out = *in
|
||||
if in.ProviderID != nil {
|
||||
in, out := &in.ProviderID, &out.ProviderID
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.InstanceID != nil {
|
||||
in, out := &in.InstanceID, &out.InstanceID
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Roles != nil {
|
||||
in, out := &in.Roles, &out.Roles
|
||||
*out = make([]Role, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.ContainerManager = in.ContainerManager
|
||||
if in.Repository != nil {
|
||||
in, out := &in.Repository, &out.Repository
|
||||
*out = new(Repository)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKMachineSpec.
|
||||
func (in *KKMachineSpec) DeepCopy() *KKMachineSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKMachineSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKMachineStatus) DeepCopyInto(out *KKMachineStatus) {
|
||||
*out = *in
|
||||
if in.Addresses != nil {
|
||||
in, out := &in.Addresses, &out.Addresses
|
||||
*out = make([]apiv1beta1.MachineAddress, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.InstanceState != nil {
|
||||
in, out := &in.InstanceState, &out.InstanceState
|
||||
*out = new(InstanceState)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureReason != nil {
|
||||
in, out := &in.FailureReason, &out.FailureReason
|
||||
*out = new(errors.MachineStatusError)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureMessage != nil {
|
||||
in, out := &in.FailureMessage, &out.FailureMessage
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make(apiv1beta1.Conditions, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKMachineStatus.
|
||||
func (in *KKMachineStatus) DeepCopy() *KKMachineStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKMachineStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKMachineTemplate) DeepCopyInto(out *KKMachineTemplate) {
|
||||
*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 KKMachineTemplate.
|
||||
func (in *KKMachineTemplate) DeepCopy() *KKMachineTemplate {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKMachineTemplate)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KKMachineTemplate) 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 *KKMachineTemplateList) DeepCopyInto(out *KKMachineTemplateList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]KKMachineTemplate, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKMachineTemplateList.
|
||||
func (in *KKMachineTemplateList) DeepCopy() *KKMachineTemplateList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKMachineTemplateList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KKMachineTemplateList) 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 *KKMachineTemplateResource) DeepCopyInto(out *KKMachineTemplateResource) {
|
||||
*out = *in
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKMachineTemplateResource.
|
||||
func (in *KKMachineTemplateResource) DeepCopy() *KKMachineTemplateResource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKMachineTemplateResource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKMachineTemplateSpec) DeepCopyInto(out *KKMachineTemplateSpec) {
|
||||
*out = *in
|
||||
in.Template.DeepCopyInto(&out.Template)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKMachineTemplateSpec.
|
||||
func (in *KKMachineTemplateSpec) DeepCopy() *KKMachineTemplateSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKMachineTemplateSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KKMachineTemplateStatus) DeepCopyInto(out *KKMachineTemplateStatus) {
|
||||
*out = *in
|
||||
if in.Capacity != nil {
|
||||
in, out := &in.Capacity, &out.Capacity
|
||||
*out = make(v1.ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KKMachineTemplateStatus.
|
||||
func (in *KKMachineTemplateStatus) DeepCopy() *KKMachineTemplateStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KKMachineTemplateStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Nodes) DeepCopyInto(out *Nodes) {
|
||||
*out = *in
|
||||
in.Auth.DeepCopyInto(&out.Auth)
|
||||
if in.Instances != nil {
|
||||
in, out := &in.Instances, &out.Instances
|
||||
*out = make([]InstanceInfo, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Nodes.
|
||||
func (in *Nodes) DeepCopy() *Nodes {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Nodes)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Override) DeepCopyInto(out *Override) {
|
||||
*out = *in
|
||||
out.Checksum = in.Checksum
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Override.
|
||||
func (in *Override) DeepCopy() *Override {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Override)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Registry) DeepCopyInto(out *Registry) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.InsecureRegistries != nil {
|
||||
in, out := &in.InsecureRegistries, &out.InsecureRegistries
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.RegistryMirrors != nil {
|
||||
in, out := &in.RegistryMirrors, &out.RegistryMirrors
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.Auth = in.Auth
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Registry.
|
||||
func (in *Registry) DeepCopy() *Registry {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Registry)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Registry) 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 *RegistryAuth) DeepCopyInto(out *RegistryAuth) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryAuth.
|
||||
func (in *RegistryAuth) DeepCopy() *RegistryAuth {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RegistryAuth)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Repository) DeepCopyInto(out *Repository) {
|
||||
*out = *in
|
||||
if in.Packages != nil {
|
||||
in, out := &in.Packages, &out.Packages
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Repository.
|
||||
func (in *Repository) DeepCopy() *Repository {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Repository)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
domain: cluster.x-k8s.io
|
||||
layout:
|
||||
- go.kubebuilder.io/v3
|
||||
plugins:
|
||||
manifests.sdk.operatorframework.io/v2: {}
|
||||
scorecard.sdk.operatorframework.io/v2: {}
|
||||
projectName: cluster-api-bootstrap-provider-kubekey-k3s
|
||||
repo: github.com/kubesphere/kubekey/bootstrap/k3s
|
||||
resources:
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: cluster.x-k8s.io
|
||||
group: bootstrap
|
||||
kind: K3sConfig
|
||||
path: github.com/kubesphere/kubekey/bootstrap/k3s/api/v1beta1
|
||||
version: v1beta1
|
||||
webhooks:
|
||||
defaulting: true
|
||||
validation: true
|
||||
webhookVersion: v1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
domain: cluster.x-k8s.io
|
||||
group: bootstrap
|
||||
kind: K3sConfigTemplate
|
||||
path: github.com/kubesphere/kubekey/bootstrap/k3s/api/v1beta1
|
||||
version: v1beta1
|
||||
webhooks:
|
||||
defaulting: true
|
||||
validation: true
|
||||
webhookVersion: v1
|
||||
version: "3"
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
Copyright 2022.
|
||||
|
||||
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 v1beta1 contains API Schema definitions for the bootstrap v1beta1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=bootstrap.cluster.x-k8s.io
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "bootstrap.cluster.x-k8s.io", Version: "v1beta1"}
|
||||
|
||||
// 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
|
||||
)
|
||||
|
|
@ -1,212 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
// ServerConfiguration defines the desired state of k3s server configuration.
|
||||
type ServerConfiguration struct {
|
||||
// Database is the database configuration.
|
||||
Database Database `json:"database,omitempty"`
|
||||
|
||||
// Listener is the listener configuration.
|
||||
Listener Listener `json:"listener,omitempty"`
|
||||
|
||||
// Networking is the networking configuration.
|
||||
Networking Networking `json:"networking,omitempty"`
|
||||
|
||||
// KubernetesComponents is the kubernetes components configuration.
|
||||
KubernetesComponents KubernetesComponents `json:"kubernetesComponents,omitempty"`
|
||||
|
||||
// KubernetesProcesses is the kubernetes processes configuration.
|
||||
KubernetesProcesses KubernetesProcesses `json:"kubernetesProcesses,omitempty"`
|
||||
|
||||
// Agent is the agent configuration.
|
||||
Agent AgentConfiguration `json:"agent,omitempty"`
|
||||
}
|
||||
|
||||
// AgentConfiguration defines the desired state of k3s agent configuration.
|
||||
type AgentConfiguration struct {
|
||||
// Node defines the k3s agent node configuration.
|
||||
Node AgentNode `json:"node,omitempty"`
|
||||
|
||||
// Runtime defines the k3s agent runtime configuration.
|
||||
Runtime AgentRuntime `json:"runtime,omitempty"`
|
||||
|
||||
// Networking defines the k3s agent networking configuration.
|
||||
Networking AgentNetworking `json:"networking,omitempty"`
|
||||
|
||||
// KubernetesAgentProcesses defines the k3s agent kubernetes processes configuration.
|
||||
KubernetesAgentProcesses KubernetesAgentProcesses `json:"kubernetesAgentProcesses,omitempty"`
|
||||
}
|
||||
|
||||
// Database defines the desired state of k3s database configuration.
|
||||
type Database struct {
|
||||
// DataStoreEndPoint specify etcd, Mysql, Postgres, or Sqlite (default) data source name.
|
||||
DataStoreEndPoint string `json:"dataStoreEndPoint,omitempty"`
|
||||
|
||||
// DataStoreCAFile TLS Certificate Authority file used to secure datastore backend communication.
|
||||
DataStoreCAFile string `json:"dataStoreCAFile,omitempty"`
|
||||
|
||||
// DataStoreCertFile TLS certification file used to secure datastore backend communication.
|
||||
DataStoreCertFile string `json:"dataStoreCertFile,omitempty"`
|
||||
|
||||
// DataStoreKeyFile TLS key file used to secure datastore backend communication.
|
||||
DataStoreKeyFile string `json:"dataStoreKeyFile,omitempty"`
|
||||
|
||||
// ClusterInit initialize a new cluster using embedded Etcd.
|
||||
ClusterInit *bool `json:"clusterInit,omitempty"`
|
||||
}
|
||||
|
||||
// Cluster is the desired state of k3s cluster configuration.
|
||||
type Cluster struct {
|
||||
// Token shared secret used to join a server or agent to a cluster.
|
||||
Token string `json:"token,omitempty"`
|
||||
|
||||
// TokenFile file containing the cluster-secret/token.
|
||||
TokenFile string `json:"tokenFile,omitempty"`
|
||||
|
||||
// Server which server to connect to, used to join a cluster.
|
||||
Server string `json:"server,omitempty"`
|
||||
}
|
||||
|
||||
// Listener defines the desired state of k3s listener configuration.
|
||||
type Listener struct {
|
||||
// BindAddress k3s bind address.
|
||||
BindAddress string `json:"bindAddress,omitempty"`
|
||||
|
||||
// HTTPSListenPort HTTPS listen port.
|
||||
HTTPSListenPort int `json:"httpsListenPort,omitempty"`
|
||||
|
||||
// AdvertiseAddress IP address that apiserver uses to advertise to members of the cluster.
|
||||
AdvertiseAddress string `json:"advertiseAddress,omitempty"`
|
||||
|
||||
// AdvertisePort Port that apiserver uses to advertise to members of the cluster (default: listen-port).
|
||||
AdvertisePort int `json:"advertisePort,omitempty"`
|
||||
|
||||
// TLSSan Add additional hostname or IP as a Subject Alternative Name in the TLS cert.
|
||||
TLSSan string `json:"tlsSan,omitempty"`
|
||||
}
|
||||
|
||||
// Networking defines the desired state of k3s networking configuration.
|
||||
type Networking struct {
|
||||
// ClusterCIDR Network CIDR to use for pod IPs.
|
||||
ClusterCIDR string `json:"clusterCIDR,omitempty"`
|
||||
|
||||
// ServiceCIDR Network CIDR to use for services IPs.
|
||||
ServiceCIDR string `json:"serviceCIDR,omitempty"`
|
||||
|
||||
// ServiceNodePortRange Port range to reserve for services with NodePort visibility.
|
||||
ServiceNodePortRange string `json:"serviceNodePortRange,omitempty"`
|
||||
|
||||
// ClusterDNS cluster IP for coredns service. Should be in your service-cidr range.
|
||||
ClusterDNS string `json:"clusterDNS,omitempty"`
|
||||
|
||||
// ClusterDomain cluster Domain.
|
||||
ClusterDomain string `json:"clusterDomain,omitempty"`
|
||||
|
||||
// FlannelBackend One of ‘none’, ‘vxlan’, ‘ipsec’, ‘host-gw’, or ‘wireguard’. (default: vxlan)
|
||||
FlannelBackend string `json:"flannelBackend,omitempty"`
|
||||
}
|
||||
|
||||
// AgentNode defines the desired state of k3s agent node configuration.
|
||||
type AgentNode struct {
|
||||
// NodeName k3s node name.
|
||||
NodeName string `json:"nodeName,omitempty"`
|
||||
|
||||
// NodeLabels registering and starting kubelet with set of labels.
|
||||
NodeLabels []string `json:"nodeLabels,omitempty"`
|
||||
|
||||
// NodeTaints registering and starting kubelet with set of taints.
|
||||
NodeTaints []string `json:"nodeTaints,omitempty"`
|
||||
|
||||
// SeLinux Enable SELinux in containerd
|
||||
SeLinux bool `json:"seLinux,omitempty"`
|
||||
|
||||
// LBServerPort
|
||||
// Local port for supervisor client load-balancer.
|
||||
// If the supervisor and apiserver are not colocated an additional port 1 less than this port
|
||||
// will also be used for the apiserver client load-balancer. (default: 6444)
|
||||
LBServerPort int `json:"lbServerPort,omitempty"`
|
||||
|
||||
// DataDir Folder to hold state.
|
||||
DataDir string `json:"dataDir,omitempty"`
|
||||
}
|
||||
|
||||
// AgentRuntime defines the desired state of k3s agent runtime configuration.
|
||||
type AgentRuntime struct {
|
||||
// ContainerRuntimeEndpoint Disable embedded containerd and use alternative CRI implementation.
|
||||
ContainerRuntimeEndpoint string `json:"containerRuntimeEndpoint,omitempty"`
|
||||
|
||||
// PauseImage Customized pause image for containerd or Docker sandbox.
|
||||
PauseImage string `json:"pauseImage,omitempty"`
|
||||
|
||||
// PrivateRegistry Path to a private registry configuration file.
|
||||
PrivateRegistry string `json:"privateRegistry,omitempty"`
|
||||
}
|
||||
|
||||
// AgentNetworking defines the desired state of k3s agent networking configuration.
|
||||
type AgentNetworking struct {
|
||||
// NodeIP IP address to advertise for node.
|
||||
NodeIP string `json:"nodeIP,omitempty"`
|
||||
|
||||
// NodeExternalIP External IP address to advertise for node.
|
||||
NodeExternalIP string `json:"nodeExternalIP,omitempty"`
|
||||
|
||||
// ResolvConf Path to Kubelet resolv.conf file.
|
||||
ResolvConf string `json:"resolvConf,omitempty"`
|
||||
}
|
||||
|
||||
// KubernetesComponents defines the desired state of k3s kubernetes components configuration.
|
||||
type KubernetesComponents struct {
|
||||
// Disable do not deploy packaged components and delete any deployed components
|
||||
// (valid items: coredns, servicelb, traefik,local-storage, metrics-server).
|
||||
Disable string `json:"disable,omitempty"`
|
||||
|
||||
// DisableKubeProxy disable running kube-proxy.
|
||||
DisableKubeProxy bool `json:"disableKubeProxy,omitempty"`
|
||||
|
||||
// DisableNetworkPolicy disable k3s default network policy controller.
|
||||
DisableNetworkPolicy bool `json:"disableNetworkPolicy,omitempty"`
|
||||
|
||||
// DisableHelmController disable Helm controller.
|
||||
DisableHelmController bool `json:"disableHelmController,omitempty"`
|
||||
}
|
||||
|
||||
// KubernetesProcesses defines the desired state of kubernetes processes configuration.
|
||||
type KubernetesProcesses struct {
|
||||
// KubeAPIServerArgs is a customized flag for kube-apiserver process
|
||||
// +optional
|
||||
KubeAPIServerArgs []string `json:"kubeAPIServerArg,omitempty"`
|
||||
|
||||
// KubeControllerManagerArgs is a customized flag for kube-controller-manager process
|
||||
// +optional
|
||||
KubeControllerManagerArgs []string `json:"kubeControllerManagerArgs,omitempty"`
|
||||
|
||||
// KubeSchedulerArgs is a customized flag for kube-scheduler process
|
||||
// +optional
|
||||
KubeSchedulerArgs []string `json:"kubeSchedulerArgs,omitempty"`
|
||||
}
|
||||
|
||||
// KubernetesAgentProcesses defines the desired state of kubernetes agent processes configuration.
|
||||
type KubernetesAgentProcesses struct {
|
||||
// KubeletArgs Customized flag for kubelet process
|
||||
// +optional
|
||||
KubeletArgs []string `json:"kubeletArgs,omitempty"`
|
||||
|
||||
// KubeProxyArgs Customized flag for kube-proxy process
|
||||
// +optional
|
||||
KubeProxyArgs []string `json:"kubeProxyArgs,omitempty"`
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
Copyright 2022.
|
||||
|
||||
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 v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
|
||||
)
|
||||
|
||||
// K3sConfigSpec defines the desired state of K3sConfig
|
||||
type K3sConfigSpec struct {
|
||||
// Files specifies extra files to be passed to user_data upon creation.
|
||||
// +optional
|
||||
Files []bootstrapv1.File `json:"files,omitempty"`
|
||||
|
||||
// Cluster defines the k3s cluster Options.
|
||||
Cluster *Cluster `json:"cluster,omitempty"`
|
||||
|
||||
// ServerConfiguration defines the k3s server configuration.
|
||||
// +optional
|
||||
ServerConfiguration *ServerConfiguration `json:"serverConfiguration,omitempty"`
|
||||
|
||||
// AgentConfiguration defines the k3s agent configuration.
|
||||
// +optional
|
||||
AgentConfiguration *AgentConfiguration `json:"agentConfiguration,omitempty"`
|
||||
|
||||
// PreK3sCommands specifies extra commands to run before k3s setup runs
|
||||
// +optional
|
||||
PreK3sCommands []string `json:"preK3sCommands,omitempty"`
|
||||
|
||||
// PostK3sCommands specifies extra commands to run after k3s setup runs
|
||||
// +optional
|
||||
PostK3sCommands []string `json:"postK3sCommands,omitempty"`
|
||||
|
||||
// Version specifies the k3s version
|
||||
// +optional
|
||||
Version string `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
// K3sConfigStatus defines the observed state of K3sConfig
|
||||
type K3sConfigStatus struct {
|
||||
// Ready indicates the BootstrapData field is ready to be consumed
|
||||
Ready bool `json:"ready,omitempty"`
|
||||
|
||||
BootstrapData []byte `json:"bootstrapData,omitempty"`
|
||||
|
||||
// DataSecretName is the name of the secret that stores the bootstrap data script.
|
||||
// +optional
|
||||
DataSecretName *string `json:"dataSecretName,omitempty"`
|
||||
|
||||
// FailureReason will be set on non-retryable errors
|
||||
// +optional
|
||||
FailureReason string `json:"failureReason,omitempty"`
|
||||
|
||||
// FailureMessage will be set on non-retryable errors
|
||||
// +optional
|
||||
FailureMessage string `json:"failureMessage,omitempty"`
|
||||
|
||||
// ObservedGeneration is the latest generation observed by the controller.
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
// Conditions defines current service state of the K3sConfig.
|
||||
// +optional
|
||||
Conditions clusterv1.Conditions `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=k3sconfigs,scope=Namespaced,categories=cluster-api
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels['cluster\\.x-k8s\\.io/cluster-name']",description="Cluster"
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of K3sConfig"
|
||||
|
||||
// K3sConfig is the Schema for the k3sConfigs API
|
||||
type K3sConfig struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec K3sConfigSpec `json:"spec,omitempty"`
|
||||
Status K3sConfigStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GetConditions returns the set of conditions for this object.
|
||||
func (c *K3sConfig) GetConditions() clusterv1.Conditions {
|
||||
return c.Status.Conditions
|
||||
}
|
||||
|
||||
// SetConditions sets the conditions on this object.
|
||||
func (c *K3sConfig) SetConditions(conditions clusterv1.Conditions) {
|
||||
c.Status.Conditions = conditions
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// K3sConfigList contains a list of K3sConfig
|
||||
type K3sConfigList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []K3sConfig `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&K3sConfig{}, &K3sConfigList{})
|
||||
}
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
var (
|
||||
conflictingFileSourceMsg = "only one of content or contentFrom may be specified for a single file"
|
||||
missingSecretNameMsg = "secret file source must specify non-empty secret name"
|
||||
missingSecretKeyMsg = "secret file source must specify non-empty secret key"
|
||||
pathConflictMsg = "path property must be unique among all files"
|
||||
)
|
||||
|
||||
func (c *K3sConfig) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(c).
|
||||
Complete()
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/mutate-bootstrap-cluster-x-k8s-io-v1beta1-k3sconfig,mutating=true,failurePolicy=fail,sideEffects=None,groups=bootstrap.cluster.x-k8s.io,resources=k3sconfigs,versions=v1beta1,name=default.k3sconfig.bootstrap.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
|
||||
|
||||
var _ webhook.Defaulter = &K3sConfig{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type
|
||||
func (c *K3sConfig) Default() {
|
||||
DefaultK3sConfigSpec(&c.Spec)
|
||||
}
|
||||
|
||||
// DefaultK3sConfigSpec defaults a K3sConfigSpec.
|
||||
func DefaultK3sConfigSpec(c *K3sConfigSpec) {
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/validate-bootstrap-cluster-x-k8s-io-v1beta1-k3sconfig,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=bootstrap.cluster.x-k8s.io,resources=k3sconfigs,versions=v1beta1,name=validation.k3sconfig.bootstrap.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
|
||||
|
||||
var _ webhook.Validator = &K3sConfig{}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (c *K3sConfig) ValidateCreate() error {
|
||||
return c.Spec.validate(c.Name)
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (c *K3sConfig) ValidateUpdate(old runtime.Object) error {
|
||||
return c.Spec.validate(c.Name)
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
|
||||
func (c *K3sConfig) ValidateDelete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *K3sConfigSpec) validate(name string) error {
|
||||
allErrs := c.Validate(field.NewPath("spec"))
|
||||
|
||||
if len(allErrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return apierrors.NewInvalid(GroupVersion.WithKind("K3sConfig").GroupKind(), name, allErrs)
|
||||
}
|
||||
|
||||
// Validate ensures the K3sConfigSpec is valid.
|
||||
func (c *K3sConfigSpec) Validate(pathPrefix *field.Path) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
|
||||
allErrs = append(allErrs, c.validateFiles(pathPrefix)...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func (c *K3sConfigSpec) validateFiles(pathPrefix *field.Path) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
|
||||
knownPaths := map[string]struct{}{}
|
||||
|
||||
for i := range c.Files {
|
||||
file := c.Files[i]
|
||||
if file.Content != "" && file.ContentFrom != nil {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(
|
||||
pathPrefix.Child("files").Index(i),
|
||||
file,
|
||||
conflictingFileSourceMsg,
|
||||
),
|
||||
)
|
||||
}
|
||||
// n.b.: if we ever add types besides Secret as a ContentFrom
|
||||
// Source, we must add webhook validation here for one of the
|
||||
// sources being non-nil.
|
||||
if file.ContentFrom != nil {
|
||||
if file.ContentFrom.Secret.Name == "" {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Required(
|
||||
pathPrefix.Child("files").Index(i).Child("contentFrom", "secret", "name"),
|
||||
missingSecretNameMsg,
|
||||
),
|
||||
)
|
||||
}
|
||||
if file.ContentFrom.Secret.Key == "" {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Required(
|
||||
pathPrefix.Child("files").Index(i).Child("contentFrom", "secret", "key"),
|
||||
missingSecretKeyMsg,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
_, conflict := knownPaths[file.Path]
|
||||
if conflict {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(
|
||||
pathPrefix.Child("files").Index(i).Child("path"),
|
||||
file,
|
||||
pathConflictMsg,
|
||||
),
|
||||
)
|
||||
}
|
||||
knownPaths[file.Path] = struct{}{}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// K3sConfigTemplateSpec defines the desired state of K3sConfigTemplate
|
||||
type K3sConfigTemplateSpec struct {
|
||||
Template K3sConfigTemplateResource `json:"template"`
|
||||
}
|
||||
|
||||
// K3sConfigTemplateResource defines the Template structure
|
||||
type K3sConfigTemplateResource struct {
|
||||
Spec K3sConfigSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=k3sconfigtemplates,scope=Namespaced,categories=cluster-api
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of K3sConfigTemplate"
|
||||
|
||||
// K3sConfigTemplate is the Schema for the k3sconfigtemplates API
|
||||
type K3sConfigTemplate struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec K3sConfigTemplateSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// K3sConfigTemplateList contains a list of K3sConfigTemplate
|
||||
type K3sConfigTemplateList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []K3sConfigTemplate `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&K3sConfigTemplate{}, &K3sConfigTemplateList{})
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
func (r *K3sConfigTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(r).
|
||||
Complete()
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/mutate-bootstrap-cluster-x-k8s-io-v1beta1-k3sconfigtemplate,mutating=true,failurePolicy=fail,groups=bootstrap.cluster.x-k8s.io,resources=k3sconfigtemplates,versions=v1beta1,name=default.k3sconfigtemplate.bootstrap.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
|
||||
|
||||
var _ webhook.Defaulter = &K3sConfigTemplate{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type
|
||||
func (r *K3sConfigTemplate) Default() {
|
||||
DefaultK3sConfigSpec(&r.Spec.Template.Spec)
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:verbs=create;update,path=/validate-bootstrap-cluster-x-k8s-io-v1beta1-k3sconfigtemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=bootstrap.cluster.x-k8s.io,resources=k3sconfigtemplates,versions=v1beta1,name=validation.k3sconfigtemplate.bootstrap.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
|
||||
|
||||
var _ webhook.Validator = &K3sConfigTemplate{}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (r *K3sConfigTemplate) ValidateCreate() error {
|
||||
return r.Spec.validate(r.Name)
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (r *K3sConfigTemplate) ValidateUpdate(old runtime.Object) error {
|
||||
return r.Spec.validate(r.Name)
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
|
||||
func (r *K3sConfigTemplate) ValidateDelete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *K3sConfigTemplateSpec) validate(name string) error {
|
||||
var allErrs field.ErrorList
|
||||
|
||||
allErrs = append(allErrs, r.Template.Spec.Validate(field.NewPath("spec", "template", "spec"))...)
|
||||
|
||||
if len(allErrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return apierrors.NewInvalid(GroupVersion.WithKind("K3sConfigTemplate").GroupKind(), name, allErrs)
|
||||
}
|
||||
|
|
@ -1,486 +0,0 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2022 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 v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
cluster_apiapiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
apiv1beta1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AgentConfiguration) DeepCopyInto(out *AgentConfiguration) {
|
||||
*out = *in
|
||||
in.Node.DeepCopyInto(&out.Node)
|
||||
out.Runtime = in.Runtime
|
||||
out.Networking = in.Networking
|
||||
in.KubernetesAgentProcesses.DeepCopyInto(&out.KubernetesAgentProcesses)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentConfiguration.
|
||||
func (in *AgentConfiguration) DeepCopy() *AgentConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AgentConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AgentNetworking) DeepCopyInto(out *AgentNetworking) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentNetworking.
|
||||
func (in *AgentNetworking) DeepCopy() *AgentNetworking {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AgentNetworking)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AgentNode) DeepCopyInto(out *AgentNode) {
|
||||
*out = *in
|
||||
if in.NodeLabels != nil {
|
||||
in, out := &in.NodeLabels, &out.NodeLabels
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.NodeTaints != nil {
|
||||
in, out := &in.NodeTaints, &out.NodeTaints
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentNode.
|
||||
func (in *AgentNode) DeepCopy() *AgentNode {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AgentNode)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AgentRuntime) DeepCopyInto(out *AgentRuntime) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentRuntime.
|
||||
func (in *AgentRuntime) DeepCopy() *AgentRuntime {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AgentRuntime)
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Database) DeepCopyInto(out *Database) {
|
||||
*out = *in
|
||||
if in.ClusterInit != nil {
|
||||
in, out := &in.ClusterInit, &out.ClusterInit
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Database.
|
||||
func (in *Database) DeepCopy() *Database {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Database)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *K3sConfig) DeepCopyInto(out *K3sConfig) {
|
||||
*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 K3sConfig.
|
||||
func (in *K3sConfig) DeepCopy() *K3sConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(K3sConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *K3sConfig) 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 *K3sConfigList) DeepCopyInto(out *K3sConfigList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]K3sConfig, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new K3sConfigList.
|
||||
func (in *K3sConfigList) DeepCopy() *K3sConfigList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(K3sConfigList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *K3sConfigList) 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 *K3sConfigSpec) DeepCopyInto(out *K3sConfigSpec) {
|
||||
*out = *in
|
||||
if in.Files != nil {
|
||||
in, out := &in.Files, &out.Files
|
||||
*out = make([]apiv1beta1.File, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Cluster != nil {
|
||||
in, out := &in.Cluster, &out.Cluster
|
||||
*out = new(Cluster)
|
||||
**out = **in
|
||||
}
|
||||
if in.ServerConfiguration != nil {
|
||||
in, out := &in.ServerConfiguration, &out.ServerConfiguration
|
||||
*out = new(ServerConfiguration)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.AgentConfiguration != nil {
|
||||
in, out := &in.AgentConfiguration, &out.AgentConfiguration
|
||||
*out = new(AgentConfiguration)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.PreK3sCommands != nil {
|
||||
in, out := &in.PreK3sCommands, &out.PreK3sCommands
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.PostK3sCommands != nil {
|
||||
in, out := &in.PostK3sCommands, &out.PostK3sCommands
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new K3sConfigSpec.
|
||||
func (in *K3sConfigSpec) DeepCopy() *K3sConfigSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(K3sConfigSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *K3sConfigStatus) DeepCopyInto(out *K3sConfigStatus) {
|
||||
*out = *in
|
||||
if in.BootstrapData != nil {
|
||||
in, out := &in.BootstrapData, &out.BootstrapData
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DataSecretName != nil {
|
||||
in, out := &in.DataSecretName, &out.DataSecretName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make(cluster_apiapiv1beta1.Conditions, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new K3sConfigStatus.
|
||||
func (in *K3sConfigStatus) DeepCopy() *K3sConfigStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(K3sConfigStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *K3sConfigTemplate) DeepCopyInto(out *K3sConfigTemplate) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new K3sConfigTemplate.
|
||||
func (in *K3sConfigTemplate) DeepCopy() *K3sConfigTemplate {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(K3sConfigTemplate)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *K3sConfigTemplate) 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 *K3sConfigTemplateList) DeepCopyInto(out *K3sConfigTemplateList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]K3sConfigTemplate, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new K3sConfigTemplateList.
|
||||
func (in *K3sConfigTemplateList) DeepCopy() *K3sConfigTemplateList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(K3sConfigTemplateList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *K3sConfigTemplateList) 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 *K3sConfigTemplateResource) DeepCopyInto(out *K3sConfigTemplateResource) {
|
||||
*out = *in
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new K3sConfigTemplateResource.
|
||||
func (in *K3sConfigTemplateResource) DeepCopy() *K3sConfigTemplateResource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(K3sConfigTemplateResource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *K3sConfigTemplateSpec) DeepCopyInto(out *K3sConfigTemplateSpec) {
|
||||
*out = *in
|
||||
in.Template.DeepCopyInto(&out.Template)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new K3sConfigTemplateSpec.
|
||||
func (in *K3sConfigTemplateSpec) DeepCopy() *K3sConfigTemplateSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(K3sConfigTemplateSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubernetesAgentProcesses) DeepCopyInto(out *KubernetesAgentProcesses) {
|
||||
*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)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesAgentProcesses.
|
||||
func (in *KubernetesAgentProcesses) DeepCopy() *KubernetesAgentProcesses {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubernetesAgentProcesses)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubernetesComponents) DeepCopyInto(out *KubernetesComponents) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesComponents.
|
||||
func (in *KubernetesComponents) DeepCopy() *KubernetesComponents {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubernetesComponents)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubernetesProcesses) DeepCopyInto(out *KubernetesProcesses) {
|
||||
*out = *in
|
||||
if in.KubeAPIServerArgs != nil {
|
||||
in, out := &in.KubeAPIServerArgs, &out.KubeAPIServerArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.KubeControllerManagerArgs != nil {
|
||||
in, out := &in.KubeControllerManagerArgs, &out.KubeControllerManagerArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.KubeSchedulerArgs != nil {
|
||||
in, out := &in.KubeSchedulerArgs, &out.KubeSchedulerArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesProcesses.
|
||||
func (in *KubernetesProcesses) DeepCopy() *KubernetesProcesses {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubernetesProcesses)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Listener) DeepCopyInto(out *Listener) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Listener.
|
||||
func (in *Listener) DeepCopy() *Listener {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Listener)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Networking) DeepCopyInto(out *Networking) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Networking.
|
||||
func (in *Networking) DeepCopy() *Networking {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Networking)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ServerConfiguration) DeepCopyInto(out *ServerConfiguration) {
|
||||
*out = *in
|
||||
in.Database.DeepCopyInto(&out.Database)
|
||||
out.Listener = in.Listener
|
||||
out.Networking = in.Networking
|
||||
out.KubernetesComponents = in.KubernetesComponents
|
||||
in.KubernetesProcesses.DeepCopyInto(&out.KubernetesProcesses)
|
||||
in.Agent.DeepCopyInto(&out.Agent)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerConfiguration.
|
||||
func (in *ServerConfiguration) DeepCopy() *ServerConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ServerConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
# The following manifests contain a self-signed issuer CR and a certificate CR.
|
||||
# More document can be found at https://docs.cert-manager.io
|
||||
# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for breaking changes
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: selfsigned-issuer
|
||||
namespace: system
|
||||
spec:
|
||||
selfSigned: {}
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
|
||||
namespace: system
|
||||
spec:
|
||||
# $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize
|
||||
dnsNames:
|
||||
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc
|
||||
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local
|
||||
issuerRef:
|
||||
kind: Issuer
|
||||
name: selfsigned-issuer
|
||||
secretName: $(SERVICE_NAME)-cert # this secret will not be prefixed, since it's not managed by kustomize
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
resources:
|
||||
- certificate.yaml
|
||||
|
||||
configurations:
|
||||
- kustomizeconfig.yaml
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# This configuration is for teaching kustomize how to update name ref and var substitution
|
||||
nameReference:
|
||||
- kind: Issuer
|
||||
group: cert-manager.io
|
||||
fieldSpecs:
|
||||
- kind: Certificate
|
||||
group: cert-manager.io
|
||||
path: spec/issuerRef/name
|
||||
|
||||
varReference:
|
||||
- kind: Certificate
|
||||
group: cert-manager.io
|
||||
path: spec/commonName
|
||||
- kind: Certificate
|
||||
group: cert-manager.io
|
||||
path: spec/dnsNames
|
||||
- kind: Certificate
|
||||
group: cert-manager.io
|
||||
path: spec/secretName
|
||||
|
|
@ -1,496 +0,0 @@
|
|||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.9.1
|
||||
creationTimestamp: null
|
||||
name: k3sconfigs.bootstrap.cluster.x-k8s.io
|
||||
spec:
|
||||
group: bootstrap.cluster.x-k8s.io
|
||||
names:
|
||||
categories:
|
||||
- cluster-api
|
||||
kind: K3sConfig
|
||||
listKind: K3sConfigList
|
||||
plural: k3sconfigs
|
||||
singular: k3sconfig
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- description: Cluster
|
||||
jsonPath: .metadata.labels['cluster\.x-k8s\.io/cluster-name']
|
||||
name: Cluster
|
||||
type: string
|
||||
- description: Time duration since creation of K3sConfig
|
||||
jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: K3sConfig is the Schema for the k3sConfigs API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: K3sConfigSpec defines the desired state of K3sConfig
|
||||
properties:
|
||||
agentConfiguration:
|
||||
description: AgentConfiguration defines the k3s agent configuration.
|
||||
properties:
|
||||
kubernetesAgentProcesses:
|
||||
description: KubernetesAgentProcesses defines the k3s agent kubernetes
|
||||
processes configuration.
|
||||
properties:
|
||||
kubeProxyArgs:
|
||||
description: KubeProxyArgs Customized flag for kube-proxy
|
||||
process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kubeletArgs:
|
||||
description: KubeletArgs Customized flag for kubelet process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
networking:
|
||||
description: Networking defines the k3s agent networking configuration.
|
||||
properties:
|
||||
nodeExternalIP:
|
||||
description: NodeExternalIP External IP address to advertise
|
||||
for node.
|
||||
type: string
|
||||
nodeIP:
|
||||
description: NodeIP IP address to advertise for node.
|
||||
type: string
|
||||
resolvConf:
|
||||
description: ResolvConf Path to Kubelet resolv.conf file.
|
||||
type: string
|
||||
type: object
|
||||
node:
|
||||
description: Node defines the k3s agent node configuration.
|
||||
properties:
|
||||
dataDir:
|
||||
description: DataDir Folder to hold state.
|
||||
type: string
|
||||
lbServerPort:
|
||||
description: 'LBServerPort Local port for supervisor client
|
||||
load-balancer. If the supervisor and apiserver are not colocated
|
||||
an additional port 1 less than this port will also be used
|
||||
for the apiserver client load-balancer. (default: 6444)'
|
||||
type: integer
|
||||
nodeLabels:
|
||||
description: NodeLabels registering and starting kubelet with
|
||||
set of labels.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
nodeName:
|
||||
description: NodeName k3s node name.
|
||||
type: string
|
||||
nodeTaints:
|
||||
description: NodeTaints registering and starting kubelet with
|
||||
set of taints.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
seLinux:
|
||||
description: SeLinux Enable SELinux in containerd
|
||||
type: boolean
|
||||
type: object
|
||||
runtime:
|
||||
description: Runtime defines the k3s agent runtime configuration.
|
||||
properties:
|
||||
containerRuntimeEndpoint:
|
||||
description: ContainerRuntimeEndpoint Disable embedded containerd
|
||||
and use alternative CRI implementation.
|
||||
type: string
|
||||
pauseImage:
|
||||
description: PauseImage Customized pause image for containerd
|
||||
or Docker sandbox.
|
||||
type: string
|
||||
privateRegistry:
|
||||
description: PrivateRegistry Path to a private registry configuration
|
||||
file.
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
cluster:
|
||||
description: Cluster defines the k3s cluster Options.
|
||||
properties:
|
||||
server:
|
||||
description: Server which server to connect to, used to join a
|
||||
cluster.
|
||||
type: string
|
||||
token:
|
||||
description: Token shared secret used to join a server or agent
|
||||
to a cluster.
|
||||
type: string
|
||||
tokenFile:
|
||||
description: TokenFile file containing the cluster-secret/token.
|
||||
type: string
|
||||
type: object
|
||||
files:
|
||||
description: Files specifies extra files to be passed to user_data
|
||||
upon creation.
|
||||
items:
|
||||
description: File defines the input for generating write_files in
|
||||
cloud-init.
|
||||
properties:
|
||||
append:
|
||||
description: Append specifies whether to append Content to existing
|
||||
file if Path exists.
|
||||
type: boolean
|
||||
content:
|
||||
description: Content is the actual content of the file.
|
||||
type: string
|
||||
contentFrom:
|
||||
description: ContentFrom is a referenced source of content to
|
||||
populate the file.
|
||||
properties:
|
||||
secret:
|
||||
description: Secret represents a secret that should populate
|
||||
this file.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the key in the secret's data map
|
||||
for this value.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the secret in the KubeadmBootstrapConfig's
|
||||
namespace to use.
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- secret
|
||||
type: object
|
||||
encoding:
|
||||
description: Encoding specifies the encoding of the file contents.
|
||||
enum:
|
||||
- base64
|
||||
- gzip
|
||||
- gzip+base64
|
||||
type: string
|
||||
owner:
|
||||
description: Owner specifies the ownership of the file, e.g.
|
||||
"root:root".
|
||||
type: string
|
||||
path:
|
||||
description: Path specifies the full path on disk where to store
|
||||
the file.
|
||||
type: string
|
||||
permissions:
|
||||
description: Permissions specifies the permissions to assign
|
||||
to the file, e.g. "0640".
|
||||
type: string
|
||||
required:
|
||||
- path
|
||||
type: object
|
||||
type: array
|
||||
postK3sCommands:
|
||||
description: PostK3sCommands specifies extra commands to run after
|
||||
k3s setup runs
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
preK3sCommands:
|
||||
description: PreK3sCommands specifies extra commands to run before
|
||||
k3s setup runs
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
serverConfiguration:
|
||||
description: ServerConfiguration defines the k3s server configuration.
|
||||
properties:
|
||||
agent:
|
||||
description: Agent is the agent configuration.
|
||||
properties:
|
||||
kubernetesAgentProcesses:
|
||||
description: KubernetesAgentProcesses defines the k3s agent
|
||||
kubernetes processes configuration.
|
||||
properties:
|
||||
kubeProxyArgs:
|
||||
description: KubeProxyArgs Customized flag for kube-proxy
|
||||
process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kubeletArgs:
|
||||
description: KubeletArgs Customized flag for kubelet process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
networking:
|
||||
description: Networking defines the k3s agent networking configuration.
|
||||
properties:
|
||||
nodeExternalIP:
|
||||
description: NodeExternalIP External IP address to advertise
|
||||
for node.
|
||||
type: string
|
||||
nodeIP:
|
||||
description: NodeIP IP address to advertise for node.
|
||||
type: string
|
||||
resolvConf:
|
||||
description: ResolvConf Path to Kubelet resolv.conf file.
|
||||
type: string
|
||||
type: object
|
||||
node:
|
||||
description: Node defines the k3s agent node configuration.
|
||||
properties:
|
||||
dataDir:
|
||||
description: DataDir Folder to hold state.
|
||||
type: string
|
||||
lbServerPort:
|
||||
description: 'LBServerPort Local port for supervisor client
|
||||
load-balancer. If the supervisor and apiserver are not
|
||||
colocated an additional port 1 less than this port will
|
||||
also be used for the apiserver client load-balancer.
|
||||
(default: 6444)'
|
||||
type: integer
|
||||
nodeLabels:
|
||||
description: NodeLabels registering and starting kubelet
|
||||
with set of labels.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
nodeName:
|
||||
description: NodeName k3s node name.
|
||||
type: string
|
||||
nodeTaints:
|
||||
description: NodeTaints registering and starting kubelet
|
||||
with set of taints.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
seLinux:
|
||||
description: SeLinux Enable SELinux in containerd
|
||||
type: boolean
|
||||
type: object
|
||||
runtime:
|
||||
description: Runtime defines the k3s agent runtime configuration.
|
||||
properties:
|
||||
containerRuntimeEndpoint:
|
||||
description: ContainerRuntimeEndpoint Disable embedded
|
||||
containerd and use alternative CRI implementation.
|
||||
type: string
|
||||
pauseImage:
|
||||
description: PauseImage Customized pause image for containerd
|
||||
or Docker sandbox.
|
||||
type: string
|
||||
privateRegistry:
|
||||
description: PrivateRegistry Path to a private registry
|
||||
configuration file.
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
database:
|
||||
description: Database is the database configuration.
|
||||
properties:
|
||||
clusterInit:
|
||||
description: ClusterInit initialize a new cluster using embedded
|
||||
Etcd.
|
||||
type: boolean
|
||||
dataStoreCAFile:
|
||||
description: DataStoreCAFile TLS Certificate Authority file
|
||||
used to secure datastore backend communication.
|
||||
type: string
|
||||
dataStoreCertFile:
|
||||
description: DataStoreCertFile TLS certification file used
|
||||
to secure datastore backend communication.
|
||||
type: string
|
||||
dataStoreEndPoint:
|
||||
description: DataStoreEndPoint specify etcd, Mysql, Postgres,
|
||||
or Sqlite (default) data source name.
|
||||
type: string
|
||||
dataStoreKeyFile:
|
||||
description: DataStoreKeyFile TLS key file used to secure
|
||||
datastore backend communication.
|
||||
type: string
|
||||
type: object
|
||||
kubernetesComponents:
|
||||
description: KubernetesComponents is the kubernetes components
|
||||
configuration.
|
||||
properties:
|
||||
disable:
|
||||
description: 'Disable do not deploy packaged components and
|
||||
delete any deployed components (valid items: coredns, servicelb,
|
||||
traefik,local-storage, metrics-server).'
|
||||
type: string
|
||||
disableHelmController:
|
||||
description: DisableHelmController disable Helm controller.
|
||||
type: boolean
|
||||
disableKubeProxy:
|
||||
description: DisableKubeProxy disable running kube-proxy.
|
||||
type: boolean
|
||||
disableNetworkPolicy:
|
||||
description: DisableNetworkPolicy disable k3s default network
|
||||
policy controller.
|
||||
type: boolean
|
||||
type: object
|
||||
kubernetesProcesses:
|
||||
description: KubernetesProcesses is the kubernetes processes configuration.
|
||||
properties:
|
||||
kubeAPIServerArg:
|
||||
description: KubeAPIServerArgs is a customized flag for kube-apiserver
|
||||
process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kubeControllerManagerArgs:
|
||||
description: KubeControllerManagerArgs is a customized flag
|
||||
for kube-controller-manager process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kubeSchedulerArgs:
|
||||
description: KubeSchedulerArgs is a customized flag for kube-scheduler
|
||||
process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
listener:
|
||||
description: Listener is the listener configuration.
|
||||
properties:
|
||||
advertiseAddress:
|
||||
description: AdvertiseAddress IP address that apiserver uses
|
||||
to advertise to members of the cluster.
|
||||
type: string
|
||||
advertisePort:
|
||||
description: 'AdvertisePort Port that apiserver uses to advertise
|
||||
to members of the cluster (default: listen-port).'
|
||||
type: integer
|
||||
bindAddress:
|
||||
description: BindAddress k3s bind address.
|
||||
type: string
|
||||
httpsListenPort:
|
||||
description: HTTPSListenPort HTTPS listen port.
|
||||
type: integer
|
||||
tlsSan:
|
||||
description: TLSSan Add additional hostname or IP as a Subject
|
||||
Alternative Name in the TLS cert.
|
||||
type: string
|
||||
type: object
|
||||
networking:
|
||||
description: Networking is the networking configuration.
|
||||
properties:
|
||||
clusterCIDR:
|
||||
description: ClusterCIDR Network CIDR to use for pod IPs.
|
||||
type: string
|
||||
clusterDNS:
|
||||
description: ClusterDNS cluster IP for coredns service. Should
|
||||
be in your service-cidr range.
|
||||
type: string
|
||||
clusterDomain:
|
||||
description: ClusterDomain cluster Domain.
|
||||
type: string
|
||||
flannelBackend:
|
||||
description: 'FlannelBackend One of ‘none’, ‘vxlan’, ‘ipsec’,
|
||||
‘host-gw’, or ‘wireguard’. (default: vxlan)'
|
||||
type: string
|
||||
serviceCIDR:
|
||||
description: ServiceCIDR Network CIDR to use for services
|
||||
IPs.
|
||||
type: string
|
||||
serviceNodePortRange:
|
||||
description: ServiceNodePortRange Port range to reserve for
|
||||
services with NodePort visibility.
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
version:
|
||||
description: Version specifies the k3s version
|
||||
type: string
|
||||
type: object
|
||||
status:
|
||||
description: K3sConfigStatus defines the observed state of K3sConfig
|
||||
properties:
|
||||
bootstrapData:
|
||||
format: byte
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions defines current service state of the K3sConfig.
|
||||
items:
|
||||
description: Condition defines an observation of a Cluster API resource
|
||||
operational state.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: Last time the condition transitioned from one status
|
||||
to another. This should be when the underlying condition changed.
|
||||
If that is not known, then using the time when the API field
|
||||
changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A human readable message indicating details about
|
||||
the transition. This field may be empty.
|
||||
type: string
|
||||
reason:
|
||||
description: The reason for the condition's last transition
|
||||
in CamelCase. The specific API may choose whether or not this
|
||||
field is considered a guaranteed API. This field may not be
|
||||
empty.
|
||||
type: string
|
||||
severity:
|
||||
description: Severity provides an explicit classification of
|
||||
Reason code, so the users or machines can immediately understand
|
||||
the current situation and act accordingly. The Severity field
|
||||
MUST be set only when Status=False.
|
||||
type: string
|
||||
status:
|
||||
description: Status of the condition, one of True, False, Unknown.
|
||||
type: string
|
||||
type:
|
||||
description: Type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
dataSecretName:
|
||||
description: DataSecretName is the name of the secret that stores
|
||||
the bootstrap data script.
|
||||
type: string
|
||||
failureMessage:
|
||||
description: FailureMessage will be set on non-retryable errors
|
||||
type: string
|
||||
failureReason:
|
||||
description: FailureReason will be set on non-retryable errors
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: ObservedGeneration is the latest generation observed
|
||||
by the controller.
|
||||
format: int64
|
||||
type: integer
|
||||
ready:
|
||||
description: Ready indicates the BootstrapData field is ready to be
|
||||
consumed
|
||||
type: boolean
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
|
@ -1,445 +0,0 @@
|
|||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.9.1
|
||||
creationTimestamp: null
|
||||
name: k3sconfigtemplates.bootstrap.cluster.x-k8s.io
|
||||
spec:
|
||||
group: bootstrap.cluster.x-k8s.io
|
||||
names:
|
||||
categories:
|
||||
- cluster-api
|
||||
kind: K3sConfigTemplate
|
||||
listKind: K3sConfigTemplateList
|
||||
plural: k3sconfigtemplates
|
||||
singular: k3sconfigtemplate
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- description: Time duration since creation of K3sConfigTemplate
|
||||
jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: K3sConfigTemplate is the Schema for the k3sconfigtemplates API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: K3sConfigTemplateSpec defines the desired state of K3sConfigTemplate
|
||||
properties:
|
||||
template:
|
||||
description: K3sConfigTemplateResource defines the Template structure
|
||||
properties:
|
||||
spec:
|
||||
description: K3sConfigSpec defines the desired state of K3sConfig
|
||||
properties:
|
||||
agentConfiguration:
|
||||
description: AgentConfiguration defines the k3s agent configuration.
|
||||
properties:
|
||||
kubernetesAgentProcesses:
|
||||
description: KubernetesAgentProcesses defines the k3s
|
||||
agent kubernetes processes configuration.
|
||||
properties:
|
||||
kubeProxyArgs:
|
||||
description: KubeProxyArgs Customized flag for kube-proxy
|
||||
process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kubeletArgs:
|
||||
description: KubeletArgs Customized flag for kubelet
|
||||
process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
networking:
|
||||
description: Networking defines the k3s agent networking
|
||||
configuration.
|
||||
properties:
|
||||
nodeExternalIP:
|
||||
description: NodeExternalIP External IP address to
|
||||
advertise for node.
|
||||
type: string
|
||||
nodeIP:
|
||||
description: NodeIP IP address to advertise for node.
|
||||
type: string
|
||||
resolvConf:
|
||||
description: ResolvConf Path to Kubelet resolv.conf
|
||||
file.
|
||||
type: string
|
||||
type: object
|
||||
node:
|
||||
description: Node defines the k3s agent node configuration.
|
||||
properties:
|
||||
dataDir:
|
||||
description: DataDir Folder to hold state.
|
||||
type: string
|
||||
lbServerPort:
|
||||
description: 'LBServerPort Local port for supervisor
|
||||
client load-balancer. If the supervisor and apiserver
|
||||
are not colocated an additional port 1 less than
|
||||
this port will also be used for the apiserver client
|
||||
load-balancer. (default: 6444)'
|
||||
type: integer
|
||||
nodeLabels:
|
||||
description: NodeLabels registering and starting kubelet
|
||||
with set of labels.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
nodeName:
|
||||
description: NodeName k3s node name.
|
||||
type: string
|
||||
nodeTaints:
|
||||
description: NodeTaints registering and starting kubelet
|
||||
with set of taints.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
seLinux:
|
||||
description: SeLinux Enable SELinux in containerd
|
||||
type: boolean
|
||||
type: object
|
||||
runtime:
|
||||
description: Runtime defines the k3s agent runtime configuration.
|
||||
properties:
|
||||
containerRuntimeEndpoint:
|
||||
description: ContainerRuntimeEndpoint Disable embedded
|
||||
containerd and use alternative CRI implementation.
|
||||
type: string
|
||||
pauseImage:
|
||||
description: PauseImage Customized pause image for
|
||||
containerd or Docker sandbox.
|
||||
type: string
|
||||
privateRegistry:
|
||||
description: PrivateRegistry Path to a private registry
|
||||
configuration file.
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
cluster:
|
||||
description: Cluster defines the k3s cluster Options.
|
||||
properties:
|
||||
server:
|
||||
description: Server which server to connect to, used to
|
||||
join a cluster.
|
||||
type: string
|
||||
token:
|
||||
description: Token shared secret used to join a server
|
||||
or agent to a cluster.
|
||||
type: string
|
||||
tokenFile:
|
||||
description: TokenFile file containing the cluster-secret/token.
|
||||
type: string
|
||||
type: object
|
||||
files:
|
||||
description: Files specifies extra files to be passed to user_data
|
||||
upon creation.
|
||||
items:
|
||||
description: File defines the input for generating write_files
|
||||
in cloud-init.
|
||||
properties:
|
||||
append:
|
||||
description: Append specifies whether to append Content
|
||||
to existing file if Path exists.
|
||||
type: boolean
|
||||
content:
|
||||
description: Content is the actual content of the file.
|
||||
type: string
|
||||
contentFrom:
|
||||
description: ContentFrom is a referenced source of content
|
||||
to populate the file.
|
||||
properties:
|
||||
secret:
|
||||
description: Secret represents a secret that should
|
||||
populate this file.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the key in the secret's
|
||||
data map for this value.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the secret in the KubeadmBootstrapConfig's
|
||||
namespace to use.
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- secret
|
||||
type: object
|
||||
encoding:
|
||||
description: Encoding specifies the encoding of the
|
||||
file contents.
|
||||
enum:
|
||||
- base64
|
||||
- gzip
|
||||
- gzip+base64
|
||||
type: string
|
||||
owner:
|
||||
description: Owner specifies the ownership of the file,
|
||||
e.g. "root:root".
|
||||
type: string
|
||||
path:
|
||||
description: Path specifies the full path on disk where
|
||||
to store the file.
|
||||
type: string
|
||||
permissions:
|
||||
description: Permissions specifies the permissions to
|
||||
assign to the file, e.g. "0640".
|
||||
type: string
|
||||
required:
|
||||
- path
|
||||
type: object
|
||||
type: array
|
||||
postK3sCommands:
|
||||
description: PostK3sCommands specifies extra commands to run
|
||||
after k3s setup runs
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
preK3sCommands:
|
||||
description: PreK3sCommands specifies extra commands to run
|
||||
before k3s setup runs
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
serverConfiguration:
|
||||
description: ServerConfiguration defines the k3s server configuration.
|
||||
properties:
|
||||
agent:
|
||||
description: Agent is the agent configuration.
|
||||
properties:
|
||||
kubernetesAgentProcesses:
|
||||
description: KubernetesAgentProcesses defines the
|
||||
k3s agent kubernetes processes configuration.
|
||||
properties:
|
||||
kubeProxyArgs:
|
||||
description: KubeProxyArgs Customized flag for
|
||||
kube-proxy process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kubeletArgs:
|
||||
description: KubeletArgs Customized flag for kubelet
|
||||
process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
networking:
|
||||
description: Networking defines the k3s agent networking
|
||||
configuration.
|
||||
properties:
|
||||
nodeExternalIP:
|
||||
description: NodeExternalIP External IP address
|
||||
to advertise for node.
|
||||
type: string
|
||||
nodeIP:
|
||||
description: NodeIP IP address to advertise for
|
||||
node.
|
||||
type: string
|
||||
resolvConf:
|
||||
description: ResolvConf Path to Kubelet resolv.conf
|
||||
file.
|
||||
type: string
|
||||
type: object
|
||||
node:
|
||||
description: Node defines the k3s agent node configuration.
|
||||
properties:
|
||||
dataDir:
|
||||
description: DataDir Folder to hold state.
|
||||
type: string
|
||||
lbServerPort:
|
||||
description: 'LBServerPort Local port for supervisor
|
||||
client load-balancer. If the supervisor and
|
||||
apiserver are not colocated an additional port
|
||||
1 less than this port will also be used for
|
||||
the apiserver client load-balancer. (default:
|
||||
6444)'
|
||||
type: integer
|
||||
nodeLabels:
|
||||
description: NodeLabels registering and starting
|
||||
kubelet with set of labels.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
nodeName:
|
||||
description: NodeName k3s node name.
|
||||
type: string
|
||||
nodeTaints:
|
||||
description: NodeTaints registering and starting
|
||||
kubelet with set of taints.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
seLinux:
|
||||
description: SeLinux Enable SELinux in containerd
|
||||
type: boolean
|
||||
type: object
|
||||
runtime:
|
||||
description: Runtime defines the k3s agent runtime
|
||||
configuration.
|
||||
properties:
|
||||
containerRuntimeEndpoint:
|
||||
description: ContainerRuntimeEndpoint Disable
|
||||
embedded containerd and use alternative CRI
|
||||
implementation.
|
||||
type: string
|
||||
pauseImage:
|
||||
description: PauseImage Customized pause image
|
||||
for containerd or Docker sandbox.
|
||||
type: string
|
||||
privateRegistry:
|
||||
description: PrivateRegistry Path to a private
|
||||
registry configuration file.
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
database:
|
||||
description: Database is the database configuration.
|
||||
properties:
|
||||
clusterInit:
|
||||
description: ClusterInit initialize a new cluster
|
||||
using embedded Etcd.
|
||||
type: boolean
|
||||
dataStoreCAFile:
|
||||
description: DataStoreCAFile TLS Certificate Authority
|
||||
file used to secure datastore backend communication.
|
||||
type: string
|
||||
dataStoreCertFile:
|
||||
description: DataStoreCertFile TLS certification file
|
||||
used to secure datastore backend communication.
|
||||
type: string
|
||||
dataStoreEndPoint:
|
||||
description: DataStoreEndPoint specify etcd, Mysql,
|
||||
Postgres, or Sqlite (default) data source name.
|
||||
type: string
|
||||
dataStoreKeyFile:
|
||||
description: DataStoreKeyFile TLS key file used to
|
||||
secure datastore backend communication.
|
||||
type: string
|
||||
type: object
|
||||
kubernetesComponents:
|
||||
description: KubernetesComponents is the kubernetes components
|
||||
configuration.
|
||||
properties:
|
||||
disable:
|
||||
description: 'Disable do not deploy packaged components
|
||||
and delete any deployed components (valid items:
|
||||
coredns, servicelb, traefik,local-storage, metrics-server).'
|
||||
type: string
|
||||
disableHelmController:
|
||||
description: DisableHelmController disable Helm controller.
|
||||
type: boolean
|
||||
disableKubeProxy:
|
||||
description: DisableKubeProxy disable running kube-proxy.
|
||||
type: boolean
|
||||
disableNetworkPolicy:
|
||||
description: DisableNetworkPolicy disable k3s default
|
||||
network policy controller.
|
||||
type: boolean
|
||||
type: object
|
||||
kubernetesProcesses:
|
||||
description: KubernetesProcesses is the kubernetes processes
|
||||
configuration.
|
||||
properties:
|
||||
kubeAPIServerArg:
|
||||
description: KubeAPIServerArgs is a customized flag
|
||||
for kube-apiserver process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kubeControllerManagerArgs:
|
||||
description: KubeControllerManagerArgs is a customized
|
||||
flag for kube-controller-manager process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kubeSchedulerArgs:
|
||||
description: KubeSchedulerArgs is a customized flag
|
||||
for kube-scheduler process
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
listener:
|
||||
description: Listener is the listener configuration.
|
||||
properties:
|
||||
advertiseAddress:
|
||||
description: AdvertiseAddress IP address that apiserver
|
||||
uses to advertise to members of the cluster.
|
||||
type: string
|
||||
advertisePort:
|
||||
description: 'AdvertisePort Port that apiserver uses
|
||||
to advertise to members of the cluster (default:
|
||||
listen-port).'
|
||||
type: integer
|
||||
bindAddress:
|
||||
description: BindAddress k3s bind address.
|
||||
type: string
|
||||
httpsListenPort:
|
||||
description: HTTPSListenPort HTTPS listen port.
|
||||
type: integer
|
||||
tlsSan:
|
||||
description: TLSSan Add additional hostname or IP
|
||||
as a Subject Alternative Name in the TLS cert.
|
||||
type: string
|
||||
type: object
|
||||
networking:
|
||||
description: Networking is the networking configuration.
|
||||
properties:
|
||||
clusterCIDR:
|
||||
description: ClusterCIDR Network CIDR to use for pod
|
||||
IPs.
|
||||
type: string
|
||||
clusterDNS:
|
||||
description: ClusterDNS cluster IP for coredns service.
|
||||
Should be in your service-cidr range.
|
||||
type: string
|
||||
clusterDomain:
|
||||
description: ClusterDomain cluster Domain.
|
||||
type: string
|
||||
flannelBackend:
|
||||
description: 'FlannelBackend One of ‘none’, ‘vxlan’,
|
||||
‘ipsec’, ‘host-gw’, or ‘wireguard’. (default: vxlan)'
|
||||
type: string
|
||||
serviceCIDR:
|
||||
description: ServiceCIDR Network CIDR to use for services
|
||||
IPs.
|
||||
type: string
|
||||
serviceNodePortRange:
|
||||
description: ServiceNodePortRange Port range to reserve
|
||||
for services with NodePort visibility.
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
version:
|
||||
description: Version specifies the k3s version
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources: {}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
# This kustomization.yaml is not intended to be run by itself,
|
||||
# since it depends on service name and namespace that are out of this kustomize package.
|
||||
# It should be run by config/default
|
||||
resources:
|
||||
- bases/bootstrap.cluster.x-k8s.io_k3sconfigs.yaml
|
||||
- bases/bootstrap.cluster.x-k8s.io_k3sconfigtemplates.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizeresource
|
||||
|
||||
commonLabels:
|
||||
cluster.x-k8s.io/v1beta1: v1beta1
|
||||
|
||||
patchesStrategicMerge:
|
||||
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
|
||||
# patches here are for enabling the conversion webhook for each CRD
|
||||
- patches/webhook_in_k3sconfigs.yaml
|
||||
- patches/webhook_in_k3sconfigtemplates.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizewebhookpatch
|
||||
|
||||
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
|
||||
# patches here are for enabling the CA injection for each CRD
|
||||
- patches/cainjection_in_k3sconfigs.yaml
|
||||
- patches/cainjection_in_k3sconfigtemplates.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
|
||||
|
||||
# the following config is for teaching kustomize how to do kustomization for CRDs.
|
||||
configurations:
|
||||
- kustomizeconfig.yaml
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# This file is for teaching kustomize how to substitute name and namespace reference in CRD
|
||||
nameReference:
|
||||
- kind: Service
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- kind: CustomResourceDefinition
|
||||
version: v1
|
||||
group: apiextensions.k8s.io
|
||||
path: spec/conversion/webhook/clientConfig/service/name
|
||||
|
||||
namespace:
|
||||
- kind: CustomResourceDefinition
|
||||
version: v1
|
||||
group: apiextensions.k8s.io
|
||||
path: spec/conversion/webhook/clientConfig/service/namespace
|
||||
create: false
|
||||
|
||||
varReference:
|
||||
- path: metadata/annotations
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
# The following patch adds a directive for certmanager to inject CA into the CRD
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
|
||||
name: k3sconfigs.bootstrap.cluster.x-k8s.io
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
# The following patch adds a directive for certmanager to inject CA into the CRD
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
|
||||
name: k3sconfigtemplates.bootstrap.cluster.x-k8s.io
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# The following patch enables a conversion webhook for the CRD
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: k3sconfigs.bootstrap.cluster.x-k8s.io
|
||||
spec:
|
||||
conversion:
|
||||
strategy: Webhook
|
||||
webhook:
|
||||
conversionReviewVersions: ["v1", "v1beta1"]
|
||||
clientConfig:
|
||||
# this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank,
|
||||
# but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager)
|
||||
caBundle: Cg==
|
||||
service:
|
||||
namespace: system
|
||||
name: webhook-service
|
||||
path: /convert
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# The following patch enables a conversion webhook for the CRD
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: k3sconfigtemplates.bootstrap.cluster.x-k8s.io
|
||||
spec:
|
||||
conversion:
|
||||
strategy: Webhook
|
||||
webhook:
|
||||
conversionReviewVersions: ["v1", "v1beta1"]
|
||||
clientConfig:
|
||||
# this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank,
|
||||
# but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager)
|
||||
caBundle: Cg==
|
||||
service:
|
||||
namespace: system
|
||||
name: webhook-service
|
||||
path: /convert
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
namePrefix: capkk-k3s-bootstrap-
|
||||
namespace: capkk-k3s-bootstrap-system
|
||||
|
||||
commonLabels:
|
||||
cluster.x-k8s.io/provider: "bootstrap-k3s"
|
||||
|
||||
resources:
|
||||
- namespace.yaml
|
||||
|
||||
bases:
|
||||
- ../rbac
|
||||
- ../manager
|
||||
- ../crd
|
||||
- ../certmanager
|
||||
- ../webhook
|
||||
|
||||
patchesStrategicMerge:
|
||||
# Provide customizable hook for make targets.
|
||||
- manager_image_patch.yaml
|
||||
- manager_pull_policy.yaml
|
||||
# Enable webhook.
|
||||
- manager_webhook_patch.yaml
|
||||
# Inject certificate in the webhook definition.
|
||||
- webhookcainjection_patch.yaml
|
||||
|
||||
configurations:
|
||||
- kustomizeconfig.yaml
|
||||
vars:
|
||||
- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
|
||||
objref:
|
||||
kind: Certificate
|
||||
group: cert-manager.io
|
||||
version: v1
|
||||
name: serving-cert # this name should match the one in certificate.yaml
|
||||
fieldref:
|
||||
fieldpath: metadata.namespace
|
||||
- name: CERTIFICATE_NAME
|
||||
objref:
|
||||
kind: Certificate
|
||||
group: cert-manager.io
|
||||
version: v1
|
||||
name: serving-cert # this name should match the one in certificate.yaml
|
||||
- name: SERVICE_NAMESPACE # namespace of the service
|
||||
objref:
|
||||
kind: Service
|
||||
version: v1
|
||||
name: webhook-service
|
||||
fieldref:
|
||||
fieldpath: metadata.namespace
|
||||
- name: SERVICE_NAME
|
||||
objref:
|
||||
kind: Service
|
||||
version: v1
|
||||
name: webhook-service
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# This configuration is for teaching kustomize how to update name ref and var substitution
|
||||
varReference:
|
||||
- kind: Deployment
|
||||
path: spec/template/spec/volumes/secret/secretName
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: controller-manager
|
||||
namespace: system
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: docker.io/kubespheredev/k3s-bootstrap-controller:main
|
||||
name: manager
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: controller-manager
|
||||
namespace: system
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: manager
|
||||
imagePullPolicy: Always
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: controller-manager
|
||||
namespace: system
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: manager
|
||||
ports:
|
||||
- containerPort: 9443
|
||||
name: webhook-server
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- mountPath: /tmp/k8s-webhook-server/serving-certs
|
||||
name: cert
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: cert
|
||||
secret:
|
||||
secretName: $(SERVICE_NAME)-cert
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
name: system
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: MutatingWebhookConfiguration
|
||||
metadata:
|
||||
name: mutating-webhook-configuration
|
||||
annotations:
|
||||
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
|
||||
---
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
name: validating-webhook-configuration
|
||||
annotations:
|
||||
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
resources:
|
||||
- manager.yaml
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: controller-manager
|
||||
namespace: system
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
control-plane: controller-manager
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- /manager
|
||||
args:
|
||||
- "--leader-elect"
|
||||
- "--metrics-bind-addr=localhost:8080"
|
||||
image: controller:latest
|
||||
name: manager
|
||||
ports:
|
||||
- containerPort: 9440
|
||||
name: healthz
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: healthz
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: healthz
|
||||
terminationGracePeriodSeconds: 10
|
||||
serviceAccountName: manager
|
||||
tolerations:
|
||||
- effect: NoSchedule
|
||||
key: node-role.kubernetes.io/master
|
||||
- effect: NoSchedule
|
||||
key: node-role.kubernetes.io/control-plane
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
resources:
|
||||
- service_account.yaml
|
||||
- role.yaml
|
||||
- role_binding.yaml
|
||||
- leader_election_role.yaml
|
||||
- leader_election_role_binding.yaml
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
# permissions to do leader election.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: leader-election-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
resources:
|
||||
- leases
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- patch
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: leader-election-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: leader-election-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: manager
|
||||
namespace: system
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: manager-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- events
|
||||
- secrets
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- bootstrap.cluster.x-k8s.io
|
||||
resources:
|
||||
- k3sconfigs
|
||||
- k3sconfigs/finalizers
|
||||
- k3sconfigs/status
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- cluster.x-k8s.io
|
||||
resources:
|
||||
- clusters
|
||||
- clusters/status
|
||||
- machinepools
|
||||
- machinepools/status
|
||||
- machines
|
||||
- machines/status
|
||||
- machinesets
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: manager-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: manager-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: manager
|
||||
namespace: system
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: manager
|
||||
namespace: system
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
|
||||
kind: K3sConfig
|
||||
metadata:
|
||||
name: k3sconfig-sample
|
||||
spec:
|
||||
# TODO(user): Add fields here
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
|
||||
kind: K3sConfigTemplate
|
||||
metadata:
|
||||
name: k3sconfigtemplate-sample
|
||||
spec:
|
||||
# TODO(user): Add fields here
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
## Append samples you want in your CSV to this file as resources ##
|
||||
resources:
|
||||
- bootstrap_v1beta1_k3sconfig.yaml
|
||||
- bootstrap_v1beta1_k3sconfigtemplate.yaml
|
||||
#+kubebuilder:scaffold:manifestskustomizesamples
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
apiVersion: scorecard.operatorframework.io/v1alpha3
|
||||
kind: Configuration
|
||||
metadata:
|
||||
name: config
|
||||
stages:
|
||||
- parallel: true
|
||||
tests: []
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
resources:
|
||||
- bases/config.yaml
|
||||
patchesJson6902:
|
||||
- path: patches/basic.config.yaml
|
||||
target:
|
||||
group: scorecard.operatorframework.io
|
||||
version: v1alpha3
|
||||
kind: Configuration
|
||||
name: config
|
||||
- path: patches/olm.config.yaml
|
||||
target:
|
||||
group: scorecard.operatorframework.io
|
||||
version: v1alpha3
|
||||
kind: Configuration
|
||||
name: config
|
||||
#+kubebuilder:scaffold:patchesJson6902
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
- op: add
|
||||
path: /stages/0/tests/-
|
||||
value:
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- basic-check-spec
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
labels:
|
||||
suite: basic
|
||||
test: basic-check-spec-test
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
- op: add
|
||||
path: /stages/0/tests/-
|
||||
value:
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- olm-bundle-validation
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
labels:
|
||||
suite: olm
|
||||
test: olm-bundle-validation-test
|
||||
- op: add
|
||||
path: /stages/0/tests/-
|
||||
value:
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- olm-crds-have-validation
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
labels:
|
||||
suite: olm
|
||||
test: olm-crds-have-validation-test
|
||||
- op: add
|
||||
path: /stages/0/tests/-
|
||||
value:
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- olm-crds-have-resources
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
labels:
|
||||
suite: olm
|
||||
test: olm-crds-have-resources-test
|
||||
- op: add
|
||||
path: /stages/0/tests/-
|
||||
value:
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- olm-spec-descriptors
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
labels:
|
||||
suite: olm
|
||||
test: olm-spec-descriptors-test
|
||||
- op: add
|
||||
path: /stages/0/tests/-
|
||||
value:
|
||||
entrypoint:
|
||||
- scorecard-test
|
||||
- olm-status-descriptors
|
||||
image: quay.io/operator-framework/scorecard-test:v1.22.2
|
||||
labels:
|
||||
suite: olm
|
||||
test: olm-status-descriptors-test
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
resources:
|
||||
- manifests.yaml
|
||||
- service.yaml
|
||||
|
||||
configurations:
|
||||
- kustomizeconfig.yaml
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
# the following config is for teaching kustomize where to look at when substituting vars.
|
||||
# It requires kustomize v2.1.0 or newer to work properly.
|
||||
nameReference:
|
||||
- kind: Service
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- kind: MutatingWebhookConfiguration
|
||||
group: admissionregistration.k8s.io
|
||||
path: webhooks/clientConfig/service/name
|
||||
- kind: ValidatingWebhookConfiguration
|
||||
group: admissionregistration.k8s.io
|
||||
path: webhooks/clientConfig/service/name
|
||||
|
||||
namespace:
|
||||
- kind: MutatingWebhookConfiguration
|
||||
group: admissionregistration.k8s.io
|
||||
path: webhooks/clientConfig/service/namespace
|
||||
create: true
|
||||
- kind: ValidatingWebhookConfiguration
|
||||
group: admissionregistration.k8s.io
|
||||
path: webhooks/clientConfig/service/namespace
|
||||
create: true
|
||||
|
||||
varReference:
|
||||
- path: metadata/annotations
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
---
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: MutatingWebhookConfiguration
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: mutating-webhook-configuration
|
||||
webhooks:
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /mutate-bootstrap-cluster-x-k8s-io-v1beta1-k3sconfig
|
||||
failurePolicy: Fail
|
||||
name: default.k3sconfig.bootstrap.cluster.x-k8s.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- bootstrap.cluster.x-k8s.io
|
||||
apiVersions:
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- k3sconfigs
|
||||
sideEffects: None
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /mutate-bootstrap-cluster-x-k8s-io-v1beta1-k3sconfigtemplate
|
||||
failurePolicy: Fail
|
||||
name: default.k3sconfigtemplate.bootstrap.cluster.x-k8s.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- bootstrap.cluster.x-k8s.io
|
||||
apiVersions:
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- k3sconfigtemplates
|
||||
sideEffects: None
|
||||
---
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: validating-webhook-configuration
|
||||
webhooks:
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /validate-bootstrap-cluster-x-k8s-io-v1beta1-k3sconfig
|
||||
failurePolicy: Fail
|
||||
matchPolicy: Equivalent
|
||||
name: validation.k3sconfig.bootstrap.cluster.x-k8s.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- bootstrap.cluster.x-k8s.io
|
||||
apiVersions:
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- k3sconfigs
|
||||
sideEffects: None
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /validate-bootstrap-cluster-x-k8s-io-v1beta1-k3sconfigtemplate
|
||||
failurePolicy: Fail
|
||||
matchPolicy: Equivalent
|
||||
name: validation.k3sconfigtemplate.bootstrap.cluster.x-k8s.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- bootstrap.cluster.x-k8s.io
|
||||
apiVersions:
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- k3sconfigtemplates
|
||||
sideEffects: None
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
spec:
|
||||
ports:
|
||||
- port: 443
|
||||
protocol: TCP
|
||||
targetPort: 9443
|
||||
selector:
|
||||
control-plane: controller-manager
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 controllers contains k3s config controllers.
|
||||
package controllers
|
||||
|
|
@ -1,794 +0,0 @@
|
|||
/*
|
||||
Copyright 2022.
|
||||
|
||||
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 controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
kerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
bootstraputil "k8s.io/cluster-bootstrap/token/util"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/pointer"
|
||||
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
|
||||
bsutil "sigs.k8s.io/cluster-api/bootstrap/util"
|
||||
expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
|
||||
"sigs.k8s.io/cluster-api/feature"
|
||||
"sigs.k8s.io/cluster-api/util"
|
||||
"sigs.k8s.io/cluster-api/util/annotations"
|
||||
"sigs.k8s.io/cluster-api/util/conditions"
|
||||
"sigs.k8s.io/cluster-api/util/patch"
|
||||
"sigs.k8s.io/cluster-api/util/predicates"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/source"
|
||||
|
||||
infrabootstrapv1 "github.com/kubesphere/kubekey/v3/bootstrap/k3s/api/v1beta1"
|
||||
"github.com/kubesphere/kubekey/v3/bootstrap/k3s/pkg/cloudinit"
|
||||
"github.com/kubesphere/kubekey/v3/bootstrap/k3s/pkg/locking"
|
||||
k3stypes "github.com/kubesphere/kubekey/v3/bootstrap/k3s/pkg/types"
|
||||
kklog "github.com/kubesphere/kubekey/v3/util/log"
|
||||
"github.com/kubesphere/kubekey/v3/util/secret"
|
||||
)
|
||||
|
||||
// InitLocker is a lock that is used around kubeadm init.
|
||||
type InitLocker interface {
|
||||
Lock(ctx context.Context, cluster *clusterv1.Cluster, machine *clusterv1.Machine) bool
|
||||
Unlock(ctx context.Context, cluster *clusterv1.Cluster) bool
|
||||
}
|
||||
|
||||
// +kubebuilder:rbac:groups=bootstrap.cluster.x-k8s.io,resources=k3sconfigs;k3sconfigs/status;k3sconfigs/finalizers,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters;clusters/status;machinesets;machines;machines/status;machinepools;machinepools/status,verbs=get;list;watch
|
||||
// +kubebuilder:rbac:groups="",resources=secrets;events;configmaps,verbs=get;list;watch;create;update;patch;delete
|
||||
|
||||
// K3sConfigReconciler reconciles a K3sConfig object
|
||||
type K3sConfigReconciler struct {
|
||||
client.Client
|
||||
K3sInitLock InitLocker
|
||||
|
||||
// WatchFilterValue is the label value used to filter events prior to reconciliation.
|
||||
WatchFilterValue string
|
||||
}
|
||||
|
||||
// Scope is a scoped struct used during reconciliation.
|
||||
type Scope struct {
|
||||
logr.Logger
|
||||
Config *infrabootstrapv1.K3sConfig
|
||||
ConfigOwner *bsutil.ConfigOwner
|
||||
Cluster *clusterv1.Cluster
|
||||
}
|
||||
|
||||
// SetupWithManager sets up the controller with the Manager.
|
||||
func (r *K3sConfigReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error {
|
||||
if r.K3sInitLock == nil {
|
||||
r.K3sInitLock = locking.NewControlPlaneInitMutex(mgr.GetClient())
|
||||
}
|
||||
|
||||
b := ctrl.NewControllerManagedBy(mgr).
|
||||
For(&infrabootstrapv1.K3sConfig{}).
|
||||
WithOptions(options).
|
||||
Watches(
|
||||
&source.Kind{Type: &clusterv1.Machine{}},
|
||||
handler.EnqueueRequestsFromMapFunc(r.MachineToBootstrapMapFunc),
|
||||
).WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(ctrl.LoggerFrom(ctx), r.WatchFilterValue))
|
||||
|
||||
if feature.Gates.Enabled(feature.MachinePool) {
|
||||
b = b.Watches(
|
||||
&source.Kind{Type: &expv1.MachinePool{}},
|
||||
handler.EnqueueRequestsFromMapFunc(r.MachinePoolToBootstrapMapFunc),
|
||||
).WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(ctrl.LoggerFrom(ctx), r.WatchFilterValue))
|
||||
}
|
||||
|
||||
c, err := b.Build(r)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed setting up with a controller manager")
|
||||
}
|
||||
|
||||
err = c.Watch(
|
||||
&source.Kind{Type: &clusterv1.Cluster{}},
|
||||
handler.EnqueueRequestsFromMapFunc(r.ClusterToK3sConfigs),
|
||||
predicates.All(ctrl.LoggerFrom(ctx),
|
||||
predicates.ClusterUnpausedAndInfrastructureReady(ctrl.LoggerFrom(ctx)),
|
||||
predicates.ResourceHasFilterLabel(ctrl.LoggerFrom(ctx), r.WatchFilterValue),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed adding Watch for Clusters to controller manager")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reconcile handles K3sConfig events.
|
||||
func (r *K3sConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Result, retErr error) {
|
||||
log := ctrl.LoggerFrom(ctx)
|
||||
|
||||
// Lookup the kubeadm config
|
||||
config := &infrabootstrapv1.K3sConfig{}
|
||||
if err := r.Client.Get(ctx, req.NamespacedName, config); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
log.Error(err, "Failed to get config")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// AddOwners adds the owners of K3sConfig as k/v pairs to the logger.
|
||||
// Specifically, it will add K3sControlPlane, MachineSet and MachineDeployment.
|
||||
ctx, log, err := kklog.AddOwners(ctx, r.Client, config)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// Look up the owner of this k3s config if there is one
|
||||
configOwner, err := bsutil.GetConfigOwner(ctx, r.Client, config)
|
||||
if apierrors.IsNotFound(err) {
|
||||
// Could not find the owner yet, this is not an error and will rereconcile when the owner gets set.
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
if err != nil {
|
||||
log.Error(err, "Failed to get owner")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
if configOwner == nil {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
log = log.WithValues(configOwner.GetKind(), klog.KRef(configOwner.GetNamespace(), configOwner.GetName()), "resourceVersion", configOwner.GetResourceVersion())
|
||||
|
||||
log = log.WithValues("Cluster", klog.KRef(configOwner.GetNamespace(), configOwner.ClusterName()))
|
||||
ctx = ctrl.LoggerInto(ctx, log)
|
||||
|
||||
// Lookup the cluster the config owner is associated with
|
||||
cluster, err := util.GetClusterByName(ctx, r.Client, configOwner.GetNamespace(), configOwner.ClusterName())
|
||||
if err != nil {
|
||||
if errors.Cause(err) == util.ErrNoCluster {
|
||||
log.Info(fmt.Sprintf("%s does not belong to a cluster yet, waiting until it's part of a cluster", configOwner.GetKind()))
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
if apierrors.IsNotFound(err) {
|
||||
log.Info("Cluster does not exist yet, waiting until it is created")
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
log.Error(err, "Could not get cluster with metadata")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
if annotations.IsPaused(cluster, config) {
|
||||
log.Info("Reconciliation is paused for this object")
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
scope := &Scope{
|
||||
Logger: log,
|
||||
Config: config,
|
||||
ConfigOwner: configOwner,
|
||||
Cluster: cluster,
|
||||
}
|
||||
|
||||
// Initialize the patch helper.
|
||||
patchHelper, err := patch.NewHelper(config, r.Client)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// Attempt to Patch the K3sConfig object and status after each reconciliation if no error occurs.
|
||||
defer func() {
|
||||
// always update the readyCondition; the summary is represented using the "1 of x completed" notation.
|
||||
conditions.SetSummary(config,
|
||||
conditions.WithConditions(
|
||||
bootstrapv1.DataSecretAvailableCondition,
|
||||
bootstrapv1.CertificatesAvailableCondition,
|
||||
),
|
||||
)
|
||||
// Patch ObservedGeneration only if the reconciliation completed successfully
|
||||
var patchOpts []patch.Option
|
||||
if retErr == nil {
|
||||
patchOpts = append(patchOpts, patch.WithStatusObservedGeneration{})
|
||||
}
|
||||
if err := patchHelper.Patch(ctx, config, patchOpts...); err != nil {
|
||||
log.Error(retErr, "Failed to patch config")
|
||||
if retErr == nil {
|
||||
retErr = err
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
switch {
|
||||
// Wait for the infrastructure to be ready.
|
||||
case !cluster.Status.InfrastructureReady:
|
||||
log.Info("Cluster infrastructure is not ready, waiting")
|
||||
conditions.MarkFalse(config, bootstrapv1.DataSecretAvailableCondition, bootstrapv1.WaitingForClusterInfrastructureReason, clusterv1.ConditionSeverityInfo, "")
|
||||
return ctrl.Result{}, nil
|
||||
// Reconcile status for machines that already have a secret reference, but our status isn't up-to-date.
|
||||
// This case solves the pivoting scenario (or a backup restore) which doesn't preserve the status subresource on objects.
|
||||
case configOwner.DataSecretName() != nil && (!config.Status.Ready || config.Status.DataSecretName == nil):
|
||||
config.Status.Ready = true
|
||||
config.Status.DataSecretName = configOwner.DataSecretName()
|
||||
conditions.MarkTrue(config, bootstrapv1.DataSecretAvailableCondition)
|
||||
return ctrl.Result{}, nil
|
||||
// Status is ready means a config has been generated.
|
||||
case config.Status.Ready:
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// Note: can't use IsFalse here because we need to handle the absence of the condition as well as false.
|
||||
if !conditions.IsTrue(cluster, clusterv1.ControlPlaneInitializedCondition) {
|
||||
return r.handleClusterNotInitialized(ctx, scope)
|
||||
}
|
||||
|
||||
// Every other case it's a join scenario
|
||||
// Nb. in this case ClusterConfiguration and InitConfiguration should not be defined by users, but in case of misconfigurations, CABPK3s simply ignore them
|
||||
|
||||
// Unlock any locks that might have been set during init process
|
||||
r.K3sInitLock.Unlock(ctx, cluster)
|
||||
|
||||
// if the .spec.cluster is missing, create a default one
|
||||
if config.Spec.Cluster == nil {
|
||||
log.Info("Creating default .spec.cluster")
|
||||
config.Spec.Cluster = &infrabootstrapv1.Cluster{}
|
||||
}
|
||||
|
||||
// it's a control plane join
|
||||
if configOwner.IsControlPlaneMachine() {
|
||||
return r.joinControlplane(ctx, scope)
|
||||
}
|
||||
|
||||
// It's a worker join
|
||||
return r.joinWorker(ctx, scope)
|
||||
}
|
||||
|
||||
func (r *K3sConfigReconciler) handleClusterNotInitialized(ctx context.Context, scope *Scope) (_ ctrl.Result, retErr error) {
|
||||
// initialize the DataSecretAvailableCondition if missing.
|
||||
// this is required in order to avoid the condition's LastTransitionTime to flicker in case of errors surfacing
|
||||
// using the DataSecretGeneratedFailedReason
|
||||
if conditions.GetReason(scope.Config, bootstrapv1.DataSecretAvailableCondition) != bootstrapv1.DataSecretGenerationFailedReason {
|
||||
conditions.MarkFalse(scope.Config, bootstrapv1.DataSecretAvailableCondition, clusterv1.WaitingForControlPlaneAvailableReason, clusterv1.ConditionSeverityInfo, "")
|
||||
}
|
||||
|
||||
// if it's NOT a control plane machine, requeue
|
||||
if !scope.ConfigOwner.IsControlPlaneMachine() {
|
||||
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
|
||||
}
|
||||
|
||||
// if the machine has not ClusterConfiguration and InitConfiguration, requeue
|
||||
if scope.Config.Spec.ServerConfiguration == nil && scope.Config.Spec.Cluster == nil {
|
||||
scope.Info("Control plane is not ready, requeing joining control planes until ready.")
|
||||
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
|
||||
}
|
||||
|
||||
machine := &clusterv1.Machine{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(scope.ConfigOwner.Object, machine); err != nil {
|
||||
return ctrl.Result{}, errors.Wrapf(err, "cannot convert %s to Machine", scope.ConfigOwner.GetKind())
|
||||
}
|
||||
|
||||
// acquire the init lock so that only the first machine configured
|
||||
// as control plane get processed here
|
||||
// if not the first, requeue
|
||||
if !r.K3sInitLock.Lock(ctx, scope.Cluster, machine) {
|
||||
scope.Info("A control plane is already being initialized, requeing until control plane is ready")
|
||||
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
if !r.K3sInitLock.Unlock(ctx, scope.Cluster) {
|
||||
retErr = kerrors.NewAggregate([]error{retErr, errors.New("failed to unlock the kubeadm init lock")})
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
scope.Info("Creating BootstrapData for the first control plane")
|
||||
|
||||
if scope.Config.Spec.ServerConfiguration == nil {
|
||||
scope.Config.Spec.ServerConfiguration = &infrabootstrapv1.ServerConfiguration{}
|
||||
}
|
||||
|
||||
// injects into config.ClusterConfiguration values from top level object
|
||||
r.reconcileTopLevelObjectSettings(ctx, scope.Cluster, machine, scope.Config)
|
||||
|
||||
certificates := secret.NewCertificatesForInitialControlPlane()
|
||||
err := certificates.LookupOrGenerate(
|
||||
ctx,
|
||||
r.Client,
|
||||
util.ObjectKey(scope.Cluster),
|
||||
*metav1.NewControllerRef(scope.Config, infrabootstrapv1.GroupVersion.WithKind("K3sConfig")),
|
||||
)
|
||||
if err != nil {
|
||||
conditions.MarkFalse(scope.Config, bootstrapv1.CertificatesAvailableCondition, bootstrapv1.CertificatesGenerationFailedReason, clusterv1.ConditionSeverityWarning, err.Error())
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
conditions.MarkTrue(scope.Config, bootstrapv1.CertificatesAvailableCondition)
|
||||
|
||||
t, err := r.generateAndStoreToken(ctx, scope)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
initData, err := k3stypes.MarshalInitServerConfiguration(&scope.Config.Spec, t)
|
||||
if err != nil {
|
||||
scope.Error(err, "Failed to marshal server configuration")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
files, err := r.resolveFiles(ctx, scope.Config)
|
||||
if err != nil {
|
||||
conditions.MarkFalse(scope.Config, bootstrapv1.DataSecretAvailableCondition, bootstrapv1.DataSecretGenerationFailedReason, clusterv1.ConditionSeverityWarning, err.Error())
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
initConfigFile := bootstrapv1.File{
|
||||
Path: k3stypes.DefaultK3sConfigLocation,
|
||||
Content: initData,
|
||||
Owner: "root:root",
|
||||
Permissions: "0640",
|
||||
}
|
||||
|
||||
controlPlaneInput := &cloudinit.ControlPlaneInput{
|
||||
BaseUserData: cloudinit.BaseUserData{
|
||||
AdditionalFiles: files,
|
||||
PreK3sCommands: scope.Config.Spec.PreK3sCommands,
|
||||
PostK3sCommands: scope.Config.Spec.PostK3sCommands,
|
||||
ConfigFile: initConfigFile,
|
||||
},
|
||||
Certificates: certificates,
|
||||
}
|
||||
|
||||
bootstrapInitData, err := cloudinit.NewInitControlPlane(controlPlaneInput)
|
||||
if err != nil {
|
||||
scope.Error(err, "Failed to generate user data for bootstrap control plane")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
if err := r.storeBootstrapData(ctx, scope, bootstrapInitData); err != nil {
|
||||
scope.Error(err, "Failed to store bootstrap data")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *K3sConfigReconciler) joinWorker(ctx context.Context, scope *Scope) (ctrl.Result, error) {
|
||||
scope.Info("Creating BootstrapData for the worker node")
|
||||
|
||||
machine := &clusterv1.Machine{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(scope.ConfigOwner.Object, machine); err != nil {
|
||||
return ctrl.Result{}, errors.Wrapf(err, "cannot convert %s to Machine", scope.ConfigOwner.GetKind())
|
||||
}
|
||||
|
||||
// injects into config.Spec values from top level object
|
||||
r.reconcileWorkerTopLevelObjectSettings(ctx, scope.Cluster, machine, scope.Config)
|
||||
|
||||
// Ensure that agentConfiguration is properly set for joining node on the current cluster.
|
||||
if res, err := r.reconcileDiscovery(ctx, scope.Cluster, scope.Config); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
} else if !res.IsZero() {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
if scope.Config.Spec.AgentConfiguration == nil {
|
||||
scope.Config.Spec.AgentConfiguration = &infrabootstrapv1.AgentConfiguration{}
|
||||
}
|
||||
|
||||
joinWorkerData, err := k3stypes.MarshalJoinAgentConfiguration(&scope.Config.Spec)
|
||||
if err != nil {
|
||||
scope.Error(err, "Failed to marshal join configuration")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
files, err := r.resolveFiles(ctx, scope.Config)
|
||||
if err != nil {
|
||||
conditions.MarkFalse(scope.Config, bootstrapv1.DataSecretAvailableCondition, bootstrapv1.DataSecretGenerationFailedReason, clusterv1.ConditionSeverityWarning, err.Error())
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
joinConfigFile := bootstrapv1.File{
|
||||
Path: k3stypes.DefaultK3sConfigLocation,
|
||||
Content: joinWorkerData,
|
||||
Owner: "root:root",
|
||||
Permissions: "0640",
|
||||
}
|
||||
|
||||
workerJoinInput := &cloudinit.NodeInput{
|
||||
BaseUserData: cloudinit.BaseUserData{
|
||||
AdditionalFiles: files,
|
||||
PreK3sCommands: scope.Config.Spec.PreK3sCommands,
|
||||
PostK3sCommands: scope.Config.Spec.PostK3sCommands,
|
||||
ConfigFile: joinConfigFile,
|
||||
},
|
||||
}
|
||||
|
||||
cloudInitData, err := cloudinit.NewNode(workerJoinInput)
|
||||
if err != nil {
|
||||
scope.Error(err, "Failed to generate user data for bootstrap control plane")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
if err := r.storeBootstrapData(ctx, scope, cloudInitData); err != nil {
|
||||
scope.Error(err, "Failed to store bootstrap data")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *K3sConfigReconciler) joinControlplane(ctx context.Context, scope *Scope) (ctrl.Result, error) {
|
||||
scope.Info("Creating BootstrapData for the joining control plane")
|
||||
|
||||
if !scope.ConfigOwner.IsControlPlaneMachine() {
|
||||
return ctrl.Result{}, fmt.Errorf("%s is not a valid control plane kind, only Machine is supported", scope.ConfigOwner.GetKind())
|
||||
}
|
||||
|
||||
if scope.Config.Spec.ServerConfiguration == nil {
|
||||
scope.Config.Spec.ServerConfiguration = &infrabootstrapv1.ServerConfiguration{}
|
||||
}
|
||||
|
||||
machine := &clusterv1.Machine{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(scope.ConfigOwner.Object, machine); err != nil {
|
||||
return ctrl.Result{}, errors.Wrapf(err, "cannot convert %s to Machine", scope.ConfigOwner.GetKind())
|
||||
}
|
||||
|
||||
// injects into config.ClusterConfiguration values from top level object
|
||||
r.reconcileTopLevelObjectSettings(ctx, scope.Cluster, machine, scope.Config)
|
||||
|
||||
// Ensure that joinConfiguration.Discovery is properly set for joining node on the current cluster.
|
||||
if res, err := r.reconcileDiscovery(ctx, scope.Cluster, scope.Config); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
} else if !res.IsZero() {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
joinData, err := k3stypes.MarshalJoinServerConfiguration(&scope.Config.Spec)
|
||||
if err != nil {
|
||||
scope.Error(err, "Failed to marshal join configuration")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
files, err := r.resolveFiles(ctx, scope.Config)
|
||||
if err != nil {
|
||||
conditions.MarkFalse(scope.Config, bootstrapv1.DataSecretAvailableCondition, bootstrapv1.DataSecretGenerationFailedReason, clusterv1.ConditionSeverityWarning, err.Error())
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
joinConfigFile := bootstrapv1.File{
|
||||
Path: k3stypes.DefaultK3sConfigLocation,
|
||||
Content: joinData,
|
||||
Owner: "root:root",
|
||||
Permissions: "0640",
|
||||
}
|
||||
|
||||
controlPlaneJoinInput := &cloudinit.ControlPlaneInput{
|
||||
BaseUserData: cloudinit.BaseUserData{
|
||||
AdditionalFiles: files,
|
||||
PreK3sCommands: scope.Config.Spec.PreK3sCommands,
|
||||
PostK3sCommands: scope.Config.Spec.PostK3sCommands,
|
||||
ConfigFile: joinConfigFile,
|
||||
},
|
||||
}
|
||||
|
||||
cloudInitData, err := cloudinit.NewJoinControlPlane(controlPlaneJoinInput)
|
||||
if err != nil {
|
||||
scope.Error(err, "Failed to generate user data for bootstrap control plane")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
if err := r.storeBootstrapData(ctx, scope, cloudInitData); err != nil {
|
||||
scope.Error(err, "Failed to store bootstrap data")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *K3sConfigReconciler) generateAndStoreToken(ctx context.Context, scope *Scope) (string, error) {
|
||||
t, err := bootstraputil.GenerateBootstrapToken()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "unable to generate bootstrap token")
|
||||
}
|
||||
|
||||
s := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-token", scope.Cluster.Name),
|
||||
Namespace: scope.Config.Namespace,
|
||||
Labels: map[string]string{
|
||||
clusterv1.ClusterLabelName: scope.Cluster.Name,
|
||||
},
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: infrabootstrapv1.GroupVersion.String(),
|
||||
Kind: "K3sConfig",
|
||||
Name: scope.Config.Name,
|
||||
UID: scope.Config.UID,
|
||||
Controller: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"value": []byte(t),
|
||||
},
|
||||
Type: clusterv1.ClusterSecretType,
|
||||
}
|
||||
|
||||
// as secret creation and scope.Config status patch are not atomic operations
|
||||
// it is possible that secret creation happens but the config.Status patches are not applied
|
||||
if err := r.Client.Create(ctx, s); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return "", errors.Wrapf(err, "failed to create token for K3sConfig %s/%s", scope.Config.Namespace, scope.Config.Name)
|
||||
}
|
||||
if err := r.Client.Update(ctx, s); err != nil {
|
||||
return "", errors.Wrapf(err, "failed to update bootstrap token secret for K3sConfig %s/%s", scope.Config.Namespace, scope.Config.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// resolveFiles maps .Spec.Files into cloudinit.Files, resolving any object references
|
||||
// along the way.
|
||||
func (r *K3sConfigReconciler) resolveFiles(ctx context.Context, cfg *infrabootstrapv1.K3sConfig) ([]bootstrapv1.File, error) {
|
||||
collected := make([]bootstrapv1.File, 0, len(cfg.Spec.Files))
|
||||
|
||||
for i := range cfg.Spec.Files {
|
||||
in := cfg.Spec.Files[i]
|
||||
if in.ContentFrom != nil {
|
||||
data, err := r.resolveSecretFileContent(ctx, cfg.Namespace, in)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to resolve file source")
|
||||
}
|
||||
in.ContentFrom = nil
|
||||
in.Content = string(data)
|
||||
}
|
||||
collected = append(collected, in)
|
||||
}
|
||||
|
||||
return collected, nil
|
||||
}
|
||||
|
||||
// resolveSecretFileContent returns file content fetched from a referenced secret object.
|
||||
func (r *K3sConfigReconciler) resolveSecretFileContent(ctx context.Context, ns string, source bootstrapv1.File) ([]byte, error) {
|
||||
s := &corev1.Secret{}
|
||||
key := types.NamespacedName{Namespace: ns, Name: source.ContentFrom.Secret.Name}
|
||||
if err := r.Client.Get(ctx, key, s); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return nil, errors.Wrapf(err, "secret not found: %s", key)
|
||||
}
|
||||
return nil, errors.Wrapf(err, "failed to retrieve Secret %q", key)
|
||||
}
|
||||
data, ok := s.Data[source.ContentFrom.Secret.Key]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("secret references non-existent secret key: %q", source.ContentFrom.Secret.Key)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// storeBootstrapData creates a new secret with the data passed in as input,
|
||||
// sets the reference in the configuration status and ready to true.
|
||||
func (r *K3sConfigReconciler) storeBootstrapData(ctx context.Context, scope *Scope, data []byte) error {
|
||||
log := ctrl.LoggerFrom(ctx)
|
||||
|
||||
s := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: scope.Config.Name,
|
||||
Namespace: scope.Config.Namespace,
|
||||
Labels: map[string]string{
|
||||
clusterv1.ClusterLabelName: scope.Cluster.Name,
|
||||
},
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: infrabootstrapv1.GroupVersion.String(),
|
||||
Kind: "K3sConfig",
|
||||
Name: scope.Config.Name,
|
||||
UID: scope.Config.UID,
|
||||
Controller: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"value": data,
|
||||
},
|
||||
Type: clusterv1.ClusterSecretType,
|
||||
}
|
||||
|
||||
// as secret creation and scope.Config status patch are not atomic operations
|
||||
// it is possible that secret creation happens but the config.Status patches are not applied
|
||||
if err := r.Client.Create(ctx, s); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return errors.Wrapf(err, "failed to create bootstrap data secret for K3sConfig %s/%s", scope.Config.Namespace, scope.Config.Name)
|
||||
}
|
||||
log.Info("bootstrap data secret for K3sConfig already exists, updating", "Secret", klog.KObj(s))
|
||||
if err := r.Client.Update(ctx, s); err != nil {
|
||||
return errors.Wrapf(err, "failed to update bootstrap data secret for K3sConfig %s/%s", scope.Config.Namespace, scope.Config.Name)
|
||||
}
|
||||
}
|
||||
scope.Config.Status.DataSecretName = pointer.String(s.Name)
|
||||
scope.Config.Status.Ready = true
|
||||
conditions.MarkTrue(scope.Config, bootstrapv1.DataSecretAvailableCondition)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *K3sConfigReconciler) reconcileDiscovery(ctx context.Context, cluster *clusterv1.Cluster, config *infrabootstrapv1.K3sConfig) (ctrl.Result, error) {
|
||||
log := ctrl.LoggerFrom(ctx)
|
||||
|
||||
// if config already contains a file discovery configuration, respect it without further validations
|
||||
if config.Spec.Cluster.TokenFile != "" {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// if BootstrapToken already contains an APIServerEndpoint, respect it; otherwise inject the APIServerEndpoint endpoint defined in cluster status
|
||||
apiServerEndpoint := config.Spec.Cluster.Server
|
||||
if apiServerEndpoint == "" {
|
||||
if !cluster.Spec.ControlPlaneEndpoint.IsValid() {
|
||||
log.V(1).Info("Waiting for Cluster Controller to set Cluster.Server")
|
||||
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
|
||||
}
|
||||
|
||||
apiServerEndpoint = cluster.Spec.ControlPlaneEndpoint.String()
|
||||
config.Spec.Cluster.Server = fmt.Sprintf("https://%s", apiServerEndpoint)
|
||||
log.V(3).Info("Altering Cluster.Server", "Server", apiServerEndpoint)
|
||||
}
|
||||
|
||||
// if BootstrapToken already contains a token, respect it; otherwise create a new bootstrap token for the node to join
|
||||
if config.Spec.Cluster.Token == "" {
|
||||
s := &corev1.Secret{}
|
||||
obj := client.ObjectKey{
|
||||
Namespace: config.Namespace,
|
||||
Name: fmt.Sprintf("%s-token", cluster.Name),
|
||||
}
|
||||
|
||||
if err := r.Client.Get(ctx, obj, s); err != nil {
|
||||
return ctrl.Result{}, errors.Wrapf(err, "failed to get token for K3sConfig %s/%s", config.Namespace, config.Name)
|
||||
}
|
||||
|
||||
config.Spec.Cluster.Token = string(s.Data["value"])
|
||||
log.V(3).Info("Altering Cluster.Token")
|
||||
}
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// MachineToBootstrapMapFunc is a handler.ToRequestsFunc to be used to enqueue
|
||||
// request for reconciliation of K3sConfig.
|
||||
func (r *K3sConfigReconciler) MachineToBootstrapMapFunc(o client.Object) []ctrl.Request {
|
||||
m, ok := o.(*clusterv1.Machine)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Expected a Machine but got a %T", o))
|
||||
}
|
||||
|
||||
var result []ctrl.Request
|
||||
if m.Spec.Bootstrap.ConfigRef != nil && m.Spec.Bootstrap.ConfigRef.GroupVersionKind() == infrabootstrapv1.GroupVersion.WithKind("K3sConfig") {
|
||||
name := client.ObjectKey{Namespace: m.Namespace, Name: m.Spec.Bootstrap.ConfigRef.Name}
|
||||
result = append(result, ctrl.Request{NamespacedName: name})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// MachinePoolToBootstrapMapFunc is a handler.ToRequestsFunc to be used to enqueue
|
||||
// request for reconciliation of K3sConfig.
|
||||
func (r *K3sConfigReconciler) MachinePoolToBootstrapMapFunc(o client.Object) []ctrl.Request {
|
||||
m, ok := o.(*expv1.MachinePool)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Expected a MachinePool but got a %T", o))
|
||||
}
|
||||
|
||||
var result []ctrl.Request
|
||||
configRef := m.Spec.Template.Spec.Bootstrap.ConfigRef
|
||||
if configRef != nil && configRef.GroupVersionKind().GroupKind() == infrabootstrapv1.GroupVersion.WithKind("K3sConfig").GroupKind() {
|
||||
name := client.ObjectKey{Namespace: m.Namespace, Name: configRef.Name}
|
||||
result = append(result, ctrl.Request{NamespacedName: name})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ClusterToK3sConfigs is a handler.ToRequestsFunc to be used to enqueue
|
||||
// requests for reconciliation of K3sConfig.
|
||||
func (r *K3sConfigReconciler) ClusterToK3sConfigs(o client.Object) []ctrl.Request {
|
||||
var result []ctrl.Request
|
||||
|
||||
c, ok := o.(*clusterv1.Cluster)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Expected a Cluster but got a %T", o))
|
||||
}
|
||||
|
||||
selectors := []client.ListOption{
|
||||
client.InNamespace(c.Namespace),
|
||||
client.MatchingLabels{
|
||||
clusterv1.ClusterLabelName: c.Name,
|
||||
},
|
||||
}
|
||||
|
||||
machineList := &clusterv1.MachineList{}
|
||||
if err := r.Client.List(context.TODO(), machineList, selectors...); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, m := range machineList.Items {
|
||||
if m.Spec.Bootstrap.ConfigRef != nil &&
|
||||
m.Spec.Bootstrap.ConfigRef.GroupVersionKind().GroupKind() == infrabootstrapv1.GroupVersion.WithKind("K3sConfig").GroupKind() {
|
||||
name := client.ObjectKey{Namespace: m.Namespace, Name: m.Spec.Bootstrap.ConfigRef.Name}
|
||||
result = append(result, ctrl.Request{NamespacedName: name})
|
||||
}
|
||||
}
|
||||
|
||||
if feature.Gates.Enabled(feature.MachinePool) {
|
||||
machinePoolList := &expv1.MachinePoolList{}
|
||||
if err := r.Client.List(context.TODO(), machinePoolList, selectors...); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, mp := range machinePoolList.Items {
|
||||
if mp.Spec.Template.Spec.Bootstrap.ConfigRef != nil &&
|
||||
mp.Spec.Template.Spec.Bootstrap.ConfigRef.GroupVersionKind().GroupKind() == infrabootstrapv1.GroupVersion.WithKind("K3sConfig").GroupKind() {
|
||||
name := client.ObjectKey{Namespace: mp.Namespace, Name: mp.Spec.Template.Spec.Bootstrap.ConfigRef.Name}
|
||||
result = append(result, ctrl.Request{NamespacedName: name})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// reconcileTopLevelObjectSettings injects into config.ClusterConfiguration values from top level objects like cluster and machine.
|
||||
// The implementation func respect user provided config values, but in case some of them are missing, values from top level objects are used.
|
||||
func (r *K3sConfigReconciler) reconcileTopLevelObjectSettings(ctx context.Context, cluster *clusterv1.Cluster, machine *clusterv1.Machine, config *infrabootstrapv1.K3sConfig) {
|
||||
log := ctrl.LoggerFrom(ctx)
|
||||
|
||||
// If there are no Network settings defined in ClusterConfiguration, use ClusterNetwork settings, if defined
|
||||
if cluster.Spec.ClusterNetwork != nil {
|
||||
if config.Spec.ServerConfiguration.Networking.ClusterDomain == "" && cluster.Spec.ClusterNetwork.ServiceDomain != "" {
|
||||
config.Spec.ServerConfiguration.Networking.ClusterDomain = cluster.Spec.ClusterNetwork.ServiceDomain
|
||||
log.V(3).Info("Altering ServerConfiguration.Networking.ClusterDomain", "ClusterDomain", config.Spec.ServerConfiguration.Networking.ClusterDomain)
|
||||
}
|
||||
if config.Spec.ServerConfiguration.Networking.ServiceCIDR == "" &&
|
||||
cluster.Spec.ClusterNetwork.Services != nil &&
|
||||
len(cluster.Spec.ClusterNetwork.Services.CIDRBlocks) > 0 {
|
||||
config.Spec.ServerConfiguration.Networking.ServiceCIDR = cluster.Spec.ClusterNetwork.Services.String()
|
||||
log.V(3).Info("Altering ServerConfiguration.Networking.ServiceCIDR", "ServiceCIDR", config.Spec.ServerConfiguration.Networking.ServiceCIDR)
|
||||
}
|
||||
if config.Spec.ServerConfiguration.Networking.ClusterCIDR == "" &&
|
||||
cluster.Spec.ClusterNetwork.Pods != nil &&
|
||||
len(cluster.Spec.ClusterNetwork.Pods.CIDRBlocks) > 0 {
|
||||
config.Spec.ServerConfiguration.Networking.ClusterCIDR = cluster.Spec.ClusterNetwork.Pods.String()
|
||||
log.V(3).Info("Altering ServerConfiguration.Networking.ClusterCIDR", "ClusterCIDR", config.Spec.ServerConfiguration.Networking.ClusterCIDR)
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no Version settings defined, use Version from machine, if defined
|
||||
if config.Spec.Version == "" && machine.Spec.Version != nil {
|
||||
config.Spec.Version = *machine.Spec.Version
|
||||
log.V(3).Info("Altering Spec.Version", "Version", config.Spec.Version)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *K3sConfigReconciler) reconcileWorkerTopLevelObjectSettings(ctx context.Context, _ *clusterv1.Cluster, machine *clusterv1.Machine, config *infrabootstrapv1.K3sConfig) {
|
||||
log := ctrl.LoggerFrom(ctx)
|
||||
|
||||
// If there are no Version settings defined, use Version from machine, if defined
|
||||
if config.Spec.Version == "" && machine.Spec.Version != nil {
|
||||
config.Spec.Version = *machine.Spec.Version
|
||||
log.V(3).Info("Altering Spec.Version", "Version", config.Spec.Version)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
Copyright 2022.
|
||||
|
||||
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 controllers
|
||||
|
||||
//var (
|
||||
// env *envtest.Environment
|
||||
// ctx = ctrl.SetupSignalHandler()
|
||||
//)
|
||||
//
|
||||
//func TestMain(m *testing.M) {
|
||||
// os.Exit(envtest.Run(ctx, envtest.RunInput{
|
||||
// M: m,
|
||||
// SetupEnv: func(e *envtest.Environment) { env = e },
|
||||
// }))
|
||||
//}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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.
|
||||
*/
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
/*
|
||||
Copyright 2022.
|
||||
|
||||
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 main
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/klog/v2/klogr"
|
||||
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
|
||||
"sigs.k8s.io/cluster-api/controllers/remote"
|
||||
expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
|
||||
"sigs.k8s.io/cluster-api/feature"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||
|
||||
infrabootstrapv1 "github.com/kubesphere/kubekey/v3/bootstrap/k3s/api/v1beta1"
|
||||
"github.com/kubesphere/kubekey/v3/bootstrap/k3s/controllers"
|
||||
infracontrolplanev1 "github.com/kubesphere/kubekey/v3/controlplane/k3s/api/v1beta1"
|
||||
//+kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
var (
|
||||
scheme = runtime.NewScheme()
|
||||
setupLog = ctrl.Log.WithName("setup")
|
||||
)
|
||||
|
||||
func init() {
|
||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
||||
utilruntime.Must(clusterv1.AddToScheme(scheme))
|
||||
utilruntime.Must(expv1.AddToScheme(scheme))
|
||||
utilruntime.Must(infrabootstrapv1.AddToScheme(scheme))
|
||||
utilruntime.Must(infracontrolplanev1.AddToScheme(scheme))
|
||||
//+kubebuilder:scaffold:scheme
|
||||
}
|
||||
|
||||
var (
|
||||
metricsAddr string
|
||||
enableLeaderElection bool
|
||||
leaderElectionLeaseDuration time.Duration
|
||||
leaderElectionRenewDeadline time.Duration
|
||||
leaderElectionRetryPeriod time.Duration
|
||||
k3sConfigConcurrency int
|
||||
healthAddr string
|
||||
watchFilterValue string
|
||||
watchNamespace string
|
||||
syncPeriod time.Duration
|
||||
webhookPort int
|
||||
webhookCertDir string
|
||||
)
|
||||
|
||||
func main() {
|
||||
klog.InitFlags(nil)
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
initFlags(pflag.CommandLine)
|
||||
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
|
||||
pflag.Parse()
|
||||
|
||||
ctrl.SetLogger(klogr.New())
|
||||
|
||||
ctx := ctrl.SetupSignalHandler()
|
||||
|
||||
restConfig := ctrl.GetConfigOrDie()
|
||||
restConfig.UserAgent = remote.DefaultClusterAPIUserAgent("cluster-api-k3s-bootstrap-manager")
|
||||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
||||
Scheme: scheme,
|
||||
MetricsBindAddress: metricsAddr,
|
||||
LeaderElection: enableLeaderElection,
|
||||
LeaderElectionID: "k3s-bootstrap-manager-leader-election-capkk",
|
||||
LeaderElectionResourceLock: resourcelock.LeasesResourceLock,
|
||||
LeaseDuration: &leaderElectionLeaseDuration,
|
||||
RenewDeadline: &leaderElectionRenewDeadline,
|
||||
RetryPeriod: &leaderElectionRetryPeriod,
|
||||
SyncPeriod: &syncPeriod,
|
||||
ClientDisableCacheFor: []client.Object{
|
||||
&corev1.ConfigMap{},
|
||||
&corev1.Secret{},
|
||||
},
|
||||
Namespace: watchNamespace,
|
||||
Port: webhookPort,
|
||||
HealthProbeBindAddress: healthAddr,
|
||||
CertDir: webhookCertDir,
|
||||
})
|
||||
if err != nil {
|
||||
setupLog.Error(err, "unable to start manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err := (&controllers.K3sConfigReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
WatchFilterValue: watchFilterValue,
|
||||
}).SetupWithManager(ctx, mgr, concurrency(k3sConfigConcurrency)); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "K3sConfig")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
||||
setupLog.Error(err, "unable to set up health check")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
|
||||
setupLog.Error(err, "unable to set up ready check")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err = (&infrabootstrapv1.K3sConfig{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create webhook", "webhook", "K3sConfig")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&infrabootstrapv1.K3sConfigTemplate{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create webhook", "webhook", "K3sConfigTemplate")
|
||||
os.Exit(1)
|
||||
}
|
||||
// +kubebuilder:scaffold:builder
|
||||
setupLog.Info("starting manager")
|
||||
if err := mgr.Start(ctx); err != nil {
|
||||
setupLog.Error(err, "problem running manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func initFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&metricsAddr, "metrics-bind-addr", "localhost:8080",
|
||||
"The address the metric endpoint binds to.")
|
||||
|
||||
fs.BoolVar(&enableLeaderElection, "leader-elect", false,
|
||||
"Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
|
||||
|
||||
fs.DurationVar(&leaderElectionLeaseDuration, "leader-elect-lease-duration", 15*time.Second,
|
||||
"Interval at which non-leader candidates will wait to force acquire leadership (duration string)")
|
||||
|
||||
fs.DurationVar(&leaderElectionRenewDeadline, "leader-elect-renew-deadline", 10*time.Second,
|
||||
"Duration that the leading controller manager will retry refreshing leadership before giving up (duration string)")
|
||||
|
||||
fs.DurationVar(&leaderElectionRetryPeriod, "leader-elect-retry-period", 2*time.Second,
|
||||
"Duration the LeaderElector clients should wait between tries of actions (duration string)")
|
||||
|
||||
fs.StringVar(&watchNamespace, "namespace", "",
|
||||
"Namespace that the controller watches to reconcile cluster-api objects. If unspecified, the controller watches for cluster-api objects across all namespaces.")
|
||||
|
||||
fs.StringVar(&healthAddr, "health-addr", ":9440",
|
||||
"The address the health endpoint binds to.")
|
||||
|
||||
fs.IntVar(&k3sConfigConcurrency, "k3sconfig-concurrency", 10,
|
||||
"Number of kubeadm configs to process simultaneously")
|
||||
|
||||
fs.DurationVar(&syncPeriod, "sync-period", 10*time.Minute,
|
||||
"The minimum interval at which watched resources are reconciled (e.g. 15m)")
|
||||
|
||||
fs.StringVar(&watchFilterValue, "watch-filter", "",
|
||||
fmt.Sprintf("Label value that the controller watches to reconcile cluster-api objects. Label key is always %s. If unspecified, the controller watches for all cluster-api objects.", clusterv1.WatchLabel))
|
||||
|
||||
fs.IntVar(&webhookPort, "webhook-port", 9443,
|
||||
"Webhook Server port")
|
||||
|
||||
fs.StringVar(&webhookCertDir, "webhook-cert-dir", "/tmp/k8s-webhook-server/serving-certs/",
|
||||
"Webhook cert dir, only used when webhook-port is specified.")
|
||||
|
||||
feature.MutableGates.AddFlag(fs)
|
||||
}
|
||||
|
||||
func concurrency(c int) controller.Options {
|
||||
return controller.Options{MaxConcurrentReconciles: c}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue