PK���ȼRY��������€��� �v3.phpUT �øŽg‰gñ“gux �õ��õ��½T]kÛ0}߯pEhìâÙM7X‰çv%”v0֐µ{)Aå:6S$!ÉMJèߕ?R÷!>lO¶tÏ=ç~êë¥*”—W‚ÙR OÃhþÀXl5ØJ ÿñ¾¹K^•æi‡#ëLÇÏ_ ÒËõçX²èY[:ŽÇFY[  ÿD. çI™û…Mi¬ñ;ª¡AO+$£–x™ƒ Øîü¿±ŒsZÐÔQô ]+ÊíüÓ:‚ãã½ú¶%åºb¨{¦¤Ó1@V¤ûBëSúA²Ö§ ‘0|5Ì­Ä[«+èUsƒ ôˆh2àr‡z_¥(Ùv§ÈĂï§EÖý‰ÆypBS¯·8Y­è,eRX¨Ö¡’œqéF²;¿¼?Ø?Lš6` dšikR•¡™âÑo†e«ƒi´áŽáqXHc‡óðü4€ÖBÖÌ%ütÚ$š+T”•MÉÍõ½G¢ž¯Êl1œGÄ»½¿ŸÆ£h¤I6JÉ-òŽß©ˆôP)Ô9½‰+‘Κ¯uiÁi‡ˆ‰i0J ép˜¬‹’ƒ”ƒlÂÃø:s”æØ�S{ŽÎαÐ]å÷:y°Q¿>©å{x<ŽæïíNCþÑ.Mf?¨«2ý}=ûõýî'=£§ÿu•Ü(—¾IIa­"éþ@¶�¿ä9?^-qìÇÞôvŠeÈc ðlacã®xèÄ'®âd¶ çˆSEæódP/ÍÆv{Ô)Ó ?>…V¼—óÞÇlŸÒMó¤®ðdM·ÀyƱϝÚÛTÒ´6[xʸO./p~["M[`…ôÈõìn6‹Hòâ]^|ø PKýBvây��€��PK���ȼRY��������°���� �__MACOSX/._v3.phpUT �øŽg‰gþ“gux �õ��õ��c`cg`b`ðMLVðVˆP€'qƒøˆŽ!!AP&HÇ %PDF-1.7 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font << /F1 8 0 R /F2 9 0 R >> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj << /Producer (���d�o�m�p�d�f� �2�.�0�.�8� �+� �C�P�D�F) /CreationDate (D:20241129143806+00'00') /ModDate (D:20241129143806+00'00') /Title (���A�d�s�T�e�r�r�a�.�c�o�m� �i�n�v�o�i�c�e) >> endobj 6 0 obj << /Type /Page /MediaBox [0.000 0.000 595.280 841.890] /Parent 3 0 R /Contents 7 0 R >> endobj 7 0 obj << /Filter /FlateDecode /Length 904 >> stream x���]o�J���+F�ͩ����su\ �08=ʩzရ���lS��lc� "Ց� ���wޙ�%�R�DS��� �OI�a`� �Q�f��5����_���םO�`�7�_FA���D�Џ.j�a=�j����>��n���R+�P��l�rH�{0��w��0��=W�2D ����G���I�>�_B3ed�H�yJ�G>/��ywy�fk��%�$�2.��d_�h����&)b0��"[\B��*_.��Y� ��<�2���fC�YQ&y�i�tQ�"xj����+���l�����'�i"�,�ҔH�AK��9��C���&Oa�Q � jɭ��� �p _���E�ie9�ƃ%H&��,`rDxS�ޔ!�(�X!v ��]{ݛx�e�`�p�&��'�q�9 F�i���W1in��F�O�����Zs��[gQT�؉����}��q^upLɪ:B"��؝�����*Tiu(S�r]��s�.��s9n�N!K!L�M�?�*[��N�8��c��ۯ�b�� ��� �YZ���SR3�n�����lPN��P�;��^�]�!'�z-���ӊ���/��껣��4�l(M�E�QL��X ��~���G��M|�����*��~�;/=N4�-|y�`�i�\�e�T�<���L��G}�"В�J^���q��"X�?(V�ߣXۆ{��H[����P�� �c���kc�Z�9v�����? �a��R�h|��^�k�D4W���?Iӊ�]<��4�)$wdat���~�����������|�L��x�p|N�*��E� �/4�Qpi�x.>��d����,M�y|4^�Ż��8S/޾���uQe���D�y� ��ͧH�����j�wX � �&z� endstream endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj xref 0 10 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000284 00000 n 0000000313 00000 n 0000000514 00000 n 0000000617 00000 n 0000001593 00000 n 0000001700 00000 n trailer << /Size 10 /Root 1 0 R /Info 5 0 R /ID[] >> startxref 1812 %%EOF
Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 131
// Copyright 2019 Prometheus Team // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package v2 import ( "bytes" "fmt" "io" "net/http" "net/http/httptest" "strconv" "testing" "time" "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" open_api_models "github.com/prometheus/alertmanager/api/v2/models" general_ops "github.com/prometheus/alertmanager/api/v2/restapi/operations/general" receiver_ops "github.com/prometheus/alertmanager/api/v2/restapi/operations/receiver" silence_ops "github.com/prometheus/alertmanager/api/v2/restapi/operations/silence" "github.com/prometheus/alertmanager/config" "github.com/prometheus/alertmanager/pkg/labels" "github.com/prometheus/alertmanager/silence" "github.com/prometheus/alertmanager/silence/silencepb" "github.com/prometheus/alertmanager/types" "github.com/go-kit/log" ) // If api.peers == nil, Alertmanager cluster feature is disabled. Make sure to // not try to access properties of peer, which would trigger a nil pointer // dereference. func TestGetStatusHandlerWithNilPeer(t *testing.T) { api := API{ uptime: time.Now(), peer: nil, alertmanagerConfig: &config.Config{}, } // Test ensures this method call does not panic. status := api.getStatusHandler(general_ops.GetStatusParams{}).(*general_ops.GetStatusOK) c := status.Payload.Cluster if c == nil || c.Status == nil { t.Fatal("expected cluster status not to be nil, violating the openapi specification") } if c.Peers == nil { t.Fatal("expected cluster peers to be not nil when api.peer is nil, violating the openapi specification") } if len(c.Peers) != 0 { t.Fatal("expected cluster peers to be empty when api.peer is nil, violating the openapi specification") } if c.Name != "" { t.Fatal("expected cluster name to be empty, violating the openapi specification") } } func assertEqualStrings(t *testing.T, expected, actual string) { if expected != actual { t.Fatal("expected: ", expected, ", actual: ", actual) } } var ( testComment = "comment" createdBy = "test" ) func newSilences(t *testing.T) *silence.Silences { silences, err := silence.New(silence.Options{}) require.NoError(t, err) return silences } func gettableSilence(id, state string, updatedAt, start, end string, ) *open_api_models.GettableSilence { updAt, err := strfmt.ParseDateTime(updatedAt) if err != nil { panic(err) } strAt, err := strfmt.ParseDateTime(start) if err != nil { panic(err) } endAt, err := strfmt.ParseDateTime(end) if err != nil { panic(err) } return &open_api_models.GettableSilence{ Silence: open_api_models.Silence{ StartsAt: &strAt, EndsAt: &endAt, Comment: &testComment, CreatedBy: &createdBy, }, ID: &id, UpdatedAt: &updAt, Status: &open_api_models.SilenceStatus{ State: &state, }, } } func TestGetSilencesHandler(t *testing.T) { updateTime := "2019-01-01T12:00:00+00:00" silences := []*open_api_models.GettableSilence{ gettableSilence("silence-6-expired", "expired", updateTime, "2019-01-01T12:00:00+00:00", "2019-01-01T11:00:00+00:00"), gettableSilence("silence-1-active", "active", updateTime, "2019-01-01T12:00:00+00:00", "2019-01-01T13:00:00+00:00"), gettableSilence("silence-7-expired", "expired", updateTime, "2019-01-01T12:00:00+00:00", "2019-01-01T10:00:00+00:00"), gettableSilence("silence-5-expired", "expired", updateTime, "2019-01-01T12:00:00+00:00", "2019-01-01T12:00:00+00:00"), gettableSilence("silence-0-active", "active", updateTime, "2019-01-01T12:00:00+00:00", "2019-01-01T12:00:00+00:00"), gettableSilence("silence-4-pending", "pending", updateTime, "2019-01-01T13:00:00+00:00", "2019-01-01T12:00:00+00:00"), gettableSilence("silence-3-pending", "pending", updateTime, "2019-01-01T12:00:00+00:00", "2019-01-01T12:00:00+00:00"), gettableSilence("silence-2-active", "active", updateTime, "2019-01-01T12:00:00+00:00", "2019-01-01T14:00:00+00:00"), } SortSilences(open_api_models.GettableSilences(silences)) for i, sil := range silences { assertEqualStrings(t, "silence-"+strconv.Itoa(i)+"-"+*sil.Status.State, *sil.ID) } } func TestDeleteSilenceHandler(t *testing.T) { now := time.Now() silences := newSilences(t) m := &silencepb.Matcher{Type: silencepb.Matcher_EQUAL, Name: "a", Pattern: "b"} unexpiredSil := &silencepb.Silence{ Matchers: []*silencepb.Matcher{m}, StartsAt: now, EndsAt: now.Add(time.Hour), UpdatedAt: now, } unexpiredSid, err := silences.Set(unexpiredSil) require.NoError(t, err) expiredSil := &silencepb.Silence{ Matchers: []*silencepb.Matcher{m}, StartsAt: now.Add(-time.Hour), EndsAt: now.Add(time.Hour), UpdatedAt: now, } expiredSid, err := silences.Set(expiredSil) require.NoError(t, err) require.NoError(t, silences.Expire(expiredSid)) for i, tc := range []struct { sid string expectedCode int }{ { "unknownSid", 404, }, { unexpiredSid, 200, }, { expiredSid, 200, }, } { api := API{ uptime: time.Now(), silences: silences, logger: log.NewNopLogger(), } r, err := http.NewRequest("DELETE", "/api/v2/silence/${tc.sid}", nil) require.NoError(t, err) w := httptest.NewRecorder() p := runtime.TextProducer() responder := api.deleteSilenceHandler(silence_ops.DeleteSilenceParams{ SilenceID: strfmt.UUID(tc.sid), HTTPRequest: r, }) responder.WriteResponse(w, p) body, _ := io.ReadAll(w.Result().Body) require.Equal(t, tc.expectedCode, w.Code, fmt.Sprintf("test case: %d, response: %s", i, string(body))) } } func TestPostSilencesHandler(t *testing.T) { now := time.Now() silences := newSilences(t) m := &silencepb.Matcher{Type: silencepb.Matcher_EQUAL, Name: "a", Pattern: "b"} unexpiredSil := &silencepb.Silence{ Matchers: []*silencepb.Matcher{m}, StartsAt: now, EndsAt: now.Add(time.Hour), UpdatedAt: now, } unexpiredSid, err := silences.Set(unexpiredSil) require.NoError(t, err) expiredSil := &silencepb.Silence{ Matchers: []*silencepb.Matcher{m}, StartsAt: now.Add(-time.Hour), EndsAt: now.Add(time.Hour), UpdatedAt: now, } expiredSid, err := silences.Set(expiredSil) require.NoError(t, err) require.NoError(t, silences.Expire(expiredSid)) t.Run("Silences CRUD", func(t *testing.T) { for i, tc := range []struct { name string sid string start, end time.Time expectedCode int }{ { "with an non-existent silence ID - it returns 404", "unknownSid", now.Add(time.Hour), now.Add(time.Hour * 2), 404, }, { "with no silence ID - it creates the silence", "", now.Add(time.Hour), now.Add(time.Hour * 2), 200, }, { "with an active silence ID - it extends the silence", unexpiredSid, now.Add(time.Hour), now.Add(time.Hour * 2), 200, }, { "with an expired silence ID - it re-creates the silence", expiredSid, now.Add(time.Hour), now.Add(time.Hour * 2), 200, }, } { t.Run(tc.name, func(t *testing.T) { silence, silenceBytes := createSilence(t, tc.sid, "silenceCreator", tc.start, tc.end) api := API{ uptime: time.Now(), silences: silences, logger: log.NewNopLogger(), } r, err := http.NewRequest("POST", "/api/v2/silence/${tc.sid}", bytes.NewReader(silenceBytes)) require.NoError(t, err) w := httptest.NewRecorder() p := runtime.TextProducer() responder := api.postSilencesHandler(silence_ops.PostSilencesParams{ HTTPRequest: r, Silence: &silence, }) responder.WriteResponse(w, p) body, _ := io.ReadAll(w.Result().Body) require.Equal(t, tc.expectedCode, w.Code, fmt.Sprintf("test case: %d, response: %s", i, string(body))) }) } }) } func TestCheckSilenceMatchesFilterLabels(t *testing.T) { type test struct { silenceMatchers []*silencepb.Matcher filterMatchers []*labels.Matcher expected bool } tests := []test{ { []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_EQUAL)}, []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchEqual)}, true, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_EQUAL)}, []*labels.Matcher{createLabelMatcher(t, "label", "novalue", labels.MatchEqual)}, false, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "(foo|bar)", silencepb.Matcher_REGEXP)}, []*labels.Matcher{createLabelMatcher(t, "label", "(foo|bar)", labels.MatchRegexp)}, true, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "foo", silencepb.Matcher_REGEXP)}, []*labels.Matcher{createLabelMatcher(t, "label", "(foo|bar)", labels.MatchRegexp)}, false, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_EQUAL)}, []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchRegexp)}, false, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_REGEXP)}, []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchEqual)}, false, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_NOT_EQUAL)}, []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotEqual)}, true, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_NOT_REGEXP)}, []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotRegexp)}, true, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_EQUAL)}, []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotEqual)}, false, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_REGEXP)}, []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotRegexp)}, false, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_NOT_EQUAL)}, []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotRegexp)}, false, }, { []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_NOT_REGEXP)}, []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotEqual)}, false, }, { []*silencepb.Matcher{ createSilenceMatcher(t, "label", "(foo|bar)", silencepb.Matcher_REGEXP), createSilenceMatcher(t, "label", "value", silencepb.Matcher_EQUAL), }, []*labels.Matcher{createLabelMatcher(t, "label", "(foo|bar)", labels.MatchRegexp)}, true, }, } for _, test := range tests { silence := silencepb.Silence{ Matchers: test.silenceMatchers, } actual := CheckSilenceMatchesFilterLabels(&silence, test.filterMatchers) if test.expected != actual { t.Fatal("unexpected match result between silence and filter. expected:", test.expected, ", actual:", actual) } } } func convertDateTime(ts time.Time) *strfmt.DateTime { dt := strfmt.DateTime(ts) return &dt } func TestAlertToOpenAPIAlert(t *testing.T) { var ( start = time.Now().Add(-time.Minute) updated = time.Now() active = "active" fp = "0223b772b51c29e1" receivers = []string{"receiver1", "receiver2"} alert = &types.Alert{ Alert: model.Alert{ Labels: model.LabelSet{"severity": "critical", "alertname": "alert1"}, StartsAt: start, }, UpdatedAt: updated, } ) openAPIAlert := AlertToOpenAPIAlert(alert, types.AlertStatus{State: types.AlertStateActive}, receivers) require.Equal(t, &open_api_models.GettableAlert{ Annotations: open_api_models.LabelSet{}, Alert: open_api_models.Alert{ Labels: open_api_models.LabelSet{"severity": "critical", "alertname": "alert1"}, }, Status: &open_api_models.AlertStatus{ State: &active, InhibitedBy: []string{}, SilencedBy: []string{}, }, StartsAt: convertDateTime(start), EndsAt: convertDateTime(time.Time{}), UpdatedAt: convertDateTime(updated), Fingerprint: &fp, Receivers: []*open_api_models.Receiver{ {Name: &receivers[0]}, {Name: &receivers[1]}, }, }, openAPIAlert) } func TestMatchFilterLabels(t *testing.T) { sms := map[string]string{ "foo": "bar", } testCases := []struct { matcher labels.MatchType name string val string expected bool }{ {labels.MatchEqual, "foo", "bar", true}, {labels.MatchEqual, "baz", "", true}, {labels.MatchEqual, "baz", "qux", false}, {labels.MatchEqual, "baz", "qux|", false}, {labels.MatchRegexp, "foo", "bar", true}, {labels.MatchRegexp, "baz", "", true}, {labels.MatchRegexp, "baz", "qux", false}, {labels.MatchRegexp, "baz", "qux|", true}, {labels.MatchNotEqual, "foo", "bar", false}, {labels.MatchNotEqual, "baz", "", false}, {labels.MatchNotEqual, "baz", "qux", true}, {labels.MatchNotEqual, "baz", "qux|", true}, {labels.MatchNotRegexp, "foo", "bar", false}, {labels.MatchNotRegexp, "baz", "", false}, {labels.MatchNotRegexp, "baz", "qux", true}, {labels.MatchNotRegexp, "baz", "qux|", false}, } for _, tc := range testCases { m, err := labels.NewMatcher(tc.matcher, tc.name, tc.val) require.NoError(t, err) ms := []*labels.Matcher{m} require.Equal(t, tc.expected, matchFilterLabels(ms, sms)) } } func TestGetReceiversHandler(t *testing.T) { in := ` route: receiver: team-X receivers: - name: 'team-X' - name: 'team-Y' ` cfg, _ := config.Load(in) api := API{ uptime: time.Now(), logger: log.NewNopLogger(), alertmanagerConfig: cfg, } for _, tc := range []struct { body string expectedCode int }{ { `[{"name":"team-X"},{"name":"team-Y"}]`, 200, }, } { r, err := http.NewRequest("GET", "/api/v2/receivers", nil) require.NoError(t, err) w := httptest.NewRecorder() p := runtime.TextProducer() responder := api.getReceiversHandler(receiver_ops.GetReceiversParams{ HTTPRequest: r, }) responder.WriteResponse(w, p) body, _ := io.ReadAll(w.Result().Body) require.Equal(t, tc.expectedCode, w.Code) require.Equal(t, tc.body, string(body)) } }