Skip to content

Commit 5f10625

Browse files
committed
RHINENG-20967: verify system's environment with candlepin
1 parent aba1d00 commit 5f10625

5 files changed

Lines changed: 89 additions & 7 deletions

File tree

base/candlepin/candlepin.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ type ConsumersUpdateResponse struct {
2121
Message string `json:"displayMessage"`
2222
}
2323

24+
type ConsumersDetailResponse struct {
25+
Environments []ConsumersEnvironment `json:"environments"`
26+
}
27+
28+
type ConsumersEnvironment struct {
29+
ID string `json:"id"`
30+
}
31+
2432
var ErrCandlepin = errors.New("candlepin error")
2533

2634
var (

deploy/clowdapp.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ objects:
148148
- {name: DB_USER, value: listener}
149149
- {name: DB_PASSWD, valueFrom: {secretKeyRef: {name: patchman-engine-database-passwords,
150150
key: listener-database-password}}}
151+
- {name: CANDLEPIN_ADDRESS, value: '${CANDLEPIN_ADDRESS}'}
152+
- {name: CANDLEPIN_CERT, valueFrom: {secretKeyRef: {name: candlepin, key: cert}}}
153+
- {name: CANDLEPIN_KEY, valueFrom: {secretKeyRef: {name: candlepin, key: key}}}
154+
- {name: CANDLEPIN_CA, valueFrom: {secretKeyRef: {name: candlepin, key: ca}}}
151155
- {name: KAFKA_GROUP, value: patchman}
152156
- {name: KAFKA_READER_MAX_ATTEMPTS, value: '${KAFKA_READER_MAX_ATTEMPTS}'}
153157
- {name: KAFKA_WRITER_MAX_ATTEMPTS, value: '${KAFKA_WRITER_MAX_ATTEMPTS}'}

listener/rhsm.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package listener
22

33
import (
4+
"app/base/candlepin"
45
"app/base/models"
56
"app/base/utils"
7+
"context"
8+
"net/http"
69

10+
"github.com/pkg/errors"
711
"gorm.io/gorm"
812
)
913

@@ -37,3 +41,27 @@ func getTemplate(db *gorm.DB, accountID int, environments []string) (*int64, err
3741
}
3842
return templateID, nil
3943
}
44+
45+
func callCandlepinEnvironment(ctx context.Context, consumer string) (
46+
*candlepin.ConsumersDetailResponse, error) {
47+
candlepinEnvConsumersURL := utils.CoreCfg.CandlepinAddress + "/consumers/" + consumer
48+
candlepinFunc := func() (interface{}, *http.Response, error) {
49+
candlepinResp := candlepin.ConsumersDetailResponse{}
50+
resp, err := candlepinClient.Request(&ctx, http.MethodGet, candlepinEnvConsumersURL, nil, &candlepinResp)
51+
statusCode := utils.TryGetStatusCode(resp)
52+
utils.LogDebug("candlepin_url", candlepinEnvConsumersURL, "status_code", statusCode, "err", err)
53+
if err != nil {
54+
err = errors.Wrap(candlepin.ErrCandlepin, err.Error())
55+
} else if statusCode != http.StatusOK && statusCode != http.StatusNoContent {
56+
err = errors.Errorf("candlepin API status %d", statusCode)
57+
}
58+
return &candlepinResp, resp, err
59+
}
60+
61+
candlepinRespPtr, err := utils.HTTPCallRetry(candlepinFunc,
62+
candlepin.CandlepinExpRetries, candlepin.CandlepinRetries, http.StatusServiceUnavailable)
63+
if err != nil {
64+
return nil, errors.Wrap(err, "candlepin /consumers call failed")
65+
}
66+
return candlepinRespPtr.(*candlepin.ConsumersDetailResponse), nil
67+
}

listener/upload.go

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package listener
33
import (
44
"app/base"
55
"app/base/api"
6+
"app/base/candlepin"
67
"app/base/database"
78
"app/base/inventory"
89
"app/base/models"
@@ -50,6 +51,7 @@ const (
5051
RepoPathPattern = "(/content/.*)"
5152
RepoBasearchPlaceholder = "$basearch"
5253
RepoReleaseverPlaceholder = "$releasever"
54+
TemplateRepoPattern = `^https://cert\.console.*/api/pulp-content/(cs-)?[[:xdigit:]]+/templates/`
5355
)
5456

5557
var (
@@ -63,10 +65,12 @@ var (
6365
)
6466

6567
var (
66-
repoPathRegex = regexp.MustCompile(RepoPathPattern)
67-
spacesRegex = regexp.MustCompile(`^\s*$`)
68-
httpClient *api.Client
69-
metricByErr = map[error]string{
68+
repoPathRegex = regexp.MustCompile(RepoPathPattern)
69+
spacesRegex = regexp.MustCompile(`^\s*$`)
70+
templateRepoPath = regexp.MustCompile(TemplateRepoPattern)
71+
httpClient *api.Client
72+
candlepinClient = candlepin.CreateCandlepinClient()
73+
metricByErr = map[error]string{
7074
ErrNoPackages: ReceivedWarnNoPackages,
7175
ErrReporter: ReceivedWarnExcludedReporter,
7276
ErrHostType: ReceivedWarnExcludedHostType,
@@ -328,12 +332,25 @@ func updateReporterCounter(reporter string) {
328332

329333
func hostTemplate(tx *gorm.DB, accountID int, host *Host) *int64 {
330334
var templateID *int64
331-
var err error
332-
if host.Reporter == rhsmReporter || host.Reporter == puptooReporter {
333-
templateID, err = getTemplate(tx, accountID, host.SystemProfile.Rhsm.Environments)
335+
336+
if hasTemplateRepo(&host.SystemProfile) {
337+
// check system's env in candlepin
338+
resp, err := callCandlepinEnvironment(base.Context, host.SystemProfile.ConsumerID)
334339
if err != nil {
335340
utils.LogWarn("inventoryID", host.ID, "err", errors.Wrap(err, "Unable to assign templates"))
336341
}
342+
343+
// get template from candlepin
344+
if resp != nil {
345+
envs := make([]string, 0, len(resp.Environments))
346+
for _, env := range resp.Environments {
347+
envs = append(envs, env.ID)
348+
}
349+
templateID, err = getTemplate(tx, accountID, envs)
350+
if err != nil {
351+
utils.LogWarn("inventoryID", host.ID, "err", errors.Wrap(err, "Unable to assign templates"))
352+
}
353+
}
337354
}
338355
return templateID
339356
}
@@ -640,6 +657,16 @@ func getRepoPath(systemProfile *inventory.SystemProfile, repo *inventory.YumRepo
640657
return repoPath, nil
641658
}
642659

660+
func hasTemplateRepo(systemProfile *inventory.SystemProfile) bool {
661+
yumRepos := systemProfile.GetYumRepos()
662+
for _, r := range yumRepos {
663+
if r.Enabled && templateRepoPath.MatchString(r.BaseURL) {
664+
return true
665+
}
666+
}
667+
return false
668+
}
669+
643670
func processRepos(systemProfile *inventory.SystemProfile) ([]string, []string) {
644671
yumRepos := systemProfile.GetYumRepos()
645672
seen := make(map[string]bool, len(yumRepos))

platform/candlepin.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io"
88
"net/http"
99
"slices"
10+
"strings"
1011

1112
"github.com/gin-gonic/gin"
1213
)
@@ -22,6 +23,19 @@ func candlepinConsumersPutHandler(c *gin.Context) {
2223
c.Data(http.StatusOK, gin.MIMEJSON, []byte{})
2324
}
2425

26+
func candlepinConsumersGetHandler(c *gin.Context) {
27+
consumer := c.Param("consumer")
28+
utils.LogInfo("GET consumer", consumer, "body")
29+
env := strings.ReplaceAll(consumer, "-", "")
30+
env = strings.Replace(env, "000", "999", 1)
31+
response := candlepin.ConsumersDetailResponse{
32+
Environments: []candlepin.ConsumersEnvironment{
33+
{ID: env},
34+
},
35+
}
36+
c.JSON(http.StatusOK, response)
37+
}
38+
2539
func candlepinConsumersEnvironmentsHandler(c *gin.Context) {
2640
owner := c.Param("owner")
2741
jsonData, _ := io.ReadAll(c.Request.Body)
@@ -42,5 +56,6 @@ func candlepinConsumersEnvironmentsHandler(c *gin.Context) {
4256

4357
func initCandlepin(app *gin.Engine) {
4458
app.PUT("/candlepin/consumers/:consumer", candlepinConsumersPutHandler)
59+
app.GET("/candlepin/consumers/:consumer", candlepinConsumersGetHandler)
4560
app.PUT("/candlepin/owners/:owner/consumers/environments", candlepinConsumersEnvironmentsHandler)
4661
}

0 commit comments

Comments
 (0)