Skip to content

Commit

Permalink
Merge pull request #124 from ycliuhw/open-port-support
Browse files Browse the repository at this point in the history
Support application port range and bump application schema version to…
  • Loading branch information
ycliuhw authored Feb 27, 2023
2 parents 507137c + 185328f commit 7eb3c0e
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.vscode/
72 changes: 63 additions & 9 deletions application.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ type Application interface {
AddOffer(ApplicationOfferArgs) ApplicationOffer

Validate() error

OpenedPortRanges() PortRanges
AddOpenedPortRange(OpenedPortRangeArgs)
}

// ExposedEndpoint encapsulates the details about the CIDRs and/or spaces that
Expand Down Expand Up @@ -134,6 +137,8 @@ type application struct {
Tools_ *agentTools `yaml:"tools,omitempty"`
OperatorStatus_ *status `yaml:"operator-status,omitempty"`

OpenedPortRanges_ *deployedPortRanges `yaml:"opened-port-ranges,omitempty"`

// Offer-related fields
Offers_ *applicationOffers `yaml:"offers,omitempty"`

Expand Down Expand Up @@ -346,6 +351,30 @@ func (a *application) MetricsCredentials() []byte {
return creds
}

// OpenedPortRanges implements Application.
func (a *application) OpenedPortRanges() PortRanges {
if a.OpenedPortRanges_ == nil {
a.OpenedPortRanges_ = newDeployedPortRanges()
}
return a.OpenedPortRanges_
}

// AddOpenedPortRange implements Application.
func (a *application) AddOpenedPortRange(args OpenedPortRangeArgs) {
if a.OpenedPortRanges_ == nil {
a.OpenedPortRanges_ = newDeployedPortRanges()
}

if a.OpenedPortRanges_.ByUnit_[args.UnitName] == nil {
a.OpenedPortRanges_.ByUnit_[args.UnitName] = newUnitPortRanges()
}

a.OpenedPortRanges_.ByUnit_[args.UnitName].ByEndpoint_[args.EndpointName] = append(
a.OpenedPortRanges_.ByUnit_[args.UnitName].ByEndpoint_[args.EndpointName],
newUnitPortRange(args.FromPort, args.ToPort, args.Protocol),
)
}

// OperatorStatus implements Application.
func (a *application) OperatorStatus() Status {
// To avoid typed nils check nil here.
Expand Down Expand Up @@ -585,15 +614,16 @@ func importApplicationList(sourceList []interface{}, importFunc applicationDeser
type applicationDeserializationFunc func(map[string]interface{}) (*application, error)

var applicationDeserializationFuncs = map[int]applicationDeserializationFunc{
1: importApplicationV1,
2: importApplicationV2,
3: importApplicationV3,
4: importApplicationV4,
5: importApplicationV5,
6: importApplicationV6,
7: importApplicationV7,
8: importApplicationV8,
9: importApplicationV9,
1: importApplicationV1,
2: importApplicationV2,
3: importApplicationV3,
4: importApplicationV4,
5: importApplicationV5,
6: importApplicationV6,
7: importApplicationV7,
8: importApplicationV8,
9: importApplicationV9,
10: importApplicationV10,
}

func applicationV1Fields() (schema.Fields, schema.Defaults) {
Expand Down Expand Up @@ -701,6 +731,13 @@ func applicationV9Fields() (schema.Fields, schema.Defaults) {
return fields, defaults
}

func applicationV10Fields() (schema.Fields, schema.Defaults) {
fields, defaults := applicationV9Fields()
fields["opened-port-ranges"] = schema.StringMap(schema.Any())
defaults["opened-port-ranges"] = schema.Omit
return fields, defaults
}

func importApplicationV1(source map[string]interface{}) (*application, error) {
fields, defaults := applicationV1Fields()
return importApplication(fields, defaults, 1, source)
Expand Down Expand Up @@ -746,6 +783,11 @@ func importApplicationV9(source map[string]interface{}) (*application, error) {
return importApplication(fields, defaults, 9, source)
}

func importApplicationV10(source map[string]interface{}) (*application, error) {
fields, defaults := applicationV10Fields()
return importApplication(fields, defaults, 10, source)
}

func importApplication(fields schema.Fields, defaults schema.Defaults, importVersion int, source map[string]interface{}) (*application, error) {
checker := schema.FieldMap(fields, defaults)

Expand Down Expand Up @@ -835,6 +877,18 @@ func importApplication(fields schema.Fields, defaults schema.Defaults, importVer
}
}

if importVersion >= 10 {
applicationPortRangesSource, ok := valid["opened-port-ranges"].(map[string]interface{})
if ok {
machPortRanges, err := importMachinePortRanges(applicationPortRangesSource)
if err != nil {
return nil, errors.Trace(err)
}
result.OpenedPortRanges_ = machPortRanges
}

}

result.importAnnotations(valid)

if err := result.importStatusHistory(valid); err != nil {
Expand Down
28 changes: 27 additions & 1 deletion application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,32 @@ func (s *ApplicationSerializationSuite) TestParsingSerializedDataWithOfferBlock(
c.Assert(application, jc.DeepEquals, app)
}

func (s *ApplicationSerializationSuite) TestAddOpenedPortRange(c *gc.C) {
app := minimalApplication()
app.AddOpenedPortRange(
OpenedPortRangeArgs{
UnitName: "magic/0",
EndpointName: "",
FromPort: 666,
ToPort: 666,
Protocol: "tcp",
},
)
app.AddOpenedPortRange(
OpenedPortRangeArgs{
UnitName: "magic/1",
EndpointName: "",
FromPort: 888,
ToPort: 888,
Protocol: "tcp",
},
)
c.Assert(app.OpenedPortRanges().ByUnit(), gc.HasLen, 2)

application := s.exportImportLatest(c, app)
c.Assert(application.OpenedPortRanges().ByUnit(), gc.HasLen, 2)
}

func (s *ApplicationSerializationSuite) exportImportVersion(c *gc.C, application_ *application, version int) *application {
initial := applications{
Version: version,
Expand All @@ -336,7 +362,7 @@ func (s *ApplicationSerializationSuite) exportImportVersion(c *gc.C, application
}

func (s *ApplicationSerializationSuite) exportImportLatest(c *gc.C, application_ *application) *application {
return s.exportImportVersion(c, application_, 9)
return s.exportImportVersion(c, application_, 10)
}

func (s *ApplicationSerializationSuite) TestV1ParsingReturnsLatest(c *gc.C) {
Expand Down
14 changes: 7 additions & 7 deletions machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type Machine interface {
BlockDevices() []BlockDevice
AddBlockDevice(BlockDeviceArgs) BlockDevice

OpenedPortRanges() MachinePortRanges
OpenedPortRanges() PortRanges
AddOpenedPortRange(OpenedPortRangeArgs)

Validate() error
Expand Down Expand Up @@ -91,7 +91,7 @@ type machine struct {

Containers_ []*machine `yaml:"containers"`

OpenedPortRanges_ *machinePortRanges `yaml:"opened-port-ranges,omitempty"`
OpenedPortRanges_ *deployedPortRanges `yaml:"opened-port-ranges,omitempty"`

Annotations_ `yaml:"annotations,omitempty"`

Expand Down Expand Up @@ -331,17 +331,17 @@ func (m *machine) AddContainer(args MachineArgs) Machine {
}

// OpenedPortRanges implements Machine.
func (m *machine) OpenedPortRanges() MachinePortRanges {
func (m *machine) OpenedPortRanges() PortRanges {
if m.OpenedPortRanges_ == nil {
m.OpenedPortRanges_ = newMachinePortRanges()
m.OpenedPortRanges_ = newDeployedPortRanges()
}
return m.OpenedPortRanges_
}

// AddOpenedPortRange implements Machine.
func (m *machine) AddOpenedPortRange(args OpenedPortRangeArgs) {
if m.OpenedPortRanges_ == nil {
m.OpenedPortRanges_ = newMachinePortRanges()
m.OpenedPortRanges_ = newDeployedPortRanges()
}

if m.OpenedPortRanges_.ByUnit_[args.UnitName] == nil {
Expand Down Expand Up @@ -443,12 +443,12 @@ var machineDeserializationFuncs = map[int]machineDeserializationFunc{
}

func importMachineV1(source map[string]interface{}) (*machine, error) {
fields, defaults := machineSchemaV2()
fields, defaults := machineSchemaV1()
return importMachine(fields, defaults, 1, source, importMachineV1)
}

func importMachineV2(source map[string]interface{}) (*machine, error) {
fields, defaults := machineSchemaV1()
fields, defaults := machineSchemaV2()
return importMachine(fields, defaults, 2, source, importMachineV2)
}

Expand Down
5 changes: 4 additions & 1 deletion model.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ func (m *model) AddApplication(args ApplicationArgs) Application {

func (m *model) setApplications(applicationList []*application) {
m.Applications_ = applications{
Version: 9,
Version: 10,
Applications_: applicationList,
}
}
Expand Down Expand Up @@ -1047,6 +1047,9 @@ func (m *model) Validate() error {
if err := application.Validate(); err != nil {
return errors.Trace(err)
}
for unitName := range application.OpenedPortRanges().ByUnit() {
validationCtx.unitsWithOpenPorts.Add(unitName)
}
validationCtx.allApplications.Add(application.Name())
validationCtx.allUnits = validationCtx.allUnits.Union(application.unitNames())
}
Expand Down
23 changes: 11 additions & 12 deletions port_ranges.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import (
"github.com/juju/schema"
)

// MachinePortRanges represents a collection of port ranges that are open on a
// particular machine.
type MachinePortRanges interface {
// PortRanges represents a collection of port ranges that are open.
type PortRanges interface {
ByUnit() map[string]UnitPortRanges
}

Expand Down Expand Up @@ -38,22 +37,22 @@ type OpenedPortRangeArgs struct {
Protocol string
}

type machinePortRanges struct {
type deployedPortRanges struct {
Version int `yaml:"version"`

// The set of opened port ranges by unit.
ByUnit_ map[string]*unitPortRanges `yaml:"machine-port-ranges"`
}

func newMachinePortRanges() *machinePortRanges {
return &machinePortRanges{
func newDeployedPortRanges() *deployedPortRanges {
return &deployedPortRanges{
Version: 1,
ByUnit_: make(map[string]*unitPortRanges),
}
}

// ByUnit implements MachinePortRanges.
func (p *machinePortRanges) ByUnit() map[string]UnitPortRanges {
// ByUnit implements deployedPortRanges.
func (p *deployedPortRanges) ByUnit() map[string]UnitPortRanges {
res := make(map[string]UnitPortRanges, len(p.ByUnit_))
for unitName, upr := range p.ByUnit_ {
res[unitName] = upr
Expand Down Expand Up @@ -114,7 +113,7 @@ func (p unitPortRange) Protocol() string {
return p.Protocol_
}

func importMachinePortRanges(source map[string]interface{}) (*machinePortRanges, error) {
func importMachinePortRanges(source map[string]interface{}) (*deployedPortRanges, error) {
checker := versionedMapChecker("machine-port-ranges")
coerced, err := checker.Coerce(source, nil)
if err != nil {
Expand All @@ -131,13 +130,13 @@ func importMachinePortRanges(source map[string]interface{}) (*machinePortRanges,
return importFunc(sourceMap)
}

type machinePortRangeDeserializationFunc func(map[string]interface{}) (*machinePortRanges, error)
type machinePortRangeDeserializationFunc func(map[string]interface{}) (*deployedPortRanges, error)

var machinePortRangeDeserializationFuncs = map[int]machinePortRangeDeserializationFunc{
1: importMachinePortRangeV1,
}

func importMachinePortRangeV1(source map[string]interface{}) (*machinePortRanges, error) {
func importMachinePortRangeV1(source map[string]interface{}) (*deployedPortRanges, error) {
unitChecker := schema.FieldMap(schema.Fields{
"unit-port-ranges": schema.StringMap(
schema.List(schema.StringMap(schema.Any())),
Expand All @@ -150,7 +149,7 @@ func importMachinePortRangeV1(source map[string]interface{}) (*machinePortRanges
"protocol": schema.String(),
}, nil) // no defaults

mpr := &machinePortRanges{
mpr := &deployedPortRanges{
Version: 1,
ByUnit_: make(map[string]*unitPortRanges),
}
Expand Down
2 changes: 1 addition & 1 deletion port_ranges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func assertUnitPortRangeMatches(c *gc.C, prA, prB UnitPortRange) {
var _ = gc.Suite(&MachinePortRangeSerializationSuite{})

func (*MachinePortRangeSerializationSuite) TestParsingSerializedData(c *gc.C) {
initial := &machinePortRanges{
initial := &deployedPortRanges{
Version: 1,
ByUnit_: map[string]*unitPortRanges{
"lorem/0": {
Expand Down
2 changes: 1 addition & 1 deletion ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
// particular subnet. OpenedPorts are always associated with a Machine.
//
// This type is deprecated and retained for backwards-compatibility purposes.
// The MachinePortRanges interface should be used instead.
// The PortRange interface should be used instead.
type OpenedPorts interface {
SubnetID() string
OpenPorts() []PortRange
Expand Down

0 comments on commit 7eb3c0e

Please sign in to comment.