From f7ee88f9b8ff5c38e90be9464178836840089b5f Mon Sep 17 00:00:00 2001 From: inksnw Date: Wed, 9 Oct 2024 17:19:25 +0800 Subject: [PATCH] add luban extension --- .github/workflows/push.yml | 43 ++++++++++++++ Dockerfile | 3 + extensions/app-tool/CHANGELOG.md | 0 extensions/app-tool/CHANGELOG_zh.md | 0 extensions/app-tool/README.md | 2 + extensions/app-tool/README_zh.md | 26 +++++++++ .../app-tool/charts/app-tool/.helmignore | 23 ++++++++ .../app-tool/charts/app-tool/Chart.yaml | 6 ++ .../charts/app-tool/templates/job.yaml | 23 ++++++++ .../app-tool/templates/post-install-job.yaml | 25 ++++++++ .../charts/app-tool/templates/role.yaml | 41 +++++++++++++ .../charts/app-tool/templates/token.yaml | 22 +++++++ .../app-tool/charts/app-tool/values.yaml | 1 + extensions/app-tool/extension.yaml | 33 +++++++++++ extensions/app-tool/permissions.yaml | 55 ++++++++++++++++++ extensions/app-tool/static/favicon.svg | 1 + .../static/screenshots/screenshot.png | Bin 0 -> 15076 bytes extensions/app-tool/values.yaml | 3 + go.mod | 1 + go.sum | 18 ++++++ main.go | 31 +++++----- 21 files changed, 339 insertions(+), 18 deletions(-) create mode 100644 .github/workflows/push.yml create mode 100644 Dockerfile create mode 100644 extensions/app-tool/CHANGELOG.md create mode 100644 extensions/app-tool/CHANGELOG_zh.md create mode 100644 extensions/app-tool/README.md create mode 100644 extensions/app-tool/README_zh.md create mode 100644 extensions/app-tool/charts/app-tool/.helmignore create mode 100644 extensions/app-tool/charts/app-tool/Chart.yaml create mode 100644 extensions/app-tool/charts/app-tool/templates/job.yaml create mode 100644 extensions/app-tool/charts/app-tool/templates/post-install-job.yaml create mode 100644 extensions/app-tool/charts/app-tool/templates/role.yaml create mode 100644 extensions/app-tool/charts/app-tool/templates/token.yaml create mode 100644 extensions/app-tool/charts/app-tool/values.yaml create mode 100644 extensions/app-tool/extension.yaml create mode 100644 extensions/app-tool/permissions.yaml create mode 100644 extensions/app-tool/static/favicon.svg create mode 100644 extensions/app-tool/static/screenshots/screenshot.png create mode 100644 extensions/app-tool/values.yaml diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 0000000..6fbb8de --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,43 @@ +name: Push Images +on: + push: + tags: + - '*' +jobs: + images: + permissions: write-all + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.23.1 + - name: Build Go code for amd64 + run: GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o app-tool-amd64 main.go + - name: Build Go code for arm64 + run: GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o app-tool-arm64 main.go + - name: Debug docker + run: echo ${{ secrets.DOCKER_USERNAME }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: kubesphere/app-tool:${{ github.ref_name }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..69afcc9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,3 @@ +FROM kubesphere/kubectl:v1.27.4 +ARG TARGETARCH +COPY app-tool-${TARGETARCH} /usr/local/bin/app-tool \ No newline at end of file diff --git a/extensions/app-tool/CHANGELOG.md b/extensions/app-tool/CHANGELOG.md new file mode 100644 index 0000000..e69de29 diff --git a/extensions/app-tool/CHANGELOG_zh.md b/extensions/app-tool/CHANGELOG_zh.md new file mode 100644 index 0000000..e69de29 diff --git a/extensions/app-tool/README.md b/extensions/app-tool/README.md new file mode 100644 index 0000000..139597f --- /dev/null +++ b/extensions/app-tool/README.md @@ -0,0 +1,2 @@ + + diff --git a/extensions/app-tool/README_zh.md b/extensions/app-tool/README_zh.md new file mode 100644 index 0000000..85ad85f --- /dev/null +++ b/extensions/app-tool/README_zh.md @@ -0,0 +1,26 @@ +# 商店导入工具 + +## 概述 + +本工具用于把 helm repo 中的软件同步到应用商店中。注意, 您可以在 kubespehre 直接配置repo源使用, 参考文档 + +https://ask.kubesphere.io/forum/d/23922-kubesphere-411-ying-yong-shang-dian-pei-zhi-fang-fa + +这个工具是把 repo 中的应用变成全局商店应用, 不是必须的操作。 + +## 使用方法 + +配置安装参数, 指定要同步的源 + +```bash +app-tool: + repoUrl: "https://charts.kubesphere.io/stable" +``` + +## 注意事项 + +由于商店允许多次上传并生成随机名称的应用,本工具不会处理多次执行的场景。如果您多次执行,希望清理生成的资源,请手动执行 + +``` +kubectl delete applications.application.kubesphere.io xxx +``` diff --git a/extensions/app-tool/charts/app-tool/.helmignore b/extensions/app-tool/charts/app-tool/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/extensions/app-tool/charts/app-tool/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/extensions/app-tool/charts/app-tool/Chart.yaml b/extensions/app-tool/charts/app-tool/Chart.yaml new file mode 100644 index 0000000..426718f --- /dev/null +++ b/extensions/app-tool/charts/app-tool/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: 1.16.0 +description: A Helm chart for Kubernetes +name: app-tool +type: application +version: 0.1.0 diff --git a/extensions/app-tool/charts/app-tool/templates/job.yaml b/extensions/app-tool/charts/app-tool/templates/job.yaml new file mode 100644 index 0000000..63796af --- /dev/null +++ b/extensions/app-tool/charts/app-tool/templates/job.yaml @@ -0,0 +1,23 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: app-tool-job + namespace: extension-app-tool +spec: + template: + metadata: + annotations: + kubesphere.io/serviceaccount-name: app-tool + spec: + serviceAccountName: app-tool-k8s + containers: + - name: app-tool-job + image: kubesphere/app-tool:1.0.0 + args: + - /bin/sh + - -c + - | + app-tool --repo={{ .Values.repoUrl }} --server=http://ks-console.kubesphere-system + + restartPolicy: Never + backoffLimit: 0 \ No newline at end of file diff --git a/extensions/app-tool/charts/app-tool/templates/post-install-job.yaml b/extensions/app-tool/charts/app-tool/templates/post-install-job.yaml new file mode 100644 index 0000000..453463d --- /dev/null +++ b/extensions/app-tool/charts/app-tool/templates/post-install-job.yaml @@ -0,0 +1,25 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: post-install-job + namespace: extension-app-tool + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed +spec: + template: + spec: + containers: + - name: post-install-job + image: kubesphere/kubectl:v1.27.4 + command: + - /bin/sh + - -c + - | + kubectl delete serviceaccounts.kubesphere.io app-tool -n extension-app-tool + kubectl delete globalrolebindings.iam.kubesphere.io app-tool-platform-admin + kubectl delete clusterroles.rbac.authorization.k8s.io app-tool-k8s-cluster-role + kubectl delete clusterrolebindings.rbac.authorization.k8s.io app-tool-k8s + kubectl delete serviceaccounts app-tool-k8s -n extension-app-tool + restartPolicy: Never + backoffLimit: 0 \ No newline at end of file diff --git a/extensions/app-tool/charts/app-tool/templates/role.yaml b/extensions/app-tool/charts/app-tool/templates/role.yaml new file mode 100644 index 0000000..f79dbb8 --- /dev/null +++ b/extensions/app-tool/charts/app-tool/templates/role.yaml @@ -0,0 +1,41 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: app-tool-k8s-cluster-role +rules: + - apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - '*' + - apiGroups: + - "application.kubesphere.io" + resources: + - "*" + verbs: + - "*" + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: app-tool-k8s + namespace: extension-app-tool +subjects: + - kind: ServiceAccount + name: app-tool-k8s + namespace: extension-app-tool +roleRef: + kind: ClusterRole + name: app-tool-k8s-cluster-role + apiGroup: rbac.authorization.k8s.io + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: app-tool-k8s + namespace: extension-app-tool \ No newline at end of file diff --git a/extensions/app-tool/charts/app-tool/templates/token.yaml b/extensions/app-tool/charts/app-tool/templates/token.yaml new file mode 100644 index 0000000..fd639f0 --- /dev/null +++ b/extensions/app-tool/charts/app-tool/templates/token.yaml @@ -0,0 +1,22 @@ +apiVersion: kubesphere.io/v1alpha1 +kind: ServiceAccount +metadata: + name: app-tool + namespace: extension-app-tool +--- +apiVersion: iam.kubesphere.io/v1beta1 +kind: GlobalRoleBinding +metadata: + labels: + iam.kubesphere.io/role-ref: platform-admin + name: app-tool-platform-admin +roleRef: + apiGroup: iam.kubesphere.io + kind: GlobalRole + name: platform-admin +subjects: + - apiGroup: kubesphere.io + kind: ServiceAccount + name: app-tool + namespace: extension-app-tool + diff --git a/extensions/app-tool/charts/app-tool/values.yaml b/extensions/app-tool/charts/app-tool/values.yaml new file mode 100644 index 0000000..0b08ddf --- /dev/null +++ b/extensions/app-tool/charts/app-tool/values.yaml @@ -0,0 +1 @@ +repoUrl: "https://charts.kubesphere.io/stable" diff --git a/extensions/app-tool/extension.yaml b/extensions/app-tool/extension.yaml new file mode 100644 index 0000000..fcf4e92 --- /dev/null +++ b/extensions/app-tool/extension.yaml @@ -0,0 +1,33 @@ +apiVersion: kubesphere.io/v1alpha1 +name: app-tool +version: 0.1.0 +displayName: + zh: 应用商店同步工具 + en: App store sync tool +description: + zh: 应用商店同步工具 + en: App store sync tool +home: https://kubesphere.io +sources: + - https://github.com/kubesphere +kubeVersion: ">=1.19.0-0" +ksVersion: ">=4.1.1-0" +category: dev-tools +keywords: + - dev-tools +provider: + zh: + name: "kubesphere" + email: "" + url: "" + en: + name: "kubesphere" + email: "" + url: "" +icon: ./static/favicon.svg +installationMode: HostOnly +externalDependencies: + - name: openpitrix + type: extension + version: '>= 1.0.0-0' + required: true \ No newline at end of file diff --git a/extensions/app-tool/permissions.yaml b/extensions/app-tool/permissions.yaml new file mode 100644 index 0000000..1edd60c --- /dev/null +++ b/extensions/app-tool/permissions.yaml @@ -0,0 +1,55 @@ +kind: ClusterRole +rules: + - verbs: + - '*' + apiGroups: + - 'extensions.kubesphere.io' + - 'jsbundles.extensions.kubesphere.io' + resources: + - '*' + - verbs: + - '*' + apiGroups: + - '' + resources: + - 'configmaps' + - 'secrets' + - verbs: + - '*' + apiGroups: + - 'rbac.authorization.k8s.io' + resources: + - 'clusterroles' + - verbs: + - '*' + apiGroups: + - '*' + resources: + - '*' + +--- +kind: Role +rules: + - verbs: + - '*' + apiGroups: + - '' + - 'apps' + - 'batch' + - 'app.k8s.io' + - 'autoscaling' + resources: + - '*' + - verbs: + - '*' + apiGroups: + - 'networking.k8s.io' + resources: + - 'ingresses' + - 'networkpolicies' + - verbs: + - '*' + apiGroups: + - '*' + resources: + - '*' diff --git a/extensions/app-tool/static/favicon.svg b/extensions/app-tool/static/favicon.svg new file mode 100644 index 0000000..1460b4d --- /dev/null +++ b/extensions/app-tool/static/favicon.svg @@ -0,0 +1 @@ + diff --git a/extensions/app-tool/static/screenshots/screenshot.png b/extensions/app-tool/static/screenshots/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..279d191381df7e6e40f51e4fe585d367b0fbc386 GIT binary patch literal 15076 zcmeHtcT`hL_b8TYr>F=bO+`>a2ofc9q(~7&q)LDwD7^#-5FiwlCLo}62t`GjNGC)} zKtVuyhd>~q2%)6V5=tm9-uu1Z?|bj9_vc&hTkGCg>zp%t_Uyf9_Uzd+XU|0H>uIu{ zx^#+#g@sjHOWlBlg^kX_a+Gx92(x75>!)+f&ry4ohbk;A<#DHXt^Z)chhPSpsw^cv ze2dIH*3syR*OQ03a?hZy64uY5HntMJuI|iQEG!DXa?Gr&t(Wy>Uso45n4GWT)jw;< zG4sER0aq{oS;fm)@#>R@`j^$9p0<~zB_t&zuPU9oeEG71=W{zb19gpmkuxF1s}5dX z?s5PC91fR&10|rI_JG^6va$e4DS(ueIJ1U0%+Jls+E?5SCiEAR|H(()7WT~3(cQ}t z>UQ}zUuzqvx0mA8tG@;PSNf}+w!V)4Ey)e`uWm6r2>6Ww+?J38{1 z!)KnhOyLetuYbw?cjUha6#&2c{%^YYOVNLpGBvGqN&)a+qo#DqefVl^b5#|mTdQ>-cOWl8>uBayjP?c7*z)cgU z=9b3^^K(lpMAF*I#@77u>dXRphDgFqFJxsEPR=f_(RXGSsH^mC^6KWV#g(zCdHn3s z0(pITg|nm z)2h99G%!5*M=v%ZJ+EhI!oxrMeL+=z=~pzS?M+gSwR3P`SzTm&w(b+RirVJRfpOJG zwzojqjf4LR^zUu`@AJxHlRsG4BQidfxp;?}+aZR=XACSoCFLJJv37_0MnuG>W171Y z`@SY-6t;8>j?F9vhQ^yiEoC(z=FBmMhREEv^l1KYNBMDc`=D1~oQ#U$#Ps5;$Ydwa z7uv>7PaS-cvx_Yq0)EVldk01vTDl}>eYV0R*}5Xs9$Lz(8&}o0Dm-{v-_)gV;qLb$ zc4BtBQNH3;bXR2`ab|9H-K6#{>u1<~R0L|WPrNiB zbFjhT8?s?)WQsz)a8QJ1VUZ5gR#!3d9Vbnaq31Ubee=LceNvX}7uh{lsNY{`ykn;$ z489s#^|pZZ+M$_0?%#|5{NPfR!E4S7c~N%_d5n$a`n5wHJ{kpLYxDP$!7ecX-VNv10wWWK7EpdoW1%H)Y3yYbl;i zqP^?+4fQa^fV%KhK_VW=bmuIjm<88vy!jDJbT9X*umD__XHACL2fk8$i60%?^W8wH z=(TOtXV=Gyd4WY}spw9ApVTjJp@gra<%d{&#@}CI**dtv1?s_*tSFe_+7M4GE2}G* z{!vrChE3X>x#>dZPf)dkNx^l;fVv6m7B5JHzfhe*HeZQ$iLISbKpj6X%hR@QGC|p% zlLhjIwAa>KvtdC+#2swskMMI!VV-CeNtstKp4!g)acfhrH()t^yE>5^j|tNo!>#sJ zaK9*)larQ`@)?pD%9Ob+R|_R9EDna-R36(jwZ!Xg37CQX6LquvR@%#BKr#wa*lktJ zGMc^hJlZ~(@llyqsRTbdDx&0vZCD`ZI=3l?ydZbsgO%OBFos84Y)VPuAX_^s>EUc8 z%s&~|beCXVEN%x?gxUgF%z-Eq@nqCZp?A;qIAw26*VQaw>XpkQDT-W8`cm5_CunB^ z?hx!GAyNWOX$u!k4JsF7vqE`mOg~T7^Jzd{+c)=zxDMRU4u23#v7Xh0ZgnR}k^}|I zGRKhHmG=pO=9vT`L}yF}IUO?>pkyUsUji$cvs*Uzn7#0kS9}av3bmwUVv6N;*)suX z5jX?);?UD0ni4<0dw%E1{|a*o1Io$C)kY4;vo5cinD=<~lLL4VI;k z2!=`WJfbm1kGrVR1sLV4r(nzZHdInKm+dGi#(ticXo4iTBAv-Z&ku?oor|%xc2Jxn zuIurs?sjqSLq1{O)4PI;owG(UX}Sp8H6EX}h3___9b=a4J&R6r84kLe5}5_VCHaG( zCifB_rwX@^)lE;H(MHvL(SFCFfYA|)x&itYfz>)sy8L33Q$|mJLt7C6Al^M%4OZqZ z-LdxncHIfo{mn%>CzkOjZhpWMTGE~4}1u*XE(a>$FEpKSHk^; zD!BSkOXTNBfU}B4@fI}ic)iTw-Yg7jT;rp8 zcsIU!y+E-71f0B!7)+bfy$K(m9khd%z&($w9F~U84q@jC0v~0USgFeH1a!cqG4hqY zWeJZUwOHHsKB^MIb=X`7`F*GRynG6#t)yh+ku}75&s+Tj-1$7Pe*hgXG<4YAsU|2i zcR!ExaDp*G3GBUB&CnWlQ2dnv*+1prj=+P zn?0v=%wu&(H-D*7G(5jz^JX?{O@d(C$DfKRx~;@jDyymByIfLlh641Xpz}Qvq6fk6I3iU{k0)*R+&2Zz;$&txYBo zCf{cK3WVM5(hT#0$%HOOTxaC>C~5m_T0bckpo|wffRaM^E6}xD)7Sy9(I_tP3fTfd zqckdDy=nVZYdIv##_UUx5o`NitufaSZB0u?Zq=UqAtNLVFNLol^PZ(uCiPC?5<;lHrSGS6#xtPyhR?)c0_*hByRUDk5i12FD0sZ< zM;@Zwb7;lZy{bhrnZK;15fujI#K0`;He5obx!ic*r3+WhcXQ)=J#=(qB!E^2aNj|Otw6$P1`1Ew zFkWKJ+~L5vp4SelLO)z4R=H{9Z>2}pqEjULbM%8#b^S_x^3VCjqi3*J zto=GKO0pgs2({&XJaKP8=6$%!ivc_B!9ew;k~OhSygV=~LJ{x`c}*^x6Je(?dwcfu zDiKDJWj~T~a{Kx1ZQ_g9ke(Q+(;G42?P>iCWr}5BBZ2R3J+arw&Pg<#zJKzmAx+a( z6dEp0@eaME@^(!8z{Hw+>dch{mTq;S&fCSK)lrHMQ7O(I*76gr*sn2xbJ+u3rh=6` zI`iYa)dD)D(Q|pD(wz(4qJsd)2;P<@m|M zd`4#6I5uxj50{c)eAV%b7wWxy;)(!|;pubcbEqsW#9nRUY{6|!w6v(mrbrqu`}b?W zZ;3y>1zslltEj3903nFg6R)hEI6{xU&z~AMU(LJEwzalvhbz_pO5fQv8}HreCFPqx13!?VDDcvyi0fcgq#Z_p*(D!9?Lr|gG=-zBg- zJ`_wGyQ_6SV&;fY;ORY`>5$?l_8hUxE6{7NE>lpZLYRYnC0t}TYE*~Mxs+(ALraWS zO-XZrrg`c@#+Uav|5D3l=&hRc@j6ZW;Ljq%>m)M9&kE!%h{ zL_I`vp3-;I7y(sWDipEL9w5>$Dfu{!6nR_lYtRULn2x1D|UjV=5t{`!d3d2)%H(Xr2eunj^`7*<_rN#;GDvMmI6q;;o_T z*=nF;=yY;P4-YDZC!p@iMtiBnoN&eU2a1bCIwWLPhVht9+9WC;Q=%CXNf&tvKRQDk z)HGH_2>ZU1BGl-FAGz+;{D%t1k2Jc|r%mO9jwBY><#zIzo}}S&@*qZ8~woALdwU z1O!`3@sV!306!TZ$UQNaPrQ0hA3u+OnCrvuLoN;;7RkjbaA ziS|ff>SUvNeZ_ghhDwXb>QvF(p+XGl(vi3$Mf_0%;y(-!WBtgMK73TvPghrXQ6bHjlON*<h8 z(g?~sPS5Z2hiVt6Jjb8vA9j?ibjroxtkbUCM_f-7Cw@V}A>3reaJ7(Cg+sntK2K|t z0o@6QUav*pKI-V5g1p)e9!!Nl?J+>`ZX0slM~I2;e=Kyd{frS0(cHCl(`?e{wBq>e zkb&zwHX*vP?Z0_A{6WvdP-p0R?B!FPGfM8YIp5V0+DFDrq_C_>8ApVUNz7Pj9aXV# zqMq&!&L$x5NJ|YuW(*LRk)_4El+l7lr7j&pLRg@}8p463+(#BgL7&NnfWWM~RuBwz&Cu(i^Cu8ybFm;X} zx%A|eBH@g7Dm3~mndU3Y71^4$Qeq0ov6c1dFhz7<8 z2ig+1KBQSK)12x}jV&H&nCFh0NXe1!Dp^ys>$!*;97k335f2MuF^_u>L`+<_M9JIqclc`jrMgk~by`8+#tfu??AHK$`E}xWlrj|9WiS=SCGL znH_cFaU4C2w`Bq!rrla$g0PJOqDN^C?w>H}@g}N>qU^CJKDv zQ+%bDzJ^wJ&KD=;r;84;I|ZE&dUl_dY9_?ToP``!;TVF92AEk->6mwa0OaE9*wem^ zRJYf3{xW-sGWCVF7n_R7fwkUM!G%wh=BDeS&R>pCqglL>QjYQjI6WxOts5ATcp0CO2M*D*kb4?;y-gt^Ba4B2g8RjLwwCm+nr_&<8JxV>(mU6CqdjGOkZN3xrkqxC}`VRa`3nfLwuVLlh zOJ|X}BFq)n&(*hHV4~<*2v$eB&Gn=+D;@fLBdK)AjbeJO0Bda3XzH&wGpJ894P@^Gyz=K~YrYeaBLaXBWDwobHcm$$LmCXbjRyrX!5BC&ezR#{^)?9t_q1c7YUs;9+I1#aT z>pm<`s;h_D+m)a^WKOYulb*&SDb$U2fRfxry;fjSMo9bj0f$mtKS$T&r0Cvf)kFA) zNmquLhOGAyGdH&+&=B4@?hI&mW8G-bKs;tn2Ih3t`HcAyoN2JLHXT-Wt;}%qhHD)V zy;<%6Sp0dtkfwe|PL*pfLN5$U zrJjD~rQmM9NqdQfoFjY7URoP~xI7KLtaZC8C6Wql9Cw1I^&nyfeKE(##yYY&^s7v_ zE?7s8-@!X)I~-V9n$_(-#;6<{yt#;!`ZV2KW8;0hn676=Rp=^4;RWv|j(kqDphZgm z;H^7v-n18`>}mkn$K+J<>!msqnXL!8WevWTtQd|)rKWu7~_Z=o1 zDGz(L$Mi_q4{eZDm->n83mE;NJa=D#{I_&voVH52_9aN66>+G#DMbs@!~**PWNvV z(3Ozi7i$1kfW&$n&69)QQ=MFGMsn?IEYPMUiI`<(uFn{_s+p^g>nQ-U11`ql^4V`n88I+~562`_DbgPIH%vLUwcGpOIL|Vts zLx)*drodu>`LHX9gDve1CRk=ME#HpcB#H?Q|BmJw$i!8`*UlrD;o7O4&c-QZ1ARV3 zh*|I3x$x3irkHOP;iV+znb^~`%uWasPR2S%FhBnZ>BS?;{$bKJ;3;IcUPaC?TOD{4 zm!0sKe0ygyeKu|SF}CSi!zua9>sE?9RIjYi%p$>V>qdg|8=|C(Gr~Hj=0~%y)OOMF zZIUgFqZ-v_o#V$>jY=q+la*(lw~6(bVMnBA9UaA7tgD-^~Q@GHE|e+igrKhvxM zJY((&&KNAqZ}yc~HN!UDS@FX*1qf6p%+Byd6o0+&=y-_lu@G}B_K)p+Vd7nnu{nTQ z$0-Q5Y2q}m1t;+;Nf%I2gY1oV0oU?WOM;rKE0DT7&J}fav;2)2`$6GE>%p;$)O9bn zH}*m#r-K=}>}95Xx>;+FoxzNW7$@%=I84sJ`lL zun{DbRj_nhlcKxm`u>iJKl0{7|GMHv0XacF)B7K9Nbul!v>uLQkBZdxFY_q-& z14U%pX*N!7MZWl?NXK&J*SHa4Dj;kaKenvMX z=OwJwwAne^GwHdib2lc6?zHoaYX`KBn9&s0-dFB^p<83!8<1H?sdM??*=K>jz!BCu z30VOzvJRN;V|$~U zVO?sM>o>09S9jhg-yE+o_&q2C%_v^?X-us4z)S1lZa^8c^~Ima)2ahLP?K>=i=%l5 zE<^?@pGQ^+99M#9jpxBLuSfsHb<03O%7J)De6=}wknWRFZQ6y~b~H~xC#}a=7uEAu zKfv{JB~}aGh9398vo+b}m(4Nxx~8KwE!U)#ZUXXLk@bO(wQ$<_hJ|EwQWXZL%SeN|Am`bWQi*tv=Gd803 zgj@u7_K%1;KBX`1(?JP*u?bs`Z$~z#Y>LX(6Qm;Kg;z73&c%(3tm=)tH)G4!t{;?) z46Nb(518Ql&)C_R&W-8OcCC0-jQ>f0XAOj5|C~W)HgD@)<1A{Ys%(=V3kA4{T(7+7MP$dQeNz8+YV`B=~{zBZd7d;CAZ%$X}Ma&P4qxev{EPysHc!-ti=23Ye4a9BQFrS9JUxNJ<#qDnIt z=mpzl^CbWBC$|D+F7j@T!;C(jf8#SWiAycch8V5zM@y9L!S_XT7hVwpH>3&tnhl#I zX7@IN7A(cMf!7nbFCrc_^O*KJSnw+zL^87J&q<1BHhtO$nHORDmIX$lWUbN=y-^s= z=>SHicyOA6sFD)ZG23OhQ;`R;*@W5qwfege9;14yK}95Sh4BpR$(8}+>1fQV169?& zbG2ZtzI?N-z!lnxPjiQkDk?LjD@y!8j}?B}?W~iW-2T;MLq(wmNYenqIYc9M49k$) zbrTR|PH@QR>lxf2$?ycMg%%x!2~#B`QIZb?%i+SJB>w;=AO8t52L;SHY#E%b^F0h_ z+9*TE*Q}={+yB7tFI$~MMAW6T2Jf-2OnvE?{!YO%VEfY78~rW#n7kW%GdU=E;A~T8 z)VPU(1>p;cGn!TtBQtM#Den39mfzOUC_jQqpLcp6ZO&}JnWhmMP zSy55J!Yxh(ddW`(CUN*kwmp>J!JbEOX;)|ml3c#Iw7dr{_mLUlLa4##6@DuU<0c;k zjRA%$9IpmP%Rid9!FjBCz!cdHMc1lYWgHjGH@}i(8ZlGAXY#Wn+o#%lr1`6jQjsi} zw9ph?P0JM&DTia?gG%akc^`_jX>w;FvXpn{^_&@>_6oixbAoba7=0LdL~+SAwVF-U z;8MXK#%P=kb)DU@uKW8f=Gh;id-hK|Fq!3$^+D(CjDQ(=8ZqCmg;Mf_D&T4#Ef%9N zu5Gt60d)Krw624+LA0S-2p1Ln`0hVdR@|+pNnx!ljEg^N!EV*2$vOXV2C@;18Sq(% zaNVj$BawkTgyRC z727T@cG9OuJV5MO4dC=b`^PftqHhkfgMd!u7d3GWl9w?SH_o(9Dg@nLV}J_^Cmue7 z8j8{JCsM>*y8*q|XTNEa0tYTBA7f#8A7Pp4%$A&`H`(Q+HfIul6*QnS7-`aXy1Djz z7zJB*R!@>ME~P7jfUtW2cN+OrU3R%vdMhXEE`(vt4{l1(Bi@ZJ zuK&PG2KY;+YD{?oKLuT-iKv5;fNz?Ph$4~SnT|~91X}6V`X8v*IOs+{RFBELL-|;rMq8g>Su(Vt$jw!s}mWvB+)pAMKN8ivT$(IGG*uv88rZm*U>an=0+4*J9(QZCl%kL z^3Y5TbnL-Q11wyGE!x{fba`F^}HRWr@~q!+hiY*;yg>|-9(Cv+REWI zLiCdAUONG&7+6X|WIt2$yJ}~|4=&m5bLni(#wj-zB$|sUgkc$mKLet}n&KV@F1GTN z!>@@evmwb@LiBwQx0h9Tm*Q4C7I~LVk)dQ+_<7Q9f2H_ZG&KzL?)nVWbU-7&ru9*R zZQ3jrH+mKU0^=@U7^joPhvY{qejDAWCH{sqIwug^JJ-&EnEfJ?@FtPM-SZlgV|5W> z3cFrw@TQW)ynEoIMAw72;A3{DJKIy;gzL-X`KfpK=B*;02->M1WTB7`?9>RIG*ApC zW&-lCZOnB93_bLFf)|-^F%wQHVzHrxrfMyBw9|9WHvkGl$+pX8C0g*_;6wRH?Nnpy z;?3)2t0V~9@mTqD4VliP<@FnVj514V-0GW!1?aXD_S>e~#m5lmVh3X_Ji#^K8l8eR znG(Hr#kb0@x%W?>rs!7u%+4K~k}qT6%OgbyijO$H+>PahI&X~HoC^Y6rZ+rD$#`&! zsFZn~9^R7-2wtK$nYRu<&j4+>lj7#d^LQ-t%8T5d7HP6ee9WTL4K}^85lLj4#QU~A zftIfiaK!JKGNWNjHRjsG{?hF=96mc~Pr5Or9r1Dy8!BbIlDN;^g7L>06&pN_<=9#iiwpU2hJ__Yz4&;ks0&F5)}k!XxJpE9SnPaRk3G+&;2 z_MNB}_Em1{pK{1T%ZH}!NU&|hdLj$fehO8Zat4NHW?!EKM zM5h?b3y8@;T-g+}p+dxp_Tw-NzsU91vn&d4J748F9#H|Or*=E4+_cl7o1UzAUv?s0c z^Rc+CR4gy(6@?!K4tZ@J#VeZPJS^GBiPn<1m0c$jyPr4w`BxjBQ9kOk9L@3hwr;kV z2%nxaAHO}h`OBp4bvv6^f#@LlE=AeMX~c39wvH1)25~ocYk;F&(kFp}2~4wgS5#Cq zKe~XsNUMm)P^Aezr^5WUk;fou2ZFol)uy06n~T zs2u55X(l(?nAkE19#In2bxR+95ZC`ux#C-fAfl2z{P=afaN9StccSNZQ<;A7n|I|v z+8IpdrnpG;Ep)KAP4SqvReQ?&21EC|<{LNg3#GcQy?u%I@Gq+b?_w7t-b9Of;b>&QU zZih9kt-7SX!GM;VzxmH$c~zYoLA5#_09Hs4GW!bi=%zE}2i~1(e5y4pb9aB$DzPpf z7L`-omOsB!=xo2<>25}1o$jCY-$}UV0hj6Sg$VK~uTp;dH2^2{)?Fu*#`g7+l$QmNG4Q2Lnf2F ziJr!acY}N82VC-C;S9{+#ue3+sP$DfPDTCnTUe@Fb2|J!Nc!ao~^zulPs yUpqV=qQ>0vv#_WfSm7rB^br5N{-0~$+aK$ymqxp~^frEr(!Q^!UZVQ+)&Bs(_~sS> literal 0 HcmV?d00001 diff --git a/extensions/app-tool/values.yaml b/extensions/app-tool/values.yaml new file mode 100644 index 0000000..b381508 --- /dev/null +++ b/extensions/app-tool/values.yaml @@ -0,0 +1,3 @@ +app-tool: + repoUrl: "https://charts.kubesphere.io/stable" + diff --git a/go.mod b/go.mod index 3e04fea..f12269f 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/spf13/cobra v1.8.1 k8s.io/apimachinery v0.31.1 k8s.io/client-go v0.31.1 + sigs.k8s.io/controller-runtime v0.19.0 sigs.k8s.io/yaml v1.4.0 ) diff --git a/go.sum b/go.sum index 4c53253..664c7c5 100644 --- a/go.sum +++ b/go.sum @@ -9,12 +9,16 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -27,6 +31,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= @@ -48,6 +54,10 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/phuslu/log v1.0.112 h1:vQ0ZFd5O+in/0IQAcjuEl6wRkHiQPw7T0sqwmOjpL0U= github.com/phuslu/log v1.0.112/go.mod h1:F8osGJADo5qLK/0F88djWwdyoZZ9xDJQL1HYRHFEkS0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -66,6 +76,10 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -99,6 +113,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -126,6 +142,8 @@ k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7F k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= +sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/main.go b/main.go index 6c4af6a..30c5d37 100644 --- a/main.go +++ b/main.go @@ -9,7 +9,6 @@ import ( "io/ioutil" "net/http" "os" - "path/filepath" "time" "github.com/phuslu/log" @@ -18,7 +17,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" - "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/controller-runtime/pkg/client/config" "sigs.k8s.io/yaml" ) @@ -73,6 +72,15 @@ func main() { Use: "app-tool", Short: "A CLI tool to manage applications", Run: func(cmd *cobra.Command, args []string) { + if token == "" { + log.Info().Msg("Using token from /var/run/secrets/kubesphere.io/serviceaccount/token") + dst := "/var/run/secrets/kubesphere.io/serviceaccount/token" + data, err := os.ReadFile(dst) + if err != nil { + log.Fatal().Msgf("Failed to read token file: %v", err) + } + token = string(data) + } run() }, } @@ -83,7 +91,6 @@ func main() { rootCmd.MarkFlagRequired("server") rootCmd.MarkFlagRequired("repo") - rootCmd.MarkFlagRequired("token") if err := rootCmd.Execute(); err != nil { fmt.Println(err) @@ -135,25 +142,13 @@ func run() { log.Info().Msgf("[4/4] updateAppLabel categoryName completed successfully") } -func initDynamicClient() error { - homeDir, err := os.UserHomeDir() - if err != nil { - log.Error().Msgf("Failed to get home directory: %v", err) - return err - } - kubeconfig := filepath.Join(homeDir, ".kube", "config") - config, err := clientcmd.BuildConfigFromFlags("", kubeconfig) - if err != nil { - log.Error().Msgf("Failed to build config: %v", err) - return err - } - - dynamicClient, err = dynamic.NewForConfig(config) +func initDynamicClient() (err error) { + conf := config.GetConfigOrDie() + dynamicClient, err = dynamic.NewForConfig(conf) if err != nil { log.Error().Msgf("Failed to create dynamic client: %v", err) return err } - log.Info().Msgf("Dynamic client initialized successfully") return nil }