Skip to content

Commit 5ffcf35

Browse files
committed
HMS-5913: add package dates from RHEL lifecycle
1 parent b502037 commit 5ffcf35

File tree

9 files changed

+482
-33
lines changed

9 files changed

+482
-33
lines changed

pkg/cache/cache.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ type Cache interface {
2828

2929
GetRoadmapAppstreams(ctx context.Context) ([]byte, error)
3030
SetRoadmapAppstreams(ctx context.Context, roadmapAppstreamsResponse []byte)
31+
32+
GetRoadmapRhelLifecycle(ctx context.Context) ([]byte, error)
33+
SetRoadmapRhelLifecycle(ctx context.Context, rhelLifecyleResponse []byte)
3134
}
3235

3336
func Initialize() Cache {

pkg/cache/cache_mock.go

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cache/noop.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,12 @@ func (c *noOpCache) GetRoadmapAppstreams(ctx context.Context) ([]byte, error) {
6464
// SetRoadmapAppstreams a NoOp version to store cached roadmap appstreams check
6565
func (c *noOpCache) SetRoadmapAppstreams(ctx context.Context, response []byte) {
6666
}
67+
68+
// GetRoadmapAppstreams a NoOp version to fetch a cached roadmap rhel lifecycle check
69+
func (c *noOpCache) GetRoadmapRhelLifecycle(ctx context.Context) ([]byte, error) {
70+
return nil, NotFound
71+
}
72+
73+
// SetRoadmapAppstreams a NoOp version to store cached roadmap rhel lifecycle check
74+
func (c *noOpCache) SetRoadmapRhelLifecycle(ctx context.Context, response []byte) {
75+
}

pkg/cache/redis.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ func roadmapAppstreamsKey(ctx context.Context) string {
6161
return fmt.Sprintf("roadmap-appstreams:%v", identity.Identity.OrgID)
6262
}
6363

64+
func roadmapRhelLifecycleKey(ctx context.Context) string {
65+
identity := identity.GetIdentity(ctx)
66+
return fmt.Sprintf("roadmap-rhel-lifecycle:%v", identity.Identity.OrgID)
67+
}
68+
6469
// GetAccessList uses the request context to read user information, and then tries to retrieve the role AccessList from the cache
6570
func (c *redisCache) GetAccessList(ctx context.Context) (rbac.AccessList, error) {
6671
accessList := rbac.AccessList{}
@@ -187,6 +192,20 @@ func (c *redisCache) SetRoadmapAppstreams(ctx context.Context, response []byte)
187192
c.client.Set(ctx, key, string(response), config.Get().Clients.Redis.Expiration.SubscriptionCheck)
188193
}
189194

195+
func (c *redisCache) GetRoadmapRhelLifecycle(ctx context.Context) ([]byte, error) {
196+
key := roadmapRhelLifecycleKey(ctx)
197+
buf, err := c.get(ctx, key)
198+
if err != nil {
199+
return nil, fmt.Errorf("redis get error: %w", err)
200+
}
201+
return buf, nil
202+
}
203+
204+
func (c *redisCache) SetRoadmapRhelLifecycle(ctx context.Context, response []byte) {
205+
key := roadmapRhelLifecycleKey(ctx)
206+
c.client.Set(ctx, key, string(response), config.Get().Clients.Redis.Expiration.SubscriptionCheck)
207+
}
208+
190209
func (c *redisCache) get(ctx context.Context, key string) ([]byte, error) {
191210
cmd := c.client.Get(ctx, key)
192211
if errors.Is(cmd.Err(), redis.Nil) {

pkg/clients/roadmap_client/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import (
1313

1414
type RoadmapClient interface {
1515
GetAppstreams(ctx context.Context) (AppstreamsResponse, int, error)
16+
GetRhelLifecycle(ctx context.Context) (LifecycleResponse, int, error)
17+
GetRhelLifecycleForLatestMajorVersions(ctx context.Context) (map[int]LifecycleEntity, error)
1618
}
1719

1820
type roadmapClient struct {

pkg/clients/roadmap_client/roadmap.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"io"
1010
"net/http"
11+
"time"
1112

1213
"github.com/content-services/content-sources-backend/pkg/api"
1314
"github.com/content-services/content-sources-backend/pkg/cache"
@@ -35,6 +36,18 @@ type AppstreamEntity struct {
3536
Impl string `json:"impl"`
3637
}
3738

39+
type LifecycleResponse struct {
40+
Data []LifecycleEntity `json:"data"`
41+
}
42+
43+
type LifecycleEntity struct {
44+
Name string `json:"name"`
45+
Start string `json:"start"`
46+
End string `json:"end"`
47+
Major int `json:"major"`
48+
Minor int `json:"minor"`
49+
}
50+
3851
func encodedIdentity(ctx context.Context) (string, error) {
3952
id := identity.GetIdentity(ctx)
4053
jsonIdentity, err := json.Marshal(id)
@@ -107,3 +120,89 @@ func (rc roadmapClient) GetAppstreams(ctx context.Context) (AppstreamsResponse,
107120

108121
return appStreamResp, statusCode, nil
109122
}
123+
124+
func (rc roadmapClient) GetRhelLifecycle(ctx context.Context) (LifecycleResponse, int, error) {
125+
statusCode := http.StatusInternalServerError
126+
server := config.Get().Clients.Roadmap.Server
127+
var err error
128+
var lifecycleResponse LifecycleResponse
129+
var body []byte
130+
131+
appstreams, err := rc.cache.GetRoadmapRhelLifecycle(ctx)
132+
if err != nil && !errors.Is(err, cache.NotFound) {
133+
log.Error().Err(err).Msg("GetAppstreams - error reading from cache")
134+
}
135+
if appstreams != nil {
136+
err = json.Unmarshal(appstreams, &lifecycleResponse)
137+
if err != nil {
138+
return LifecycleResponse{}, statusCode, fmt.Errorf("error during unmarshal response body: %w", err)
139+
}
140+
return lifecycleResponse, http.StatusOK, nil
141+
}
142+
143+
fullPath := server + "/lifecycle/rhel"
144+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullPath, nil)
145+
if err != nil {
146+
return LifecycleResponse{}, statusCode, fmt.Errorf("error building request: %w", err)
147+
}
148+
149+
if config.Get().Clients.Roadmap.Username != "" && config.Get().Clients.Roadmap.Password != "" {
150+
req.SetBasicAuth(config.Get().Clients.Roadmap.Username, config.Get().Clients.Roadmap.Password)
151+
}
152+
153+
encodedXRHID, err := encodedIdentity(ctx)
154+
if err != nil {
155+
return LifecycleResponse{}, statusCode, fmt.Errorf("error getting encoded XRHID: %w", err)
156+
}
157+
req.Header.Set(api.IdentityHeader, encodedXRHID)
158+
159+
resp, err := rc.client.Do(req)
160+
if resp != nil {
161+
defer resp.Body.Close()
162+
163+
body, err = io.ReadAll(resp.Body)
164+
if err != nil {
165+
return LifecycleResponse{}, statusCode, fmt.Errorf("error reading response body: %w", err)
166+
}
167+
if resp.StatusCode != 0 {
168+
statusCode = resp.StatusCode
169+
}
170+
}
171+
if err != nil {
172+
return LifecycleResponse{}, statusCode, fmt.Errorf("error sending request: %w", err)
173+
}
174+
if statusCode < 200 || statusCode >= 300 {
175+
return LifecycleResponse{}, statusCode, fmt.Errorf("unexpected status code with body: %s", string(body))
176+
}
177+
178+
rc.cache.SetRoadmapRhelLifecycle(ctx, body)
179+
180+
err = json.Unmarshal(body, &lifecycleResponse)
181+
if err != nil {
182+
return LifecycleResponse{}, statusCode, fmt.Errorf("error during unmarshal response body: %w", err)
183+
}
184+
185+
return lifecycleResponse, statusCode, nil
186+
}
187+
188+
func (rc roadmapClient) GetRhelLifecycleForLatestMajorVersions(ctx context.Context) (map[int]LifecycleEntity, error) {
189+
lifecycleResp, _, err := rc.GetRhelLifecycle(ctx)
190+
if err != nil {
191+
return nil, err
192+
}
193+
194+
currentDate := time.Now().UTC().Truncate(24 * time.Hour)
195+
rhelEolMap := make(map[int]LifecycleEntity)
196+
for _, item := range lifecycleResp.Data {
197+
startDate, err := time.Parse("2006-01-02", item.Start)
198+
if err != nil {
199+
return nil, err
200+
}
201+
if startDate.Before(currentDate) || startDate.Equal(currentDate) {
202+
if existing, found := rhelEolMap[item.Major]; !found || (item.Minor > existing.Minor) {
203+
rhelEolMap[item.Major] = item
204+
}
205+
}
206+
}
207+
return rhelEolMap, nil
208+
}

pkg/clients/roadmap_client/roadmap_client_mock.go

Lines changed: 65 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)