diff --git a/configuration/structured_peers.go b/configuration/structured_peers.go index ba9654ad..3b06ea16 100644 --- a/configuration/structured_peers.go +++ b/configuration/structured_peers.go @@ -200,6 +200,17 @@ func parsePeerSection(name string, p parser.Parser) (*models.PeerSection, error) return nil, errsa } ps.Servers = serversa + + // tables + tables, err := ParseTables(name, p) + if err != nil { + return nil, err + } + tablesa, errsa := namedResourceArrayToMap(tables) + if errsa != nil { + return nil, errsa + } + ps.Tables = tablesa return ps, nil } @@ -233,5 +244,10 @@ func serializePeerSection(a StructuredToParserArgs, ps *models.PeerSection) erro return a.HandleError(strconv.FormatInt(int64(i), 10), PeersParentName, ps.Name, a.TID, a.TID == "", err) } } + for _, table := range ps.Tables { + if err = p.Insert(parser.Peers, ps.Name, "table", SerializeTable(table), -1); err != nil { + return a.HandleError(table.Name, PeersParentName, ps.Name, a.TID, a.TID == "", err) + } + } return nil } diff --git a/models/peer_section.go b/models/peer_section.go index d41cb921..24dc9d69 100644 --- a/models/peer_section.go +++ b/models/peer_section.go @@ -46,6 +46,9 @@ type PeerSection struct { // servers Servers map[string]Server `json:"servers,omitempty"` + + // tables + Tables map[string]Table `json:"tables,omitempty"` } // UnmarshalJSON unmarshals this object from a JSON structure @@ -66,6 +69,8 @@ func (m *PeerSection) UnmarshalJSON(raw []byte) error { PeerEntries map[string]PeerEntry `json:"peer_entries,omitempty"` Servers map[string]Server `json:"servers,omitempty"` + + Tables map[string]Table `json:"tables,omitempty"` } if err := swag.ReadJSON(raw, &dataAO1); err != nil { return err @@ -79,6 +84,8 @@ func (m *PeerSection) UnmarshalJSON(raw []byte) error { m.Servers = dataAO1.Servers + m.Tables = dataAO1.Tables + return nil } @@ -99,6 +106,8 @@ func (m PeerSection) MarshalJSON() ([]byte, error) { PeerEntries map[string]PeerEntry `json:"peer_entries,omitempty"` Servers map[string]Server `json:"servers,omitempty"` + + Tables map[string]Table `json:"tables,omitempty"` } dataAO1.LogTargetList = m.LogTargetList @@ -109,6 +118,8 @@ func (m PeerSection) MarshalJSON() ([]byte, error) { dataAO1.Servers = m.Servers + dataAO1.Tables = m.Tables + jsonDataAO1, errAO1 := swag.WriteJSON(dataAO1) if errAO1 != nil { return nil, errAO1 @@ -142,6 +153,10 @@ func (m *PeerSection) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateTables(formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { return errors.CompositeValidationError(res...) } @@ -247,6 +262,33 @@ func (m *PeerSection) validateServers(formats strfmt.Registry) error { return nil } +func (m *PeerSection) validateTables(formats strfmt.Registry) error { + + if swag.IsZero(m.Tables) { // not required + return nil + } + + for k := range m.Tables { + + if err := validate.Required("tables"+"."+k, "body", m.Tables[k]); err != nil { + return err + } + if val, ok := m.Tables[k]; ok { + if err := val.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("tables" + "." + k) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("tables" + "." + k) + } + return err + } + } + + } + + return nil +} + // ContextValidate validate this peer section based on the context it is used func (m *PeerSection) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error @@ -272,6 +314,10 @@ func (m *PeerSection) ContextValidate(ctx context.Context, formats strfmt.Regist res = append(res, err) } + if err := m.contextValidateTables(ctx, formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { return errors.CompositeValidationError(res...) } @@ -337,6 +383,21 @@ func (m *PeerSection) contextValidateServers(ctx context.Context, formats strfmt return nil } +func (m *PeerSection) contextValidateTables(ctx context.Context, formats strfmt.Registry) error { + + for k := range m.Tables { + + if val, ok := m.Tables[k]; ok { + if err := val.ContextValidate(ctx, formats); err != nil { + return err + } + } + + } + + return nil +} + // MarshalBinary interface implementation func (m *PeerSection) MarshalBinary() ([]byte, error) { if m == nil { diff --git a/models/peer_section_compare.go b/models/peer_section_compare.go index 2c702f81..f3120971 100644 --- a/models/peer_section_compare.go +++ b/models/peer_section_compare.go @@ -71,6 +71,16 @@ func (s PeerSection) Equal(t PeerSection, opts ...Options) bool { } } + if !CheckSameNilAndLenMap[string, Table](s.Tables, t.Tables, opt) { + return false + } + + for k, v := range s.Tables { + if !t.Tables[k].Equal(v, opt) { + return false + } + } + return true } @@ -130,5 +140,15 @@ func (s PeerSection) Diff(t PeerSection, opts ...Options) map[string][]interface } } + if !CheckSameNilAndLenMap[string, Table](s.Tables, t.Tables, opt) { + diff["Tables"] = []interface{}{s.Tables, t.Tables} + } + + for k, v := range s.Tables { + if !t.Tables[k].Equal(v, opt) { + diff["Tables"] = []interface{}{s.Tables, t.Tables} + } + } + return diff } diff --git a/models/peer_section_compare_test.go b/models/peer_section_compare_test.go index b025edbf..a91b6b7d 100644 --- a/models/peer_section_compare_test.go +++ b/models/peer_section_compare_test.go @@ -170,7 +170,7 @@ func TestPeerSectionDiffFalse(t *testing.T) { for _, sample := range samples { result := sample.a.Diff(sample.b) - if len(result) != 5 { + if len(result) != 6 { json := jsoniter.ConfigCompatibleWithStandardLibrary a, err := json.Marshal(&sample.a) if err != nil { @@ -180,7 +180,7 @@ func TestPeerSectionDiffFalse(t *testing.T) { if err != nil { t.Errorf(err.Error()) } - t.Errorf("Expected PeerSection to be different in 5 cases, but it is not (%d) %s %s", len(result), a, b) + t.Errorf("Expected PeerSection to be different in 6 cases, but it is not (%d) %s %s", len(result), a, b) } } } diff --git a/specification/build/haproxy_spec.yaml b/specification/build/haproxy_spec.yaml index 09b757e6..527b5141 100644 --- a/specification/build/haproxy_spec.yaml +++ b/specification/build/haproxy_spec.yaml @@ -4054,6 +4054,9 @@ definitions: servers: additionalProperties: $ref: '#/definitions/server' + tables: + additionalProperties: + $ref: '#/definitions/table' type: object description: Peer Section with all it's children resources type: object diff --git a/specification/models/configuration/peers.yaml b/specification/models/configuration/peers.yaml index d45f585d..94922127 100644 --- a/specification/models/configuration/peers.yaml +++ b/specification/models/configuration/peers.yaml @@ -19,6 +19,9 @@ peer_section: servers: additionalProperties: $ref: "#/definitions/server" + tables: + additionalProperties: + $ref: "#/definitions/table" peer_section_base: title: Peer Section Base description: HAProxy peer_section configuration diff --git a/test/expected/structured.json b/test/expected/structured.json index 953186db..06f59df4 100644 --- a/test/expected/structured.json +++ b/test/expected/structured.json @@ -3106,6 +3106,36 @@ "port": 1023, "shard": 1 } + }, + "tables": { + "t1": { + "expire": "5m", + "name": "t1", + "no_purge": true, + "size": "200k", + "store": "gpc0,conn_rate(30s)", + "type": "string", + "type_len": 1000 + }, + "t2": { + "expire": "5m", + "name": "t2", + "no_purge": true, + "size": "200k", + "store": "gpc0,gpc1,conn_rate(30s)", + "type": "string", + "type_len": 1000 + }, + "t9": { + "expire": "5m", + "name": "t9", + "no_purge": true, + "size": "200k", + "store": "gpc0,conn_rate(30s)", + "type": "string", + "type_len": 1000, + "write_to": "t2" + } } } },