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

mendersoftware / iot-manager / 1445709825

09 Sep 2024 11:23AM UTC coverage: 86.917% (-0.3%) from 87.172%
1445709825

Pull #303

gitlab-ci

alfrunes
ci: update gitlab runner

Moving to deprecated docker gitlab public runner, to a self-hosted runner

Ticket: SEC-1133
Changelog: none

Signed-off-by: Roberto Giovanardi <roberto.giovanardi@northern.tech>
(cherry picked from commit bb026f77c)
Pull Request #303: Cherry-pick MEN-7478 to 1.3.x (3.7.x)

42 of 54 new or added lines in 2 files covered. (77.78%)

128 existing lines in 10 files now uncovered.

3169 of 3646 relevant lines covered (86.92%)

9.75 hits per line

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

96.88
/api/http/router.go
1
// Copyright 2023 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

15
package http
16

17
import (
18
        "context"
19
        "net/http"
20
        "time"
21

22
        "github.com/gin-gonic/gin"
23
        "github.com/gin-gonic/gin/binding"
24
        "github.com/pkg/errors"
25

26
        "github.com/mendersoftware/go-lib-micro/accesslog"
27
        "github.com/mendersoftware/go-lib-micro/identity"
28
        "github.com/mendersoftware/go-lib-micro/log"
29
        "github.com/mendersoftware/go-lib-micro/requestid"
30
        "github.com/mendersoftware/go-lib-micro/rest.utils"
31

32
        "github.com/mendersoftware/iot-manager/app"
33
)
34

35
// API URL used by the HTTP router
36
const (
37
        APIURLInternal = "/api/internal/v1/iot-manager"
38

39
        APIURLAlive             = "/alive"
40
        APIURLHealth            = "/health"
41
        APIURLTenants           = "/tenants"
42
        APIURLTenant            = APIURLTenants + "/:tenant_id"
43
        APIURLTenantAuth        = APIURLTenant + "/auth"
44
        APIURLTenantDevices     = APIURLTenant + "/devices"
45
        APIURLTenantDevice      = APIURLTenantDevices + "/:device_id"
46
        APIURLTenantBulkDevices = APIURLTenant + "/bulk/devices"
47
        APIURLTenantBulkStatus  = APIURLTenantBulkDevices + "/status/:status"
48

49
        APIURLManagement = "/api/management/v1/iot-manager"
50

51
        APIURLIntegrations           = "/integrations"
52
        APIURLIntegration            = "/integrations/:id"
53
        APIURLIntegrationCredentials = APIURLIntegration + "/credentials"
54

55
        APIURLDevice                 = "/devices/:id"
56
        APIURLDeviceState            = APIURLDevice + "/state"
57
        APIURLDeviceStateIntegration = APIURLDevice + "/state/:integrationId"
58

59
        APIURLEvents = "/events"
60
)
61

62
const (
63
        defaultTimeout = time.Second * 10
64
)
65

66
type Config struct {
67
        Client *http.Client
68
}
69

70
// NewConfig initializes a new empty config and optionally merges the
71
// configurations provided as argument.
72
func NewConfig(configs ...*Config) *Config {
151✔
73
        var config = new(Config)
151✔
74
        for _, conf := range configs {
228✔
75
                if conf == nil {
78✔
76
                        continue
1✔
77
                }
78
                if conf.Client != nil {
78✔
79
                        config.Client = conf.Client
2✔
80
                }
2✔
81
        }
82
        return config
151✔
83
}
84

85
func (conf *Config) SetClient(client *http.Client) *Config {
1✔
86
        conf.Client = client
1✔
87
        return conf
1✔
88
}
1✔
89

90
// NewRouter returns the gin router
91
func NewRouter(
92
        app app.App,
93
        config ...*Config,
94
) *gin.Engine {
75✔
95
        conf := NewConfig(config...)
75✔
96
        gin.SetMode(gin.ReleaseMode)
75✔
97
        gin.DisableConsoleColor()
75✔
98
        handler := NewAPIHandler(app, conf)
75✔
99
        internal := (*InternalHandler)(handler)
75✔
100
        management := (*ManagementHandler)(handler)
75✔
101

75✔
102
        router := gin.New()
75✔
103
        router.Use(accesslog.Middleware())
75✔
104
        router.Use(requestid.Middleware())
75✔
105

75✔
106
        router.NoRoute(handler.NoRoute)
75✔
107

75✔
108
        internalAPI := router.Group(APIURLInternal)
75✔
109
        internalAPI.GET(APIURLAlive, handler.Alive)
75✔
110
        internalAPI.GET(APIURLHealth, handler.Health)
75✔
111

75✔
112
        internalAPI.POST(APIURLTenantDevices, internal.ProvisionDevice)
75✔
113
        internalAPI.DELETE(APIURLTenantDevice, internal.DecommissionDevice)
75✔
114
        internalAPI.PUT(APIURLTenantBulkStatus, internal.BulkSetDeviceStatus)
75✔
115

75✔
116
        internalAPI.POST(APIURLTenantAuth, internal.PreauthorizeHandler)
75✔
117

75✔
118
        managementAPI := router.Group(APIURLManagement, identity.Middleware())
75✔
119
        managementAPI.GET(APIURLIntegrations, management.GetIntegrations)
75✔
120
        managementAPI.GET(APIURLIntegration, management.GetIntegrationById)
75✔
121
        managementAPI.POST(APIURLIntegrations, management.CreateIntegration)
75✔
122
        managementAPI.PUT(APIURLIntegrationCredentials, management.SetIntegrationCredentials)
75✔
123
        managementAPI.DELETE(APIURLIntegration, management.RemoveIntegration)
75✔
124

75✔
125
        managementAPI.GET(APIURLDeviceState, management.GetDeviceState)
75✔
126
        managementAPI.GET(APIURLDeviceStateIntegration, management.GetDeviceStateIntegration)
75✔
127
        managementAPI.PUT(APIURLDeviceStateIntegration, management.SetDeviceStateIntegration)
75✔
128

75✔
129
        managementAPI.GET(APIURLEvents, management.GetEvents)
75✔
130

75✔
131
        return router
75✔
132
}
75✔
133

134
type APIHandler struct {
135
        *http.Client
136
        app app.App
137
}
138

139
func NewAPIHandler(app app.App, config ...*Config) *APIHandler {
75✔
140
        conf := NewConfig(config...)
75✔
141
        if conf.Client == nil {
149✔
142
                conf.Client = new(http.Client)
74✔
143
        }
74✔
144
        return &APIHandler{
75✔
145
                Client: conf.Client,
75✔
146
                app:    app,
75✔
147
        }
75✔
148
}
149

150
// Alive responds to GET /alive
151
func (h *APIHandler) Alive(c *gin.Context) {
1✔
152
        c.Writer.WriteHeader(http.StatusNoContent)
1✔
153
}
1✔
154

155
// Health responds to GET /health
156
func (h *APIHandler) Health(c *gin.Context) {
2✔
157
        ctx := c.Request.Context()
2✔
158
        l := log.FromContext(ctx)
2✔
159
        ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
2✔
160
        defer cancel()
2✔
161

2✔
162
        err := h.app.HealthCheck(ctx)
2✔
163
        if err != nil {
3✔
164
                l.Error(errors.Wrap(err, "health check failed"))
1✔
165
                c.JSON(http.StatusServiceUnavailable, gin.H{
1✔
166
                        "error": err.Error(),
1✔
167
                })
1✔
168
                return
1✔
169
        }
1✔
170

171
        c.Writer.WriteHeader(http.StatusNoContent)
1✔
172
}
173

174
func (h *APIHandler) NoRoute(c *gin.Context) {
1✔
175
        c.JSON(http.StatusNotFound, rest.Error{
1✔
176
                Err:       "not found",
1✔
177
                RequestID: requestid.FromContext(c.Request.Context()),
1✔
178
        })
1✔
179
}
1✔
180

181
// Make gin-gonic use validatable structs instead of relying on go-playground
182
// validator interface.
183
type validateValidatableValidator struct{}
184

185
func (validateValidatableValidator) ValidateStruct(obj interface{}) error {
29✔
186
        if v, ok := obj.(interface{ Validate() error }); ok {
41✔
187
                return v.Validate()
12✔
188
        }
12✔
189
        return nil
17✔
190
}
191

UNCOV
192
func (validateValidatableValidator) Engine() interface{} {
×
193
        return nil
×
194
}
×
195

196
func init() {
3✔
197
        binding.Validator = validateValidatableValidator{}
3✔
198
}
3✔
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