Files
kubesphere/pkg/kapis/application/v2/handler_repo.go
KubeSphere CI Bot bb60d39434 Support manual triggering of a repository update. (#6414)
* Support manual triggering of a repository update.

* cherry pick add api for workload template (#1982)

* cherry pick (add operator application (#1970))

* Modify routing implementation to improve readability

* cherry pick from kse dfc40e5adf5aa2e67d1

* Filter by Routing Parameter Namespace (#1990)

* add doc for workloadtemplates

---------

Co-authored-by: inksnw <inksnw@gmail.com>
2025-03-11 11:36:02 +08:00

188 lines
5.0 KiB
Go

/*
* Please refer to the LICENSE file in the root directory of the project.
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
*/
package v2
import (
"fmt"
"net/url"
k8suitl "kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/simple/client/application"
"kubesphere.io/kubesphere/pkg/api"
"github.com/emicklei/go-restful/v3"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/klog/v2"
appv2 "kubesphere.io/api/application/v2"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/utils/stringutils"
)
func (h *appHandler) CreateOrUpdateRepo(req *restful.Request, resp *restful.Response) {
repoRequest := &appv2.Repo{}
err := req.ReadEntity(repoRequest)
if requestDone(err, resp) {
return
}
if repoRequest.Name == appv2.UploadRepoKey {
api.HandleBadRequest(resp, req, fmt.Errorf("repo name %s is not allowed", appv2.UploadRepoKey))
return
}
repoId := req.PathParameter("repo")
if repoId == "" {
repoId = repoRequest.Name
}
parsedUrl, err := url.Parse(repoRequest.Spec.Url)
if requestDone(err, resp) {
return
}
if parsedUrl.User != nil {
repoRequest.Spec.Credential.Username = parsedUrl.User.Username()
repoRequest.Spec.Credential.Password, _ = parsedUrl.User.Password()
}
_, err = application.LoadRepoIndex(repoRequest.Spec.Url, repoRequest.Spec.Credential)
if requestDone(err, resp) {
return
}
if req.QueryParameter("validate") != "" {
data := map[string]any{"ok": true}
resp.WriteAsJson(data)
return
}
repo := &appv2.Repo{}
repo.Name = repoId
if h.conflictedDone(req, resp, "repo", repo) {
return
}
mutateFn := func() error {
repo.Spec = appv2.RepoSpec{
Url: parsedUrl.String(),
SyncPeriod: repoRequest.Spec.SyncPeriod,
Description: stringutils.ShortenString(repoRequest.Spec.Description, 512),
}
if parsedUrl.User != nil {
repo.Spec.Credential.Username = parsedUrl.User.Username()
repo.Spec.Credential.Password, _ = parsedUrl.User.Password()
}
if repo.GetLabels() == nil {
repo.SetLabels(map[string]string{})
}
repo.Labels[constants.WorkspaceLabelKey] = repoRequest.Labels[constants.WorkspaceLabelKey]
if repo.GetAnnotations() == nil {
repo.SetAnnotations(map[string]string{})
}
ant := repoRequest.GetAnnotations()
repo.Annotations[constants.DisplayNameAnnotationKey] = ant[constants.DisplayNameAnnotationKey]
return nil
}
_, err = controllerutil.CreateOrUpdate(req.Request.Context(), h.client, repo, mutateFn)
if requestDone(err, resp) {
return
}
data := map[string]interface{}{"repo_id": repoId}
resp.WriteAsJson(data)
}
func (h *appHandler) DeleteRepo(req *restful.Request, resp *restful.Response) {
repoId := req.PathParameter("repo")
err := h.client.Delete(req.Request.Context(), &appv2.Repo{ObjectMeta: metav1.ObjectMeta{Name: repoId}})
if requestDone(err, resp) {
return
}
klog.V(4).Info("delete repo: ", repoId)
resp.WriteEntity(errors.None)
}
func (h *appHandler) ManualSync(req *restful.Request, resp *restful.Response) {
repoId := req.PathParameter("repo")
key := runtimeclient.ObjectKey{Name: repoId}
repo := &appv2.Repo{}
err := h.client.Get(req.Request.Context(), key, repo)
if requestDone(err, resp) {
return
}
repo.Status.State = appv2.StatusManualTrigger
err = h.client.Status().Update(req.Request.Context(), repo)
if err != nil {
api.HandleInternalError(resp, nil, err)
return
}
resp.WriteEntity(errors.None)
}
func (h *appHandler) DescribeRepo(req *restful.Request, resp *restful.Response) {
repoId := req.PathParameter("repo")
key := runtimeclient.ObjectKey{Name: repoId}
repo := &appv2.Repo{}
err := h.client.Get(req.Request.Context(), key, repo)
if requestDone(err, resp) {
return
}
repo.SetManagedFields(nil)
resp.WriteEntity(repo)
}
func (h *appHandler) ListRepos(req *restful.Request, resp *restful.Response) {
helmRepoList := &appv2.RepoList{}
err := h.client.List(req.Request.Context(), helmRepoList)
if requestDone(err, resp) {
return
}
workspace := req.PathParameter("workspace")
filteredList := &appv2.RepoList{}
for _, repo := range helmRepoList.Items {
allowList := []string{appv2.SystemWorkspace, workspace}
if !stringutils.StringIn(repo.Labels[constants.WorkspaceLabelKey], allowList) {
continue
}
filteredList.Items = append(filteredList.Items, repo)
}
resp.WriteEntity(k8suitl.ConvertToListResult(filteredList, req))
}
func (h *appHandler) ListRepoEvents(req *restful.Request, resp *restful.Response) {
repoId := req.PathParameter("repo")
list := v1.EventList{}
selector := fields.SelectorFromSet(fields.Set{
"involvedObject.name": repoId,
})
opt := &runtimeclient.ListOptions{FieldSelector: selector}
err := h.client.List(req.Request.Context(), &list, opt)
if requestDone(err, resp) {
return
}
resp.WriteEntity(k8suitl.ConvertToListResult(&list, req))
}