• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender-server / 1495380963

14 Oct 2024 03:35PM UTC coverage: 70.373% (-2.5%) from 72.904%
1495380963

Pull #101

gitlab-ci

mineralsfree
feat: tenant list added

Ticket: MEN-7568
Changelog: None

Signed-off-by: Mikita Pilinka <mikita.pilinka@northern.tech>
Pull Request #101: feat: tenant list added

4406 of 6391 branches covered (68.94%)

Branch coverage included in aggregate %.

88 of 183 new or added lines in 10 files covered. (48.09%)

2623 existing lines in 65 files now uncovered.

36673 of 51982 relevant lines covered (70.55%)

31.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.86
/backend/services/create-artifact-worker/client/deployments.go
1
// Copyright 2021 Northern.tech AS
2
//
3
//        Licensed under the Apache License, Version 2.0 (the "License");
4
//        you may not use this file except in compliance with the License.
5
//        You may obtain a copy of the License at
6
//
7
//            http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//        Unless required by applicable law or agreed to in writing, software
10
//        distributed under the License is distributed on an "AS IS" BASIS,
11
//        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//        See the License for the specific language governing permissions and
13
//        limitations under the License.
14
package client
15

16
import (
17
        "bytes"
18
        "context"
19
        "crypto/tls"
20
        "encoding/json"
21
        "fmt"
22
        "io"
23
        "mime/multipart"
24
        "net/http"
25
        "os"
26
        "path/filepath"
27
        "time"
28

29
        "github.com/pkg/errors"
30
)
31

32
const (
33
        uriInternalUpload = "/api/internal/v1/deployments/tenants/{id}/artifacts"
34
)
35

36
var (
37
        timeoutSec = 900 * time.Second
38
)
39

40
type Deployments interface {
41
        UploadArtifactInternal(ctx context.Context, path, aid, tid, desc string) error
42
}
43

44
type deployments struct {
45
        deplUrl string
46
        c       *http.Client
47
}
48

49
func NewDeployments(deplUrl string, skipSsl bool) (Deployments, error) {
1✔
50
        tr := &http.Transport{
1✔
51
                TLSClientConfig: &tls.Config{
1✔
52
                        InsecureSkipVerify: skipSsl,
1✔
53
                },
1✔
54
        }
1✔
55

1✔
56
        c := &http.Client{
1✔
57
                Transport: tr,
1✔
58
        }
1✔
59

1✔
60
        return &deployments{
1✔
61
                deplUrl: deplUrl,
1✔
62
                c:       c,
1✔
63
        }, nil
1✔
64
}
1✔
65

66
func (d *deployments) UploadArtifactInternal(
67
        ctx context.Context,
68
        fpath,
69
        aid,
70
        tid,
71
        desc string,
72
) error {
1✔
73
        ctx, cancel := context.WithTimeout(ctx, timeoutSec)
1✔
74
        defer cancel()
1✔
75

1✔
76
        artifact, err := os.Open(fpath)
1✔
77
        if err != nil {
1✔
78
                return errors.Wrapf(err, "cannot read artifact file %s", fpath)
×
79
        }
×
80
        defer artifact.Close()
1✔
81

1✔
82
        body := &bytes.Buffer{}
1✔
83

1✔
84
        writer := multipart.NewWriter(body)
1✔
85

1✔
86
        _ = writer.WriteField("id", tid)
1✔
87
        _ = writer.WriteField("artifact_id", aid)
1✔
88
        _ = writer.WriteField("description", desc)
1✔
89

1✔
90
        part, err := writer.CreateFormFile("artifact", filepath.Base(fpath))
1✔
91
        if err != nil {
1✔
92
                return errors.Wrap(err, "cannot create artifact upload request")
×
93
        }
×
94

95
        _, err = io.Copy(part, artifact)
1✔
96
        if err != nil {
1✔
97
                return errors.Wrap(err, "cannot create artifact upload request")
×
98
        }
×
99

100
        err = writer.Close()
1✔
101
        if err != nil {
1✔
102
                return errors.Wrap(err, "cannot create artifact upload request")
×
103
        }
×
104

105
        if tid == "" {
1✔
UNCOV
106
                tid = "default"
×
UNCOV
107
        }
×
108

109
        url, err := join(d.deplUrl, uriInternalUpload, map[string]string{"id": tid})
1✔
110
        if err != nil {
1✔
111
                return err
×
112
        }
×
113

114
        req, err := http.NewRequest(http.MethodPost,
1✔
115
                url,
1✔
116
                body)
1✔
117
        if err != nil {
1✔
118
                return errors.Wrap(err, "cannot create artifact upload request")
×
119
        }
×
120

121
        req = req.WithContext(ctx)
1✔
122

1✔
123
        req.Header.Set("Content-Type", writer.FormDataContentType())
1✔
124

1✔
125
        res, err := d.c.Do(req)
1✔
126
        if err != nil {
1✔
127
                return errors.Wrapf(err, "failed to upload artifact %s", aid)
×
128
        }
×
129
        defer res.Body.Close()
1✔
130

1✔
131
        if res.StatusCode != http.StatusCreated {
2✔
132
                return errors.Wrapf(apiErr(res), "failed to upload artifact %s", aid)
1✔
133
        }
1✔
134

135
        return nil
1✔
136
}
137

138
func apiErr(r *http.Response) error {
1✔
139
        e := struct {
1✔
140
                Reqid string `json:"request_id"`
1✔
141
                Msg   string `json:"error"`
1✔
142
        }{}
1✔
143

1✔
144
        err := json.NewDecoder(r.Body).Decode(&e)
1✔
145
        if err != nil {
1✔
146
                return errors.New(fmt.Sprintf(
×
147
                        "got error code %d from api but failed to decode response",
×
148
                        r.StatusCode,
×
149
                ))
×
150
        }
×
151

152
        return errors.New(fmt.Sprintf("http %d, reqid: %s, msg: %s", r.StatusCode, e.Reqid, e.Msg))
1✔
153
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc