github.com/freiheit-com/kuberpult@v1.24.2-0.20240328135542-315d5630abe6/services/cd-service/pkg/service/version.go (about)

     1  /*This file is part of kuberpult.
     2  
     3  Kuberpult is free software: you can redistribute it and/or modify
     4  it under the terms of the Expat(MIT) License as published by
     5  the Free Software Foundation.
     6  
     7  Kuberpult is distributed in the hope that it will be useful,
     8  but WITHOUT ANY WARRANTY; without even the implied warranty of
     9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  MIT License for more details.
    11  
    12  You should have received a copy of the MIT License
    13  along with kuberpult. If not, see <https://directory.fsf.org/wiki/License:Expat>.
    14  
    15  Copyright 2023 freiheit.com*/
    16  
    17  package service
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"fmt"
    23  	"os"
    24  	"strconv"
    25  
    26  	"github.com/freiheit-com/kuberpult/pkg/grpc"
    27  
    28  	"google.golang.org/grpc/codes"
    29  	"google.golang.org/grpc/status"
    30  	"google.golang.org/protobuf/types/known/timestamppb"
    31  
    32  	api "github.com/freiheit-com/kuberpult/pkg/api/v1"
    33  	"github.com/freiheit-com/kuberpult/services/cd-service/pkg/repository"
    34  	git "github.com/libgit2/git2go/v34"
    35  )
    36  
    37  type VersionServiceServer struct {
    38  	Repository repository.Repository
    39  }
    40  
    41  func (o *VersionServiceServer) GetVersion(
    42  	ctx context.Context,
    43  	in *api.GetVersionRequest) (*api.GetVersionResponse, error) {
    44  	oid, err := git.NewOid(in.GitRevision)
    45  	if err != nil {
    46  		// Note that "not finding a oid" does not mean that it doesn't exist.
    47  		// Because we do a shallow clone, we won't have information on all existing OIDs.
    48  		return nil, grpc.PublicError(ctx, fmt.Errorf("getVersion: could not find revision %v: %v", in.GitRevision, err))
    49  	}
    50  	state, err := o.Repository.StateAt(oid)
    51  	if err != nil {
    52  		var gerr *git.GitError
    53  		if errors.As(err, &gerr) {
    54  			if gerr.Code == git.ErrorCodeNotFound {
    55  				return nil, status.Error(codes.NotFound, "not found")
    56  			}
    57  		}
    58  		return nil, err
    59  	}
    60  	//exhaustruct:ignore
    61  	res := api.GetVersionResponse{}
    62  	version, err := state.GetEnvironmentApplicationVersion(in.Environment, in.Application)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	if version != nil {
    67  		res.Version = *version
    68  		_, deployedAt, err := state.GetDeploymentMetaData(in.Environment, in.Application)
    69  		if err != nil {
    70  			return nil, err
    71  		}
    72  		res.DeployedAt = timestamppb.New(deployedAt)
    73  		release, err := state.GetApplicationRelease(in.Application, *version)
    74  		if err != nil {
    75  			return nil, err
    76  		}
    77  		res.SourceCommitId = release.SourceCommitId
    78  	}
    79  	return &res, nil
    80  }
    81  
    82  func (o *VersionServiceServer) GetManifests(ctx context.Context, req *api.GetManifestsRequest) (*api.GetManifestsResponse, error) {
    83  	if req.Application == "" {
    84  		return nil, status.Error(codes.InvalidArgument, "no application specified")
    85  	}
    86  
    87  	state := o.Repository.State()
    88  
    89  	wrapError := func(what string, err error) error {
    90  		if !os.IsNotExist(err) {
    91  			return status.Errorf(codes.NotFound, "%s not found", what)
    92  		} else {
    93  			return status.Error(codes.Internal, err.Error())
    94  		}
    95  	}
    96  
    97  	var (
    98  		err     error
    99  		release uint64
   100  	)
   101  	if req.Release == "latest" {
   102  		release, err = repository.GetLastRelease(state.Filesystem, req.Application)
   103  		if err != nil {
   104  			return nil, wrapError("application", err)
   105  		}
   106  		if release == 0 {
   107  			return nil, status.Errorf(codes.NotFound, "no releases found for application %s", req.Application)
   108  		}
   109  	} else {
   110  		release, err = strconv.ParseUint(req.Release, 10, 64)
   111  		if err != nil {
   112  			return nil, status.Error(codes.InvalidArgument, "invalid release number, expected uint or 'latest'")
   113  		}
   114  	}
   115  	repoRelease, err := state.GetApplicationRelease(req.Application, release)
   116  	if err != nil {
   117  		return nil, wrapError("release", err)
   118  	}
   119  	manifests, err := state.GetApplicationReleaseManifests(req.Application, release)
   120  	if err != nil {
   121  		return nil, wrapError("manifests", err)
   122  	}
   123  
   124  	return &api.GetManifestsResponse{
   125  		Release:   repoRelease.ToProto(),
   126  		Manifests: manifests,
   127  	}, nil
   128  }