github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/overlord/configstate/configcore/proxy_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2017 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package configcore_test
    21  
    22  import (
    23  	"fmt"
    24  	"io/ioutil"
    25  	"os"
    26  	"path/filepath"
    27  	"time"
    28  
    29  	. "gopkg.in/check.v1"
    30  
    31  	"github.com/snapcore/snapd/asserts"
    32  	"github.com/snapcore/snapd/asserts/assertstest"
    33  	"github.com/snapcore/snapd/dirs"
    34  	"github.com/snapcore/snapd/overlord/assertstate"
    35  	"github.com/snapcore/snapd/overlord/assertstate/assertstatetest"
    36  	"github.com/snapcore/snapd/overlord/configstate/configcore"
    37  	"github.com/snapcore/snapd/release"
    38  	"github.com/snapcore/snapd/testutil"
    39  )
    40  
    41  type proxySuite struct {
    42  	configcoreSuite
    43  
    44  	mockEtcEnvironment string
    45  
    46  	storeSigning *assertstest.StoreStack
    47  }
    48  
    49  var _ = Suite(&proxySuite{})
    50  
    51  func (s *proxySuite) SetUpTest(c *C) {
    52  	s.configcoreSuite.SetUpTest(c)
    53  
    54  	err := os.MkdirAll(filepath.Join(dirs.GlobalRootDir, "/etc/"), 0755)
    55  	c.Assert(err, IsNil)
    56  	s.mockEtcEnvironment = filepath.Join(dirs.GlobalRootDir, "/etc/environment")
    57  
    58  	s.storeSigning = assertstest.NewStoreStack("canonical", nil)
    59  
    60  	db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{
    61  		Backstore:       asserts.NewMemoryBackstore(),
    62  		Trusted:         s.storeSigning.Trusted,
    63  		OtherPredefined: s.storeSigning.Generic,
    64  	})
    65  	c.Assert(err, IsNil)
    66  
    67  	s.state.Lock()
    68  	assertstate.ReplaceDB(s.state, db)
    69  	s.state.Unlock()
    70  
    71  	err = db.Add(s.storeSigning.StoreAccountKey(""))
    72  	c.Assert(err, IsNil)
    73  }
    74  
    75  func (s *proxySuite) makeMockEtcEnvironment(c *C) {
    76  	err := ioutil.WriteFile(s.mockEtcEnvironment, []byte(`
    77  PATH="/usr/bin"
    78  `), 0644)
    79  	c.Assert(err, IsNil)
    80  }
    81  
    82  func (s *proxySuite) TestConfigureProxyUnhappy(c *C) {
    83  	restore := release.MockOnClassic(false)
    84  	defer restore()
    85  
    86  	dirs.SetRootDir(c.MkDir())
    87  	err := configcore.Run(&mockConf{
    88  		state: s.state,
    89  		conf: map[string]interface{}{
    90  			"proxy.http": "http://example.com",
    91  		},
    92  	})
    93  	c.Assert(err, ErrorMatches, "open .*/etc/environment: no such file or directory")
    94  }
    95  
    96  func (s *proxySuite) TestConfigureProxy(c *C) {
    97  	restore := release.MockOnClassic(false)
    98  	defer restore()
    99  
   100  	for _, proto := range []string{"http", "https", "ftp"} {
   101  		// populate with content
   102  		s.makeMockEtcEnvironment(c)
   103  
   104  		err := configcore.Run(&mockConf{
   105  			state: s.state,
   106  			conf: map[string]interface{}{
   107  				fmt.Sprintf("proxy.%s", proto): fmt.Sprintf("%s://example.com", proto),
   108  			},
   109  		})
   110  		c.Assert(err, IsNil)
   111  
   112  		c.Check(s.mockEtcEnvironment, testutil.FileEquals, fmt.Sprintf(`
   113  PATH="/usr/bin"
   114  %[1]s_proxy=%[1]s://example.com`, proto))
   115  	}
   116  }
   117  
   118  func (s *proxySuite) TestConfigureNoProxy(c *C) {
   119  	restore := release.MockOnClassic(false)
   120  	defer restore()
   121  
   122  	// populate with content
   123  	s.makeMockEtcEnvironment(c)
   124  	err := configcore.Run(&mockConf{
   125  		state: s.state,
   126  		conf: map[string]interface{}{
   127  			"proxy.no-proxy": "example.com,bar.com",
   128  		},
   129  	})
   130  	c.Assert(err, IsNil)
   131  
   132  	c.Check(s.mockEtcEnvironment, testutil.FileEquals, `
   133  PATH="/usr/bin"
   134  no_proxy=example.com,bar.com`)
   135  }
   136  
   137  func (s *proxySuite) TestConfigureProxyStore(c *C) {
   138  	// set to ""
   139  	err := configcore.Run(&mockConf{
   140  		state: s.state,
   141  		conf: map[string]interface{}{
   142  			"proxy.store": "",
   143  		},
   144  	})
   145  	c.Check(err, IsNil)
   146  
   147  	// no assertion
   148  	conf := &mockConf{
   149  		state: s.state,
   150  		conf: map[string]interface{}{
   151  			"proxy.store": "foo",
   152  		},
   153  	}
   154  
   155  	err = configcore.Run(conf)
   156  	c.Check(err, ErrorMatches, `cannot set proxy.store to "foo" without a matching store assertion`)
   157  
   158  	operatorAcct := assertstest.NewAccount(s.storeSigning, "foo-operator", nil, "")
   159  	// have a store assertion
   160  	stoAs, err := s.storeSigning.Sign(asserts.StoreType, map[string]interface{}{
   161  		"store":       "foo",
   162  		"operator-id": operatorAcct.AccountID(),
   163  		"url":         "http://store.interal:9943",
   164  		"timestamp":   time.Now().Format(time.RFC3339),
   165  	}, nil, "")
   166  	c.Assert(err, IsNil)
   167  	func() {
   168  		s.state.Lock()
   169  		defer s.state.Unlock()
   170  		assertstatetest.AddMany(s.state, operatorAcct, stoAs)
   171  	}()
   172  
   173  	err = configcore.Run(conf)
   174  	c.Check(err, IsNil)
   175  }
   176  
   177  func (s *proxySuite) TestConfigureProxyStoreNoURL(c *C) {
   178  	conf := &mockConf{
   179  		state: s.state,
   180  		conf: map[string]interface{}{
   181  			"proxy.store": "foo",
   182  		},
   183  	}
   184  
   185  	operatorAcct := assertstest.NewAccount(s.storeSigning, "foo-operator", nil, "")
   186  	// have a store assertion but no url
   187  	stoAs, err := s.storeSigning.Sign(asserts.StoreType, map[string]interface{}{
   188  		"store":       "foo",
   189  		"operator-id": operatorAcct.AccountID(),
   190  		"timestamp":   time.Now().Format(time.RFC3339),
   191  	}, nil, "")
   192  	c.Assert(err, IsNil)
   193  	func() {
   194  		s.state.Lock()
   195  		defer s.state.Unlock()
   196  		assertstatetest.AddMany(s.state, operatorAcct, stoAs)
   197  	}()
   198  
   199  	err = configcore.Run(conf)
   200  	c.Check(err, ErrorMatches, `cannot set proxy.store to "foo" with a matching store assertion with url unset`)
   201  }